Source Code Cross Referenced for ResultSet.java in  » Database-DBMS » db-derby-10.2 » org » apache » derby » client » am » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Database DBMS » db derby 10.2 » org.apache.derby.client.am 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:
0003:           Derby - Class org.apache.derby.client.am.ResultSet
0004:
0005:           Licensed to the Apache Software Foundation (ASF) under one or more
0006:           contributor license agreements.  See the NOTICE file distributed with
0007:           this work for additional information regarding copyright ownership.
0008:           The ASF licenses this file to You under the Apache License, Version 2.0
0009:           (the "License"); you may not use this file except in compliance with
0010:           the License.  You may obtain a copy of the License at
0011:
0012:              http://www.apache.org/licenses/LICENSE-2.0
0013:
0014:           Unless required by applicable law or agreed to in writing, software
0015:           distributed under the License is distributed on an "AS IS" BASIS,
0016:           WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0017:           See the License for the specific language governing permissions and
0018:           limitations under the License.
0019:
0020:         */
0021:
0022:        package org.apache.derby.client.am;
0023:
0024:        import java.io.IOException;
0025:        import java.io.InputStream;
0026:        import java.io.Reader;
0027:        import java.sql.SQLException;
0028:        import org.apache.derby.client.am.SQLExceptionFactory;
0029:        import org.apache.derby.shared.common.reference.SQLState;
0030:        import org.apache.derby.shared.common.i18n.MessageUtil;
0031:
0032:        public abstract class ResultSet implements  java.sql.ResultSet,
0033:                ResultSetCallbackInterface {
0034:            //---------------------navigational members-----------------------------------
0035:
0036:            public Statement statement_;
0037:            public ColumnMetaData resultSetMetaData_; // As obtained from the SQLDA
0038:            private SqlWarning warnings_;
0039:            public Cursor cursor_;
0040:            protected Agent agent_;
0041:
0042:            public Section generatedSection_ = null;
0043:
0044:            private CloseFilterInputStream is_;
0045:
0046:            //---------------------navigational cheat-links-------------------------------
0047:            // Cheat-links are for convenience only, and are not part of the conceptual model.
0048:            // Warning:
0049:            //   Cheat-links should only be defined for invariant state data.
0050:            //   That is, the state data is set by the constructor and never changes.
0051:
0052:            // Alias for statement_.connection
0053:            public final Connection connection_;
0054:
0055:            //----------------------------- constants ------------------------------------
0056:
0057:            public final static int scrollOrientation_relative__ = 1;
0058:            public final static int scrollOrientation_absolute__ = 2;
0059:            public final static int scrollOrientation_after__ = 3;
0060:            public final static int scrollOrientation_before__ = 4;
0061:            public final static int scrollOrientation_prior__ = 5;
0062:            public final static int scrollOrientation_first__ = 6;
0063:            public final static int scrollOrientation_last__ = 7;
0064:            public final static int scrollOrientation_current__ = 8;
0065:            public final static int scrollOrientation_next__ = 0;
0066:
0067:            public final static int updatability_unknown__ = 0;
0068:            public final static int updatability_readOnly__ = 1;
0069:            public final static int updatability_delete__ = 2;
0070:            public final static int updatability_update__ = 4;
0071:
0072:            public final static int sensitivity_unknown__ = 0;
0073:            public final static int sensitivity_insensitive__ = 1;
0074:            public final static int sensitivity_sensitive_static__ = 2;
0075:            public final static int sensitivity_sensitive_dynamic__ = 3;
0076:
0077:            static final private int WAS_NULL = 1;
0078:            static final private int WAS_NOT_NULL = 2;
0079:            static final private int WAS_NULL_UNSET = 0;
0080:
0081:            static final public int NEXT_ROWSET = 1;
0082:            static final public int PREVIOUS_ROWSET = 2;
0083:            static final public int ABSOLUTE_ROWSET = 3;
0084:            static final public int FIRST_ROWSET = 4;
0085:            static final public int LAST_ROWSET = 5;
0086:            static final public int RELATIVE_ROWSET = 6;
0087:            static final public int REFRESH_ROWSET = 7;
0088:            //  determines if a cursor is a:
0089:            //    Return to Client - not to be read by the stored procedure only by client
0090:            //    Return to Caller
0091:            public static final byte DDM_RETURN_CALLER = 0x01;
0092:            public static final byte DDM_RETURN_CLIENT = 0x02;
0093:
0094:            //-----------------------------state------------------------------------------
0095:
0096:            // Note:
0097:            //   Result set meta data as described by the SQLDA is described in ColumnMetaData.
0098:
0099:            private int wasNull_ = WAS_NULL_UNSET;
0100:
0101:            // ResultSet returnability for Stored Procedure cursors
0102:            //  determines if a cursor is a:
0103:            //    Return to Client - not to be read by the stored procedure only by client
0104:            //    Return to Caller - only calling JSP can read it, not the client
0105:            protected byte rsReturnability_ = DDM_RETURN_CLIENT;
0106:
0107:            // This means the client-side jdbc result set object is open.
0108:            boolean openOnClient_ = true;
0109:            // This means a server-side DERBY query section (cursor) for this result set is in the open state.
0110:            // A jdbc result set may remain open even after the server has closed its cursor
0111:            // (openOnClient=true, openOnServer=false); this is known as the "close-only" state.
0112:            public boolean openOnServer_ = true;
0113:
0114:            // there is a query terminating sqlca returned from the server when the server closes
0115:            // it's cursor and the client moves to the close-only state.
0116:            public Sqlca queryTerminatingSqlca_;
0117:
0118:            // Only true for forward cursors after next() returns false (+100).
0119:            // Used to prevent multiple commits for subsequent next() calls.
0120:            boolean autoCommitted_ = false;
0121:
0122:            // Before the first call to next() or any cursor positioning method, the cursor position is invalid
0123:            // and getter methods cannot be called.
0124:            // Also, if a cursor is exhausted (+100), the cursor position is invalid.
0125:            public boolean isValidCursorPosition_ = false;
0126:
0127:            public boolean cursorHold_;
0128:
0129:            // query instance identifier returned on open by uplevel servers.
0130:            // this value plus the package information uniquely identifies a query.
0131:            // it is 64 bits long and it's value is unarchitected.
0132:            public long queryInstanceIdentifier_ = 0;
0133:
0134:            public int resultSetType_;
0135:            public int resultSetConcurrency_;
0136:            public int resultSetHoldability_;
0137:            public boolean scrollable_ = false;
0138:            public int sensitivity_;
0139:            public boolean isRowsetCursor_ = false;
0140:            public boolean isBeforeFirst_ = true;
0141:            public boolean isAfterLast_ = false;
0142:            public boolean isFirst_ = false;
0143:            public boolean isLast_ = false;
0144:            public boolean rowsetContainsLastRow_ = false;
0145:            public Sqlca[] rowsetSqlca_;
0146:
0147:            // Gets its initial value from the statement when the result set is created.
0148:            // It can be modified by setFetchSize and retrieved via getFetchSize.
0149:            protected int suggestedFetchSize_;
0150:
0151:            // Set by the net layer based on suggestedFetchSize_, protocol
0152:            // type, scrollability and presence of lobs.
0153:            public int fetchSize_;
0154:
0155:            public int fetchDirection_;
0156:
0157:            public long rowCount_ = -1;
0158:
0159:            protected long absolutePosition_ = 0; // absolute position of the current row
0160:            protected long firstRowInRowset_ = 0; // absolute position of the first row in the current rowset
0161:            protected long lastRowInRowset_ = 0; // absolute position of the last row in the current rowset
0162:            protected long currentRowInRowset_ = -1; // relative position to the first row in the current rowsetwel
0163:
0164:            protected long absoluteRowNumberForTheIntendedRow_;
0165:
0166:            private boolean isOnInsertRow_ = false; // reserved for later
0167:            protected boolean isOnCurrentRow_ = true;
0168:            public int rowsReceivedInCurrentRowset_ = 0; // keep track of the number of rows received in the
0169:            // current rowset so far
0170:
0171:            // maybe be able to consolidate with rowsReceivedInCurrentRowset_
0172:            // Could use the rowsReceivedInCurrentRowset_ flag. But since we are going to set it to the
0173:            // fetchSize and decrement it each time we successfully receiveds a row, the name will be confusing.
0174:            // Fetch size can be changed in the middle of a rowset, and since we don't pre-parse all the rows \
0175:            // for forward-only cursors like we do for scrollable cursors, we will lose the original fetchSize
0176:            // when it's reset.  By decrementing rowsYetToBeReceivedInRowset_, when we come across a fetch
0177:            // request, if rowsYetToBeReceivedInRowset_ is 0, then we can fetch using the "new" fetchSize,
0178:            // otherwise, we will use rowsYetToBeReceivedInRowset_ to complete the rowset.
0179:            public int rowsYetToBeReceivedForRowset_ = 0; // keep track of the number of rows still need to
0180:            // be received to complete the rowset
0181:
0182:            private Object updatedColumns_[];
0183:
0184:            // Keeps track of whether a column has been updated.  If a column is updated to null,
0185:            // the object array updatedColumns_ entry is null, and we will use this array to distinguish
0186:            // between column not updated and column updated to null.
0187:            private boolean columnUpdated_[];
0188:
0189:            public PreparedStatement preparedStatementForUpdate_;
0190:            public PreparedStatement preparedStatementForDelete_;
0191:            public PreparedStatement preparedStatementForInsert_;
0192:
0193:            // Nesting level of the result set in a stored procedure
0194:            public int nestingLevel_ = -1;
0195:
0196:            // Whenever a commit occurs, it unpositions the cursor on the server.  We need to
0197:            // reposition the cursor before updating/deleting again.  This flag will be set to true
0198:            // whenever a commit happens, and reset to false again after we repositoin the cursor.
0199:            public boolean cursorUnpositionedOnServer_ = false;
0200:
0201:            // Keep maxRows in the ResultSet, so that changes to maxRow in the statement
0202:            // do not affect the resultSet after it has been created
0203:            private int maxRows_;
0204:
0205:            private boolean[] streamUsedFlags_;
0206:
0207:            //---------------------constructors/finalizer---------------------------------
0208:
0209:            protected ResultSet(Agent agent, Statement statement,
0210:                    Cursor cursor, int resultSetType, int resultSetConcurrency,
0211:                    int resultSetHoldability) {
0212:                agent_ = agent;
0213:                statement_ = statement;
0214:                connection_ = statement_.connection_;
0215:                cursor_ = cursor;
0216:                if (cursor_ != null) {
0217:                    cursor_.maxFieldSize_ = statement_.maxFieldSize_;
0218:                }
0219:                resultSetType_ = resultSetType;
0220:                resultSetConcurrency_ = resultSetConcurrency;
0221:                resultSetHoldability_ = resultSetHoldability;
0222:                fetchDirection_ = statement_.fetchDirection_;
0223:                suggestedFetchSize_ = statement_.fetchSize_;
0224:
0225:                maxRows_ = statement_.maxRows_;
0226:
0227:                // Only set the warning if actual resultSetType returned by the server is less
0228:                // than the application requested resultSetType.
0229:                // TYPE_FORWARD_ONLY = 1003
0230:                // TYPE_SCROLL_INSENSITIVE = 1004
0231:                // TYPE_SCROLL_SENSITIVE = 1005
0232:                if (resultSetType_ < statement_.resultSetType_) {
0233:                    statement_.accumulateWarning(new SqlWarning(
0234:                            agent_.logWriter_, new ClientMessageId(
0235:                                    SQLState.INVALID_RESULTSET_TYPE),
0236:                            new Integer(statement_.resultSetType_),
0237:                            new Integer(resultSetType_)));
0238:                }
0239:
0240:                // Only set the warning if actual resultSetConcurrency returned by the server is
0241:                // less than the application requested resultSetConcurrency.
0242:                // CONCUR_READ_ONLY = 1007
0243:                // CONCUR_UPDATABLE = 1008
0244:                if (resultSetConcurrency_ < statement_.resultSetConcurrency_) {
0245:                    accumulateWarning(new SqlWarning(
0246:                            agent_.logWriter_,
0247:                            new ClientMessageId(
0248:                                    SQLState.QUERY_NOT_QUALIFIED_FOR_UPDATABLE_RESULTSET)));
0249:
0250:                }
0251:
0252:                listenToUnitOfWork();
0253:            }
0254:
0255:            // ---------------------------jdbc 1------------------------------------------
0256:
0257:            public final boolean next() throws SQLException {
0258:                try {
0259:                    synchronized (connection_) {
0260:                        if (agent_.loggingEnabled()) {
0261:                            agent_.logWriter_.traceEntry(this , "next");
0262:                        }
0263:                        boolean isValidCursorPosition = nextX();
0264:                        if (agent_.loggingEnabled()) {
0265:                            agent_.logWriter_.traceExit(this , "next",
0266:                                    isValidCursorPosition);
0267:                        }
0268:                        return isValidCursorPosition;
0269:                    }
0270:                } catch (SqlException se) {
0271:                    throw se.getSQLException();
0272:                }
0273:            }
0274:
0275:            // used by DBMD
0276:            boolean nextX() throws SqlException {
0277:                checkForClosedResultSet();
0278:                clearWarningsX();
0279:
0280:                moveToCurrentRowX();
0281:
0282:                wasNull_ = ResultSet.WAS_NULL_UNSET;
0283:
0284:                // discard all previous updates when moving the cursor
0285:                resetUpdatedColumns();
0286:
0287:                unuseStreams();
0288:
0289:                // for TYPE_FORWARD_ONLY ResultSet, just call cursor.next()
0290:                if (resultSetType_ == java.sql.ResultSet.TYPE_FORWARD_ONLY) {
0291:                    // cursor is null for singleton selects that do not return data.
0292:                    isValidCursorPosition_ = (cursor_ == null) ? false
0293:                            : cursor_.next();
0294:
0295:                    // for forward-only cursors, if qryrowset was specificed on OPNQRY or EXCSQLSTT,
0296:                    // then we must count the rows returned in the rowset to make sure we received a
0297:                    // complete rowset.  if not, we need to complete the rowset on the next fetch.
0298:                    if (fetchSize_ != 0) {
0299:                        if (rowsYetToBeReceivedForRowset_ == 0) {
0300:                            rowsYetToBeReceivedForRowset_ = fetchSize_;
0301:                        }
0302:                        if (isValidCursorPosition_) {
0303:                            rowsYetToBeReceivedForRowset_--;
0304:                        }
0305:                    }
0306:
0307:                    // Auto-commit semantics for exhausted cursors follows.
0308:                    // From Connection.setAutoCommit() javadoc:
0309:                    //   The commit occurs when the statement completes or the next execute occurs, whichever comes first.
0310:                    //   In the case of statements returning a ResultSet object, the statement completes when the
0311:                    //   last row of the ResultSet object has been retrieved or the ResultSet object has been closed.
0312:                    //   In advanced cases, a single statement may return multiple results as well as output parameter values.
0313:                    //   In these cases, the commit occurs when all results and output parameter values have been retrieved.
0314:                    // we will check to see if the forward only result set has gone past the end,
0315:                    // we will close the result set, the autocommit logic is in the closeX() method
0316:                    //
0317:                    //Aug 24, 2005: Auto-commit logic is no longer in the closeX() method. Insted it has been 
0318:                    //moved to Statement and is handled in a manner similar to the embedded driver.
0319:                    //    if (!isValidCursorPosition_ && // We've gone past the end (+100)
0320:                    //        cursor_ != null) {
0321:                    if ((!isValidCursorPosition_ && cursor_ != null)
0322:                            || (maxRows_ > 0 && cursor_.rowsRead_ > maxRows_)) {
0323:                        isValidCursorPosition_ = false;
0324:
0325:                        // if not on a valid row and the query is closed at the server.
0326:                        // check for an error which may have caused the cursor to terminate.
0327:                        // if there were no more rows because of an error, then this method
0328:                        // should throw an SqlException rather than just returning false.
0329:                        // depending on how this works with scrollable cursors, there may be
0330:                        // a better way/more common place for this logic.
0331:                        SqlException sqlException = null;
0332:                        if (!openOnServer_) {
0333:                            int sqlcode = Utils
0334:                                    .getSqlcodeFromSqlca(queryTerminatingSqlca_);
0335:                            if (sqlcode > 0 && sqlcode != 100) {
0336:                                accumulateWarning(new SqlWarning(
0337:                                        agent_.logWriter_,
0338:                                        queryTerminatingSqlca_));
0339:                            } else if (sqlcode < 0) {
0340:                                sqlException = new SqlException(
0341:                                        agent_.logWriter_,
0342:                                        queryTerminatingSqlca_);
0343:                            }
0344:                        }
0345:
0346:                        try {
0347:                            statement_.resultSetCommitting(this );
0348:                        } catch (SqlException sqle) {
0349:                            sqlException = Utils.accumulateSQLException(sqle,
0350:                                    sqlException);
0351:                        }
0352:
0353:                        if (sqlException != null)
0354:                            throw sqlException;
0355:                    }
0356:                }
0357:
0358:                // for scrollable ResultSet's,
0359:                // if the "next" request is still fetching within the current rowset,
0360:                //   update column info from cache and increment the current row index
0361:                // else
0362:                //   fetch the next rowset from the server
0363:                else {
0364:
0365:                    // These flags will only be used for dynamic cursors where we don't know the row count
0366:                    // and can't keep track of the absolute position of the cursor.
0367:                    isAfterLast_ = false;
0368:                    isLast_ = false;
0369:
0370:                    // if the next row is still within the current rowset
0371:                    if (rowIsInCurrentRowset(firstRowInRowset_
0372:                            + currentRowInRowset_ + 1, scrollOrientation_next__)) {
0373:                        isValidCursorPosition_ = true;
0374:                        currentRowInRowset_++;
0375:                    } else {
0376:                        checkAndThrowReceivedQueryTerminatingException();
0377:                        isValidCursorPosition_ = getNextRowset();
0378:                    }
0379:
0380:                    if (isValidCursorPosition_) {
0381:                        updateColumnInfoFromCache();
0382:                        // check if there is a non-null SQLCA for the current row for rowset cursors
0383:                        checkRowsetSqlca();
0384:                        if (isBeforeFirst_) {
0385:                            isFirst_ = true;
0386:                        }
0387:                        isBeforeFirst_ = false;
0388:                    } else {
0389:                        isFirst_ = false;
0390:                        return isValidCursorPosition_;
0391:                    }
0392:                }
0393:
0394:                // for forward-only cursors, check if rowsRead_ > maxRows_.
0395:                // for scrollable cursors, check if absolute row number > maxRows_.
0396:                // maxRows_ will be ignored by sensitive dynamic cursors since we don't know the rowCount
0397:                if (!openOnClient_) {
0398:                    isValidCursorPosition_ = false;
0399:                } else if (sensitivity_ != sensitivity_sensitive_dynamic__
0400:                        && maxRows_ > 0
0401:                        && (firstRowInRowset_ + currentRowInRowset_ > maxRows_)) {
0402:                    isValidCursorPosition_ = false;
0403:                }
0404:                return isValidCursorPosition_;
0405:            }
0406:
0407:            public void close() throws SQLException {
0408:                try {
0409:                    synchronized (connection_) {
0410:                        if (agent_.loggingEnabled()) {
0411:                            agent_.logWriter_.traceEntry(this , "close");
0412:                        }
0413:                        closeX();
0414:                    }
0415:                } catch (SqlException se) {
0416:                    throw se.getSQLException();
0417:                }
0418:            }
0419:
0420:            // TO DO: when parseEndqryrm() notifies common w/ endQueryCloseOnlyEvent() we need to mark something
0421:            // that we later check to drive a commit.
0422:            // An untraced version of close()
0423:            public final void closeX() throws SqlException {
0424:                if (!openOnClient_) {
0425:                    return;
0426:                }
0427:                preClose_();
0428:                try {
0429:                    if (openOnServer_) {
0430:                        flowCloseAndAutoCommitIfNotAutoCommitted();
0431:                    } else {
0432:                        statement_.resultSetCommitting(this );
0433:                    }
0434:                } finally {
0435:                    markClosed(true);
0436:                }
0437:
0438:                if (statement_.openOnClient_ && statement_.isCatalogQuery_) {
0439:                    statement_.closeX();
0440:                }
0441:
0442:                nullDataForGC();
0443:            }
0444:
0445:            public void nullDataForGC() {
0446:                // This method is called by closeX().  We cannot call this if cursor is cached,
0447:                // otherwise it will cause NullPointerException's when cursor is reused.
0448:                // Cursor is only cached for PreparedStatement's.
0449:                if (cursor_ != null && !statement_.isPreparedStatement_) {
0450:                    cursor_.nullDataForGC();
0451:                }
0452:                cursor_ = null;
0453:                resultSetMetaData_ = null;
0454:            }
0455:
0456:            void flowCloseAndAutoCommitIfNotAutoCommitted() throws SqlException {
0457:                agent_.beginWriteChain(statement_);
0458:                boolean performedAutoCommit = writeCloseAndAutoCommit();
0459:                agent_.flow(statement_);
0460:                readCloseAndAutoCommit(performedAutoCommit);
0461:                agent_.endReadChain();
0462:            }
0463:
0464:            private boolean writeCloseAndAutoCommit() throws SqlException {
0465:                // set autoCommitted_ to false so commit will flow following
0466:                // close cursor if autoCommit is true.
0467:                autoCommitted_ = false;
0468:                if (generatedSection_ == null) { // none call statement result set case
0469:                    writeCursorClose_(statement_.section_);
0470:                } else { // call statement result set(s) case
0471:                    writeCursorClose_(generatedSection_);
0472:                }
0473:                return statement_.resultSetCommitting(this , true);
0474:            }
0475:
0476:            private void readCloseAndAutoCommit(boolean readAutoCommit)
0477:                    throws SqlException {
0478:                readCursorClose_();
0479:                if (readAutoCommit)
0480:                    readAutoCommitIfNotAutoCommitted();
0481:            }
0482:
0483:            void writeClose() throws SqlException {
0484:                // set autoCommitted_ to false so commit will flow following
0485:                // close cursor if autoCommit is true.
0486:                autoCommitted_ = false;
0487:                if (generatedSection_ == null) { // none call statement result set case
0488:                    writeCursorClose_(statement_.section_);
0489:                } else { // call statement result set(s) case
0490:                    writeCursorClose_(generatedSection_);
0491:                }
0492:            }
0493:
0494:            void readClose() throws SqlException {
0495:                try {
0496:                    if (generatedSection_ == null) { // none call statement result set case
0497:                        readCursorClose_();
0498:                    } else { // call statement result set(s) case
0499:                        readCursorClose_();
0500:                    }
0501:                } finally {
0502:                    markClosed();
0503:                }
0504:            }
0505:
0506:            // precondition: transaction state allows for auto commit to generate flow
0507:            private void writeAutoCommitIfNotAutoCommitted()
0508:                    throws SqlException {
0509:                if (connection_.autoCommit_ && !autoCommitted_) {
0510:                    connection_.writeAutoCommit();
0511:                }
0512:            }
0513:
0514:            private void readAutoCommitIfNotAutoCommitted() throws SqlException {
0515:                if (connection_.autoCommit_ && !autoCommitted_) {
0516:                    connection_.readAutoCommit();
0517:                    markAutoCommitted();
0518:                }
0519:            }
0520:
0521:            public boolean wasNull() throws SQLException {
0522:                try {
0523:                    if (agent_.loggingEnabled()) {
0524:                        agent_.logWriter_.traceEntry(this , "wasNull");
0525:                    }
0526:                    checkForClosedResultSet();
0527:
0528:                    if (wasNull_ == ResultSet.WAS_NULL_UNSET) {
0529:                        throw new SqlException(agent_.logWriter_,
0530:                                new ClientMessageId(SQLState.WASNULL_INVALID));
0531:                    }
0532:
0533:                    if (agent_.loggingEnabled()) {
0534:                        agent_.logWriter_.traceExit(this , "wasNull",
0535:                                wasNull_ == ResultSet.WAS_NULL);
0536:                    }
0537:                    return wasNull_ == ResultSet.WAS_NULL;
0538:                } catch (SqlException se) {
0539:                    throw se.getSQLException();
0540:                }
0541:            }
0542:
0543:            //------------------- getters on column index --------------------------------
0544:
0545:            // Live life on the edge and run unsynchronized
0546:            public boolean getBoolean(int column) throws SQLException {
0547:                try {
0548:                    closeCloseFilterInputStream();
0549:
0550:                    if (agent_.loggingEnabled()) {
0551:                        agent_.logWriter_
0552:                                .traceEntry(this , "getBoolean", column);
0553:                    }
0554:                    checkGetterPreconditions(column);
0555:                    boolean result = false;
0556:                    if (wasNonNullSensitiveUpdate(column) || isOnInsertRow_) {
0557:                        if (isOnInsertRow_
0558:                                && updatedColumns_[column - 1] == null) {
0559:                            result = false;
0560:                        } else {
0561:                            result = agent_.crossConverters_
0562:                                    .setBooleanFromObject(
0563:                                            updatedColumns_[column - 1],
0564:                                            resultSetMetaData_.types_[column - 1]);
0565:                        }
0566:                    } else {
0567:                        result = isNull(column) ? false : cursor_
0568:                                .getBoolean(column);
0569:                    }
0570:                    if (agent_.loggingEnabled()) {
0571:                        agent_.logWriter_.traceExit(this , "getBoolean", result);
0572:                    }
0573:                    setWasNull(column); // Placed close to the return to minimize risk of thread interference
0574:                    return result;
0575:                } catch (SqlException se) {
0576:                    throw se.getSQLException();
0577:                }
0578:            }
0579:
0580:            // Live life on the edge and run unsynchronized
0581:            public byte getByte(int column) throws SQLException {
0582:                try {
0583:                    closeCloseFilterInputStream();
0584:
0585:                    if (agent_.loggingEnabled()) {
0586:                        agent_.logWriter_.traceEntry(this , "getByte", column);
0587:                    }
0588:                    checkGetterPreconditions(column);
0589:                    byte result = 0;
0590:                    if (wasNonNullSensitiveUpdate(column) || isOnInsertRow_) {
0591:                        if ((isOnInsertRow_)
0592:                                && (updatedColumns_[column - 1] == null)) {
0593:                            result = 0;
0594:                        } else {
0595:                            result = agent_.crossConverters_.setByteFromObject(
0596:                                    updatedColumns_[column - 1],
0597:                                    resultSetMetaData_.types_[column - 1]);
0598:                        }
0599:                    } else {
0600:                        result = isNull(column) ? 0 : cursor_.getByte(column);
0601:                    }
0602:                    if (agent_.loggingEnabled()) {
0603:                        agent_.logWriter_.traceExit(this , "getByte", result);
0604:                    }
0605:                    setWasNull(column); // Placed close to the return to minimize risk of thread interference
0606:                    return result;
0607:                } catch (SqlException se) {
0608:                    throw se.getSQLException();
0609:                }
0610:            }
0611:
0612:            // Live life on the edge and run unsynchronized
0613:            public short getShort(int column) throws SQLException {
0614:                try {
0615:                    closeCloseFilterInputStream();
0616:
0617:                    if (agent_.loggingEnabled()) {
0618:                        agent_.logWriter_.traceEntry(this , "getShort", column);
0619:                    }
0620:                    checkGetterPreconditions(column);
0621:                    short result = 0;
0622:                    if (wasNonNullSensitiveUpdate(column) || isOnInsertRow_) {
0623:                        if (isOnInsertRow_
0624:                                && updatedColumns_[column - 1] == null) {
0625:                            result = 0;
0626:                        } else {
0627:                            result = ((Short) agent_.crossConverters_
0628:                                    .setObject(java.sql.Types.SMALLINT,
0629:                                            updatedColumns_[column - 1]))
0630:                                    .shortValue();
0631:                        }
0632:                    } else {
0633:                        result = isNull(column) ? 0 : cursor_.getShort(column);
0634:                    }
0635:                    if (agent_.loggingEnabled()) {
0636:                        agent_.logWriter_.traceExit(this , "getShort", result);
0637:                    }
0638:                    setWasNull(column); // Placed close to the return to minimize risk of thread interference
0639:                    return result;
0640:                } catch (SqlException se) {
0641:                    throw se.getSQLException();
0642:                }
0643:            }
0644:
0645:            // Live life on the edge and run unsynchronized
0646:            public int getInt(int column) throws SQLException {
0647:                try {
0648:                    closeCloseFilterInputStream();
0649:
0650:                    if (agent_.loggingEnabled()) {
0651:                        agent_.logWriter_.traceEntry(this , "getInt", column);
0652:                    }
0653:                    checkGetterPreconditions(column);
0654:                    int result = 0;
0655:                    if (wasNonNullSensitiveUpdate(column) || isOnInsertRow_) {
0656:                        if (isOnInsertRow_
0657:                                && updatedColumns_[column - 1] == null) {
0658:                            result = 0;
0659:                        } else {
0660:                            result = ((Integer) agent_.crossConverters_
0661:                                    .setObject(java.sql.Types.INTEGER,
0662:                                            updatedColumns_[column - 1]))
0663:                                    .intValue();
0664:                        }
0665:                    } else {
0666:                        result = isNull(column) ? 0 : cursor_.getInt(column);
0667:                    }
0668:                    if (agent_.loggingEnabled()) {
0669:                        agent_.logWriter_.traceExit(this , "getInt", result);
0670:                    }
0671:                    setWasNull(column); // this is placed here close to the return to minimize risk of race condition.
0672:                    return result;
0673:                } catch (SqlException se) {
0674:                    throw se.getSQLException();
0675:                }
0676:            }
0677:
0678:            // Live life on the edge and run unsynchronized
0679:            public long getLong(int column) throws SQLException {
0680:                try {
0681:                    closeCloseFilterInputStream();
0682:
0683:                    if (agent_.loggingEnabled()) {
0684:                        agent_.logWriter_.traceEntry(this , "getLong", column);
0685:                    }
0686:                    checkGetterPreconditions(column);
0687:                    long result = 0;
0688:                    if (wasNonNullSensitiveUpdate(column) || isOnInsertRow_) {
0689:                        if (isOnInsertRow_
0690:                                && updatedColumns_[column - 1] == null) {
0691:                            result = 0;
0692:                        } else {
0693:                            result = ((Long) agent_.crossConverters_.setObject(
0694:                                    java.sql.Types.BIGINT,
0695:                                    updatedColumns_[column - 1])).longValue();
0696:                        }
0697:                    } else {
0698:                        result = isNull(column) ? 0 : cursor_.getLong(column);
0699:                    }
0700:                    if (agent_.loggingEnabled()) {
0701:                        agent_.logWriter_.traceExit(this , "getLong", result);
0702:                    }
0703:                    setWasNull(column); // Placed close to the return to minimize risk of thread interference
0704:                    return result;
0705:                } catch (SqlException se) {
0706:                    throw se.getSQLException();
0707:                }
0708:            }
0709:
0710:            // Live life on the edge and run unsynchronized
0711:            public float getFloat(int column) throws SQLException {
0712:                try {
0713:                    closeCloseFilterInputStream();
0714:
0715:                    if (agent_.loggingEnabled()) {
0716:                        agent_.logWriter_.traceEntry(this , "getFloat", column);
0717:                    }
0718:                    checkGetterPreconditions(column);
0719:                    float result = 0;
0720:                    if (wasNonNullSensitiveUpdate(column) || isOnInsertRow_) {
0721:                        if ((isOnInsertRow_ && updatedColumns_[column - 1] == null)) {
0722:                            result = 0;
0723:                        } else {
0724:                            result = ((Float) agent_.crossConverters_
0725:                                    .setObject(java.sql.Types.REAL,
0726:                                            updatedColumns_[column - 1]))
0727:                                    .floatValue();
0728:                        }
0729:                    } else {
0730:                        result = isNull(column) ? 0 : cursor_.getFloat(column);
0731:                    }
0732:                    if (agent_.loggingEnabled()) {
0733:                        agent_.logWriter_.traceExit(this , "getFloat", result);
0734:                    }
0735:                    setWasNull(column); // Placed close to the return to minimize risk of thread interference
0736:                    return result;
0737:                } catch (SqlException se) {
0738:                    throw se.getSQLException();
0739:                }
0740:            }
0741:
0742:            // Live life on the edge and run unsynchronized
0743:            public double getDouble(int column) throws SQLException {
0744:                try {
0745:                    closeCloseFilterInputStream();
0746:
0747:                    if (agent_.loggingEnabled()) {
0748:                        agent_.logWriter_.traceEntry(this , "getDouble", column);
0749:                    }
0750:                    checkGetterPreconditions(column);
0751:                    double result = 0;
0752:                    if (wasNonNullSensitiveUpdate(column) || isOnInsertRow_) {
0753:                        if (isOnInsertRow_
0754:                                && updatedColumns_[column - 1] == null) {
0755:                            result = 0;
0756:                        } else {
0757:                            result = ((Double) agent_.crossConverters_
0758:                                    .setObject(java.sql.Types.DOUBLE,
0759:                                            updatedColumns_[column - 1]))
0760:                                    .doubleValue();
0761:                        }
0762:                    } else {
0763:                        result = isNull(column) ? 0 : cursor_.getDouble(column);
0764:                    }
0765:                    if (agent_.loggingEnabled()) {
0766:                        agent_.logWriter_.traceExit(this , "getDouble", result);
0767:                    }
0768:                    setWasNull(column); // Placed close to the return to minimize risk of thread interference
0769:                    return result;
0770:                } catch (SqlException se) {
0771:                    throw se.getSQLException();
0772:                }
0773:            }
0774:
0775:            // Live life on the edge and run unsynchronized
0776:            public java.math.BigDecimal getBigDecimal(int column, int scale)
0777:                    throws SQLException {
0778:                try {
0779:                    closeCloseFilterInputStream();
0780:
0781:                    if (agent_.loggingEnabled()) {
0782:                        agent_.logWriter_.traceDeprecatedEntry(this ,
0783:                                "getBigDecimal", column, scale);
0784:                    }
0785:                    checkGetterPreconditions(column);
0786:                    java.math.BigDecimal result = null;
0787:                    if (wasNonNullSensitiveUpdate(column)) {
0788:                        result = ((java.math.BigDecimal) agent_.crossConverters_
0789:                                .setObject(java.sql.Types.DECIMAL,
0790:                                        updatedColumns_[column - 1])).setScale(
0791:                                scale, java.math.BigDecimal.ROUND_DOWN);
0792:                    } else {
0793:                        result = isNull(column) ? null : cursor_.getBigDecimal(
0794:                                column).setScale(scale,
0795:                                java.math.BigDecimal.ROUND_DOWN);
0796:                    }
0797:                    if (agent_.loggingEnabled()) {
0798:                        agent_.logWriter_.traceDeprecatedExit(this ,
0799:                                "getBigDecimal", result);
0800:                    }
0801:                    setWasNull(column); // Placed close to the return to minimize risk of thread interference
0802:                    return result;
0803:                } catch (SqlException se) {
0804:                    throw se.getSQLException();
0805:                }
0806:            }
0807:
0808:            // Live life on the edge and run unsynchronized
0809:            public java.math.BigDecimal getBigDecimal(int column)
0810:                    throws SQLException {
0811:                try {
0812:
0813:                    closeCloseFilterInputStream();
0814:
0815:                    if (agent_.loggingEnabled()) {
0816:                        agent_.logWriter_.traceEntry(this , "getBigDecimal",
0817:                                column);
0818:                    }
0819:                    checkGetterPreconditions(column);
0820:                    java.math.BigDecimal result = null;
0821:                    if (wasNonNullSensitiveUpdate(column)) {
0822:                        result = (java.math.BigDecimal) agent_.crossConverters_
0823:                                .setObject(java.sql.Types.DECIMAL,
0824:                                        updatedColumns_[column - 1]);
0825:                    } else {
0826:                        result = isNull(column) ? null : cursor_
0827:                                .getBigDecimal(column);
0828:                    }
0829:                    if (agent_.loggingEnabled()) {
0830:                        agent_.logWriter_.traceExit(this , "getBigDecimal",
0831:                                result);
0832:                    }
0833:                    setWasNull(column); // Placed close to the return to minimize risk of thread interference
0834:                    return result;
0835:                } catch (SqlException se) {
0836:                    throw se.getSQLException();
0837:                }
0838:            }
0839:
0840:            // Live life on the edge and run unsynchronized
0841:            public java.sql.Date getDate(int column) throws SQLException {
0842:                try {
0843:                    closeCloseFilterInputStream();
0844:
0845:                    if (agent_.loggingEnabled()) {
0846:                        agent_.logWriter_.traceEntry(this , "getDate", column);
0847:                    }
0848:                    checkGetterPreconditions(column);
0849:                    java.sql.Date result = null;
0850:                    if (wasNonNullSensitiveUpdate(column)) {
0851:                        result = (java.sql.Date) agent_.crossConverters_
0852:                                .setObject(java.sql.Types.DATE,
0853:                                        updatedColumns_[column - 1]);
0854:                    } else {
0855:                        result = isNull(column) ? null : cursor_
0856:                                .getDate(column);
0857:                    }
0858:                    if (agent_.loggingEnabled()) {
0859:                        agent_.logWriter_.traceExit(this , "getDate", result);
0860:                    }
0861:                    setWasNull(column); // Placed close to the return to minimize risk of thread interference
0862:                    return result;
0863:                } catch (SqlException se) {
0864:                    throw se.getSQLException();
0865:                }
0866:            }
0867:
0868:            // Live life on the edge and run unsynchronized
0869:            public java.sql.Date getDate(int column, java.util.Calendar calendar)
0870:                    throws SQLException {
0871:                try {
0872:                    closeCloseFilterInputStream();
0873:
0874:                    if (agent_.loggingEnabled()) {
0875:                        agent_.logWriter_.traceEntry(this , "getDate", column,
0876:                                calendar);
0877:                    }
0878:                    java.sql.Date date = getDate(column);
0879:                    if (calendar == null) {
0880:                        throw new SqlException(agent_.logWriter_,
0881:                                new ClientMessageId(SQLState.CALENDAR_IS_NULL));
0882:                    }
0883:                    if (date != null) {
0884:                        java.util.Calendar targetCalendar = java.util.Calendar
0885:                                .getInstance(calendar.getTimeZone());
0886:                        targetCalendar.clear();
0887:                        targetCalendar.setTime(date);
0888:                        java.util.Calendar defaultCalendar = java.util.Calendar
0889:                                .getInstance();
0890:                        defaultCalendar.clear();
0891:                        defaultCalendar.setTime(date);
0892:                        long timeZoneOffset = targetCalendar
0893:                                .get(java.util.Calendar.ZONE_OFFSET)
0894:                                - defaultCalendar
0895:                                        .get(java.util.Calendar.ZONE_OFFSET)
0896:                                + targetCalendar
0897:                                        .get(java.util.Calendar.DST_OFFSET)
0898:                                - defaultCalendar
0899:                                        .get(java.util.Calendar.DST_OFFSET);
0900:                        date.setTime(date.getTime() - timeZoneOffset);
0901:                    }
0902:                    if (agent_.loggingEnabled()) {
0903:                        agent_.logWriter_.traceExit(this , "getDate", date);
0904:                    }
0905:                    return date;
0906:                } catch (SqlException se) {
0907:                    throw se.getSQLException();
0908:                }
0909:            }
0910:
0911:            // Live life on the edge and run unsynchronized
0912:            public java.sql.Time getTime(int column) throws SQLException {
0913:                try {
0914:                    closeCloseFilterInputStream();
0915:
0916:                    if (agent_.loggingEnabled()) {
0917:                        agent_.logWriter_.traceEntry(this , "getTime", column);
0918:                    }
0919:                    checkGetterPreconditions(column);
0920:                    java.sql.Time result = null;
0921:                    if (wasNonNullSensitiveUpdate(column)) {
0922:                        result = (java.sql.Time) agent_.crossConverters_
0923:                                .setObject(java.sql.Types.TIME,
0924:                                        updatedColumns_[column - 1]);
0925:                    } else {
0926:                        result = isNull(column) ? null : cursor_
0927:                                .getTime(column);
0928:                    }
0929:                    if (agent_.loggingEnabled()) {
0930:                        agent_.logWriter_.traceExit(this , "getTime", result);
0931:                    }
0932:                    setWasNull(column); // Placed close to the return to minimize risk of thread interference
0933:                    return result;
0934:                } catch (SqlException se) {
0935:                    throw se.getSQLException();
0936:                }
0937:            }
0938:
0939:            // Live life on the edge and run unsynchronized
0940:            public java.sql.Time getTime(int column, java.util.Calendar calendar)
0941:                    throws SQLException {
0942:                try {
0943:                    closeCloseFilterInputStream();
0944:
0945:                    if (agent_.loggingEnabled()) {
0946:                        agent_.logWriter_.traceEntry(this , "getTime", column,
0947:                                calendar);
0948:                    }
0949:                    java.sql.Time time = getTime(column);
0950:                    if (calendar == null) {
0951:                        throw new SqlException(agent_.logWriter_,
0952:                                new ClientMessageId(SQLState.CALENDAR_IS_NULL));
0953:                    }
0954:                    if (time != null) {
0955:                        java.util.Calendar targetCalendar = java.util.Calendar
0956:                                .getInstance(calendar.getTimeZone());
0957:                        targetCalendar.clear();
0958:                        targetCalendar.setTime(time);
0959:                        java.util.Calendar defaultCalendar = java.util.Calendar
0960:                                .getInstance();
0961:                        defaultCalendar.clear();
0962:                        defaultCalendar.setTime(time);
0963:                        long timeZoneOffset = targetCalendar
0964:                                .get(java.util.Calendar.ZONE_OFFSET)
0965:                                - defaultCalendar
0966:                                        .get(java.util.Calendar.ZONE_OFFSET)
0967:                                + targetCalendar
0968:                                        .get(java.util.Calendar.DST_OFFSET)
0969:                                - defaultCalendar
0970:                                        .get(java.util.Calendar.DST_OFFSET);
0971:                        time.setTime(time.getTime() - timeZoneOffset);
0972:                    }
0973:                    if (agent_.loggingEnabled()) {
0974:                        agent_.logWriter_.traceExit(this , "getTime", time);
0975:                    }
0976:                    return time;
0977:                } catch (SqlException se) {
0978:                    throw se.getSQLException();
0979:                }
0980:            }
0981:
0982:            // Live life on the edge and run unsynchronized
0983:            public java.sql.Timestamp getTimestamp(int column)
0984:                    throws SQLException {
0985:                try {
0986:                    closeCloseFilterInputStream();
0987:
0988:                    if (agent_.loggingEnabled()) {
0989:                        agent_.logWriter_.traceEntry(this , "getTimestamp",
0990:                                column);
0991:                    }
0992:                    checkGetterPreconditions(column);
0993:                    java.sql.Timestamp result = null;
0994:                    if (wasNonNullSensitiveUpdate(column)) {
0995:                        result = (java.sql.Timestamp) agent_.crossConverters_
0996:                                .setObject(java.sql.Types.TIMESTAMP,
0997:                                        updatedColumns_[column - 1]);
0998:                    } else {
0999:                        result = isNull(column) ? null : cursor_
1000:                                .getTimestamp(column);
1001:                    }
1002:                    if (agent_.loggingEnabled()) {
1003:                        agent_.logWriter_.traceExit(this , "getTimestamp",
1004:                                result);
1005:                    }
1006:                    setWasNull(column); // Placed close to the return to minimize risk of thread interference
1007:                    return result;
1008:                } catch (SqlException se) {
1009:                    throw se.getSQLException();
1010:                }
1011:            }
1012:
1013:            // Live life on the edge and run unsynchronized
1014:            public java.sql.Timestamp getTimestamp(int column,
1015:                    java.util.Calendar calendar) throws SQLException {
1016:                try {
1017:                    closeCloseFilterInputStream();
1018:
1019:                    if (agent_.loggingEnabled()) {
1020:                        agent_.logWriter_.traceEntry(this , "getTimestamp",
1021:                                column, calendar);
1022:                    }
1023:                    java.sql.Timestamp timestamp = getTimestamp(column);
1024:                    if (calendar == null) {
1025:                        throw new SqlException(agent_.logWriter_,
1026:                                new ClientMessageId(SQLState.CALENDAR_IS_NULL));
1027:                    }
1028:                    if (timestamp != null) {
1029:                        int nano = timestamp.getNanos();
1030:                        java.util.Calendar targetCalendar = java.util.Calendar
1031:                                .getInstance(calendar.getTimeZone());
1032:                        targetCalendar.clear();
1033:                        targetCalendar.setTime(timestamp);
1034:                        java.util.Calendar defaultCalendar = java.util.Calendar
1035:                                .getInstance();
1036:                        defaultCalendar.clear();
1037:                        defaultCalendar.setTime(timestamp);
1038:                        long timeZoneOffset = targetCalendar
1039:                                .get(java.util.Calendar.ZONE_OFFSET)
1040:                                - defaultCalendar
1041:                                        .get(java.util.Calendar.ZONE_OFFSET)
1042:                                + targetCalendar
1043:                                        .get(java.util.Calendar.DST_OFFSET)
1044:                                - defaultCalendar
1045:                                        .get(java.util.Calendar.DST_OFFSET);
1046:                        timestamp.setTime(timestamp.getTime() - timeZoneOffset);
1047:                        timestamp.setNanos(nano);
1048:                    }
1049:                    if (agent_.loggingEnabled()) {
1050:                        agent_.logWriter_.traceExit(this , "getTimestamp",
1051:                                timestamp);
1052:                    }
1053:                    return timestamp;
1054:                } catch (SqlException se) {
1055:                    throw se.getSQLException();
1056:                }
1057:            }
1058:
1059:            // Live life on the edge and run unsynchronized
1060:            public String getString(int column) throws SQLException {
1061:                try {
1062:                    closeCloseFilterInputStream();
1063:
1064:                    if (agent_.loggingEnabled()) {
1065:                        agent_.logWriter_.traceEntry(this , "getString", column);
1066:                    }
1067:                    checkGetterPreconditions(column);
1068:                    String result = null;
1069:                    if (wasNonNullSensitiveUpdate(column)) {
1070:                        result = (String) agent_.crossConverters_.setObject(
1071:                                java.sql.Types.CHAR,
1072:                                updatedColumns_[column - 1]);
1073:                    } else {
1074:                        result = isNull(column) ? null : cursor_
1075:                                .getString(column);
1076:                    }
1077:                    if (agent_.loggingEnabled()) {
1078:                        agent_.logWriter_.traceExit(this , "getString", result);
1079:                    }
1080:                    setWasNull(column); // Placed close to the return to minimize risk of thread interference
1081:                    return result;
1082:                } catch (SqlException se) {
1083:                    throw se.getSQLException();
1084:                }
1085:            }
1086:
1087:            // Live life on the edge and run unsynchronized
1088:            public byte[] getBytes(int column) throws SQLException {
1089:                try {
1090:                    closeCloseFilterInputStream();
1091:
1092:                    if (agent_.loggingEnabled()) {
1093:                        agent_.logWriter_.traceEntry(this , "getBytes", column);
1094:                    }
1095:                    checkGetterPreconditions(column);
1096:                    byte[] result = null;
1097:                    if (wasNonNullSensitiveUpdate(column)) {
1098:                        result = (byte[]) agent_.crossConverters_.setObject(
1099:                                java.sql.Types.BINARY,
1100:                                updatedColumns_[column - 1]);
1101:                    } else {
1102:                        result = isNull(column) ? null : cursor_
1103:                                .getBytes(column);
1104:                    }
1105:                    if (agent_.loggingEnabled()) {
1106:                        agent_.logWriter_.traceExit(this , "getBytes", result);
1107:                    }
1108:                    setWasNull(column); // Placed close to the return to minimize risk of thread interference
1109:                    return result;
1110:                } catch (SqlException se) {
1111:                    throw se.getSQLException();
1112:                }
1113:            }
1114:
1115:            // Live life on the edge and run unsynchronized
1116:            public java.io.InputStream getBinaryStream(int column)
1117:                    throws SQLException {
1118:                try {
1119:                    closeCloseFilterInputStream();
1120:
1121:                    if (agent_.loggingEnabled()) {
1122:                        agent_.logWriter_.traceEntry(this , "getBinaryStream",
1123:                                column);
1124:                    }
1125:
1126:                    checkGetterPreconditions(column);
1127:                    useStream(column);
1128:
1129:                    java.io.InputStream result = null;
1130:                    if (wasNonNullSensitiveUpdate(column)) {
1131:                        result = new java.io.ByteArrayInputStream(
1132:                                (byte[]) agent_.crossConverters_.setObject(
1133:                                        java.sql.Types.BINARY,
1134:                                        updatedColumns_[column - 1]));
1135:                    } else {
1136:                        result = isNull(column) ? null : cursor_
1137:                                .getBinaryStream(column);
1138:                    }
1139:                    if (agent_.loggingEnabled()) {
1140:                        agent_.logWriter_.traceExit(this , "getBinaryStream",
1141:                                result);
1142:                    }
1143:                    setWasNull(column); // Placed close to the return to minimize risk of thread interference
1144:                    return createCloseFilterInputStream(result);
1145:                } catch (SqlException se) {
1146:                    throw se.getSQLException();
1147:                }
1148:            }
1149:
1150:            // Live life on the edge and run unsynchronized
1151:            public java.io.InputStream getAsciiStream(int column)
1152:                    throws SQLException {
1153:                try {
1154:                    closeCloseFilterInputStream();
1155:
1156:                    if (agent_.loggingEnabled()) {
1157:                        agent_.logWriter_.traceEntry(this , "getAsciiStream",
1158:                                column);
1159:                    }
1160:
1161:                    checkGetterPreconditions(column);
1162:                    useStream(column);
1163:
1164:                    java.io.InputStream result = null;
1165:                    if (wasNonNullSensitiveUpdate(column)) {
1166:
1167:                        result = new AsciiStream(
1168:                                (String) agent_.crossConverters_.setObject(
1169:                                        java.sql.Types.CHAR,
1170:                                        updatedColumns_[column - 1]));
1171:                    } else {
1172:                        result = isNull(column) ? null : cursor_
1173:                                .getAsciiStream(column);
1174:                    }
1175:                    if (agent_.loggingEnabled()) {
1176:                        agent_.logWriter_.traceExit(this , "getAsciiStream",
1177:                                result);
1178:                    }
1179:                    setWasNull(column); // Placed close to the return to minimize risk of thread interference
1180:                    return createCloseFilterInputStream(result);
1181:                } catch (SqlException se) {
1182:                    throw se.getSQLException();
1183:                }
1184:            }
1185:
1186:            /**
1187:             * Retrieve the value of the specified column as a stream of two-byte
1188:             * Unicode characters. Deprecated in JDBC 2.0 and this method will just
1189:             * throw a feature not implemented exception.
1190:             *
1191:             * @param column the column to retrieve as a Unicode stream
1192:             * @exception SQLException throws feature not implemented
1193:             */
1194:            public java.io.InputStream getUnicodeStream(int column)
1195:                    throws SQLException {
1196:                if (agent_.loggingEnabled()) {
1197:                    agent_.logWriter_.traceDeprecatedEntry(this ,
1198:                            "getUnicodeStream", column);
1199:                }
1200:
1201:                throw SQLExceptionFactory.notImplemented("getUnicodeStream");
1202:            }
1203:
1204:            // Live life on the edge and run unsynchronized
1205:            public java.io.Reader getCharacterStream(int column)
1206:                    throws SQLException {
1207:                try {
1208:                    closeCloseFilterInputStream();
1209:
1210:                    if (agent_.loggingEnabled()) {
1211:                        agent_.logWriter_.traceEntry(this ,
1212:                                "getCharacterStream", column);
1213:                    }
1214:
1215:                    checkGetterPreconditions(column);
1216:                    useStream(column);
1217:
1218:                    java.io.Reader result = null;
1219:                    if (wasNonNullSensitiveUpdate(column)) {
1220:                        result = new java.io.StringReader(
1221:                                (String) agent_.crossConverters_.setObject(
1222:                                        java.sql.Types.CHAR,
1223:                                        updatedColumns_[column - 1]));
1224:                    } else {
1225:                        result = isNull(column) ? null : cursor_
1226:                                .getCharacterStream(column);
1227:                    }
1228:                    if (agent_.loggingEnabled()) {
1229:                        agent_.logWriter_.traceExit(this , "getCharacterStream",
1230:                                result);
1231:                    }
1232:                    setWasNull(column); // Placed close to the return to minimize risk of thread interference
1233:                    return result;
1234:                } catch (SqlException se) {
1235:                    throw se.getSQLException();
1236:                }
1237:            }
1238:
1239:            // Live life on the edge and run unsynchronized
1240:            public java.sql.Blob getBlob(int column) throws SQLException {
1241:                try {
1242:                    closeCloseFilterInputStream();
1243:
1244:                    if (agent_.loggingEnabled()) {
1245:                        agent_.logWriter_.traceEntry(this , "getBlob", column);
1246:                    }
1247:                    checkGetterPreconditions(column);
1248:                    java.sql.Blob result = null;
1249:                    if (wasNonNullSensitiveUpdate(column)) {
1250:                        result = (java.sql.Blob) agent_.crossConverters_
1251:                                .setObject(java.sql.Types.BLOB,
1252:                                        updatedColumns_[column - 1]);
1253:                    } else {
1254:                        result = isNull(column) ? null : cursor_
1255:                                .getBlob(column);
1256:                    }
1257:                    if (agent_.loggingEnabled()) {
1258:                        agent_.logWriter_.traceExit(this , "getBlob", result);
1259:                    }
1260:                    setWasNull(column); // Placed close to the return to minimize risk of thread interference
1261:                    return result;
1262:                } catch (SqlException se) {
1263:                    throw se.getSQLException();
1264:                }
1265:            }
1266:
1267:            // Live life on the edge and run unsynchronized
1268:            public java.sql.Clob getClob(int column) throws SQLException {
1269:                try {
1270:                    closeCloseFilterInputStream();
1271:
1272:                    if (agent_.loggingEnabled()) {
1273:                        agent_.logWriter_.traceEntry(this , "getClob", column);
1274:                    }
1275:                    checkGetterPreconditions(column);
1276:                    java.sql.Clob result = null;
1277:                    if (wasNonNullSensitiveUpdate(column)) {
1278:                        result = (java.sql.Clob) agent_.crossConverters_
1279:                                .setObject(java.sql.Types.CLOB,
1280:                                        updatedColumns_[column - 1]);
1281:                    } else {
1282:                        result = isNull(column) ? null : cursor_
1283:                                .getClob(column);
1284:                    }
1285:                    if (agent_.loggingEnabled()) {
1286:                        agent_.logWriter_.traceExit(this , "getClob", result);
1287:                    }
1288:                    setWasNull(column); // Placed close to the return to minimize risk of thread interference
1289:                    return result;
1290:                } catch (SqlException se) {
1291:                    throw se.getSQLException();
1292:                }
1293:            }
1294:
1295:            // Live life on the edge and run unsynchronized
1296:            public java.sql.Ref getRef(int column) throws SQLException {
1297:                try {
1298:                    closeCloseFilterInputStream();
1299:
1300:                    if (agent_.loggingEnabled()) {
1301:                        agent_.logWriter_.traceEntry(this , "getRef", column);
1302:                    }
1303:                    checkGetterPreconditions(column);
1304:                    java.sql.Ref result = isNull(column) ? null : cursor_
1305:                            .getRef(column);
1306:                    if (true) {
1307:                        throw new SqlException(agent_.logWriter_,
1308:                                new ClientMessageId(
1309:                                        SQLState.JDBC_METHOD_NOT_IMPLEMENTED));
1310:                    }
1311:                    if (agent_.loggingEnabled()) {
1312:                        agent_.logWriter_.traceExit(this , "getRef", result);
1313:                    }
1314:                    setWasNull(column); // Placed close to the return to minimize risk of thread interference
1315:                    return result;
1316:                } catch (SqlException se) {
1317:                    throw se.getSQLException();
1318:                }
1319:            }
1320:
1321:            // Live life on the edge and run unsynchronized
1322:            public java.sql.Array getArray(int column) throws SQLException {
1323:                try {
1324:                    closeCloseFilterInputStream();
1325:
1326:                    if (agent_.loggingEnabled()) {
1327:                        agent_.logWriter_.traceEntry(this , "getArray", column);
1328:                    }
1329:                    checkGetterPreconditions(column);
1330:                    java.sql.Array result = isNull(column) ? null : cursor_
1331:                            .getArray(column);
1332:                    if (true) {
1333:                        throw new SqlException(agent_.logWriter_,
1334:                                new ClientMessageId(
1335:                                        SQLState.JDBC_METHOD_NOT_IMPLEMENTED));
1336:                    }
1337:                    if (agent_.loggingEnabled()) {
1338:                        agent_.logWriter_.traceExit(this , "getArray", result);
1339:                    }
1340:                    setWasNull(column); // Placed close to the return to minimize risk of thread interference
1341:                    return result;
1342:                } catch (SqlException se) {
1343:                    throw se.getSQLException();
1344:                }
1345:            }
1346:
1347:            // Live life on the edge and run unsynchronized
1348:            public Object getObject(int column) throws SQLException {
1349:                try {
1350:                    closeCloseFilterInputStream();
1351:
1352:                    if (agent_.loggingEnabled()) {
1353:                        agent_.logWriter_.traceEntry(this , "getObject", column);
1354:                    }
1355:                    Object result = getObjectX(column);
1356:                    if (agent_.loggingEnabled()) {
1357:                        agent_.logWriter_.traceExit(this , "getObject", result);
1358:                    }
1359:                    return result;
1360:                } catch (SqlException se) {
1361:                    throw se.getSQLException();
1362:                }
1363:            }
1364:
1365:            // used by DBMD
1366:            Object getObjectX(int column) throws SqlException {
1367:                checkGetterPreconditions(column);
1368:                Object result = null;
1369:                if (wasNonNullSensitiveUpdate(column)) {
1370:                    result = updatedColumns_[column - 1];
1371:                } else {
1372:                    result = isNull(column) ? null : cursor_.getObject(column);
1373:                }
1374:                setWasNull(column); // Placed close to the return to minimize risk of thread interference
1375:                return result;
1376:            }
1377:
1378:            // Live life on the edge and run unsynchronized
1379:            public Object getObject(int column, java.util.Map map)
1380:                    throws SQLException {
1381:                try {
1382:                    closeCloseFilterInputStream();
1383:
1384:                    if (agent_.loggingEnabled()) {
1385:                        agent_.logWriter_.traceEntry(this , "getObject", column,
1386:                                map);
1387:                    }
1388:                    checkGetterPreconditions(column);
1389:                    Object result = null;
1390:                    if (wasNonNullSensitiveUpdate(column)) {
1391:                        result = updatedColumns_[column - 1];
1392:                    } else {
1393:                        result = isNull(column) ? null : cursor_
1394:                                .getObject(column);
1395:                    }
1396:                    if (true) {
1397:                        throw new SqlException(agent_.logWriter_,
1398:                                new ClientMessageId(
1399:                                        SQLState.JDBC_METHOD_NOT_IMPLEMENTED));
1400:                    }
1401:                    if (agent_.loggingEnabled()) {
1402:                        agent_.logWriter_.traceExit(this , "getObject", result);
1403:                    }
1404:                    setWasNull(column); // Placed close to the return to minimize risk of thread interference
1405:                    return result;
1406:                } catch (SqlException se) {
1407:                    throw se.getSQLException();
1408:                }
1409:            }
1410:
1411:            //----------------------------------------------------------------------------
1412:
1413:            // This method only returns true if there is a new non-null updated value.
1414:            // If the resultset is updatable, sensitive, and updated, return the new non-null updated value.
1415:            // Otherwise this method will return false.
1416:            // If the column is updated to null, or if the column has not been update but is null,
1417:            // a null will be returned by isNull(), which first calls wasNullSensitiveUpdate() to check for a column
1418:            // that is updated to null, and columnUpdated_ is checked there.
1419:            private boolean wasNonNullSensitiveUpdate(int column) {
1420:                return updatedColumns_ != null
1421:                        && updatedColumns_[column - 1] != null;
1422:            }
1423:
1424:            // if updatedColumns_ entry is null, but columnUpdated_ entry
1425:            // indicates column has been updated, then column is updated to null.
1426:            private boolean wasNullSensitiveUpdate(int column) {
1427:                return updatedColumns_ != null
1428:                        && updatedColumns_[column - 1] == null
1429:                        && columnUpdated_[column - 1];
1430:            }
1431:
1432:            private void setWasNull(int column) {
1433:                if (wasNullSensitiveUpdate(column)
1434:                        || (isOnInsertRow_ && updatedColumns_[column - 1] == null)) {
1435:                    wasNull_ = WAS_NULL;
1436:                } else {
1437:                    wasNull_ = (cursor_.isNull_ == null || cursor_.isNull_[column - 1]) ? WAS_NULL
1438:                            : WAS_NOT_NULL;
1439:                }
1440:            }
1441:
1442:            private boolean isNull(int column) {
1443:                if (wasNullSensitiveUpdate(column)) {
1444:                    return true;
1445:                } else {
1446:                    return (cursor_.isUpdateDeleteHole_ == true || cursor_.isNull_[column - 1]);
1447:                }
1448:            }
1449:
1450:            // ------------- Methods for accessing results by column name ----------------
1451:
1452:            public final boolean getBoolean(String columnName)
1453:                    throws SQLException {
1454:                try {
1455:                    if (agent_.loggingEnabled()) {
1456:                        agent_.logWriter_.traceEntry(this , "getBoolean",
1457:                                columnName);
1458:                    }
1459:                    return getBoolean(findColumnX(columnName));
1460:                } catch (SqlException se) {
1461:                    throw se.getSQLException();
1462:                }
1463:            }
1464:
1465:            public final byte getByte(String columnName) throws SQLException {
1466:                try {
1467:                    if (agent_.loggingEnabled()) {
1468:                        agent_.logWriter_.traceEntry(this , "getByte",
1469:                                columnName);
1470:                    }
1471:                    return getByte(findColumnX(columnName));
1472:                } catch (SqlException se) {
1473:                    throw se.getSQLException();
1474:                }
1475:            }
1476:
1477:            public final short getShort(String columnName) throws SQLException {
1478:                try {
1479:                    if (agent_.loggingEnabled()) {
1480:                        agent_.logWriter_.traceEntry(this , "getShort",
1481:                                columnName);
1482:                    }
1483:                    return getShort(findColumnX(columnName));
1484:                } catch (SqlException se) {
1485:                    throw se.getSQLException();
1486:                }
1487:            }
1488:
1489:            public final int getInt(String columnName) throws SQLException {
1490:                try {
1491:                    if (agent_.loggingEnabled()) {
1492:                        agent_.logWriter_
1493:                                .traceEntry(this , "getInt", columnName);
1494:                    }
1495:                    return getInt(findColumnX(columnName));
1496:                } catch (SqlException se) {
1497:                    throw se.getSQLException();
1498:                }
1499:            }
1500:
1501:            public final long getLong(String columnName) throws SQLException {
1502:                try {
1503:                    if (agent_.loggingEnabled()) {
1504:                        agent_.logWriter_.traceEntry(this , "getLong",
1505:                                columnName);
1506:                    }
1507:                    return getLong(findColumnX(columnName));
1508:                } catch (SqlException se) {
1509:                    throw se.getSQLException();
1510:                }
1511:            }
1512:
1513:            public final float getFloat(String columnName) throws SQLException {
1514:                try {
1515:                    if (agent_.loggingEnabled()) {
1516:                        agent_.logWriter_.traceEntry(this , "getFloat",
1517:                                columnName);
1518:                    }
1519:                    return getFloat(findColumnX(columnName));
1520:                } catch (SqlException se) {
1521:                    throw se.getSQLException();
1522:                }
1523:            }
1524:
1525:            public final double getDouble(String columnName)
1526:                    throws SQLException {
1527:                try {
1528:                    if (agent_.loggingEnabled()) {
1529:                        agent_.logWriter_.traceEntry(this , "getDouble",
1530:                                columnName);
1531:                    }
1532:                    return getDouble(findColumnX(columnName));
1533:                } catch (SqlException se) {
1534:                    throw se.getSQLException();
1535:                }
1536:            }
1537:
1538:            public final java.math.BigDecimal getBigDecimal(String columnName,
1539:                    int scale) throws SQLException {
1540:                try {
1541:                    if (agent_.loggingEnabled()) {
1542:                        agent_.logWriter_.traceDeprecatedEntry(this ,
1543:                                "getBigDecimal", columnName, scale);
1544:                    }
1545:                    return getBigDecimal(findColumnX(columnName), scale);
1546:                } catch (SqlException se) {
1547:                    throw se.getSQLException();
1548:                }
1549:            }
1550:
1551:            public final java.math.BigDecimal getBigDecimal(String columnName)
1552:                    throws SQLException {
1553:                try {
1554:                    if (agent_.loggingEnabled()) {
1555:                        agent_.logWriter_.traceEntry(this , "getBigDecimal",
1556:                                columnName);
1557:                    }
1558:                    return getBigDecimal(findColumnX(columnName));
1559:                } catch (SqlException se) {
1560:                    throw se.getSQLException();
1561:                }
1562:            }
1563:
1564:            public final java.sql.Date getDate(String columnName)
1565:                    throws SQLException {
1566:                try {
1567:                    if (agent_.loggingEnabled()) {
1568:                        agent_.logWriter_.traceEntry(this , "getDate",
1569:                                columnName);
1570:                    }
1571:                    return getDate(findColumnX(columnName));
1572:                } catch (SqlException se) {
1573:                    throw se.getSQLException();
1574:                }
1575:            }
1576:
1577:            public final java.sql.Date getDate(String columnName,
1578:                    java.util.Calendar cal) throws SQLException {
1579:                try {
1580:                    if (agent_.loggingEnabled()) {
1581:                        agent_.logWriter_.traceEntry(this , "getDate",
1582:                                columnName, cal);
1583:                    }
1584:                    return getDate(findColumnX(columnName), cal);
1585:                } catch (SqlException se) {
1586:                    throw se.getSQLException();
1587:                }
1588:            }
1589:
1590:            public final java.sql.Time getTime(String columnName)
1591:                    throws SQLException {
1592:                try {
1593:                    if (agent_.loggingEnabled()) {
1594:                        agent_.logWriter_.traceEntry(this , "getTime",
1595:                                columnName);
1596:                    }
1597:                    return getTime(findColumnX(columnName));
1598:                } catch (SqlException se) {
1599:                    throw se.getSQLException();
1600:                }
1601:            }
1602:
1603:            public final java.sql.Time getTime(String columnName,
1604:                    java.util.Calendar cal) throws SQLException {
1605:                try {
1606:                    if (agent_.loggingEnabled()) {
1607:                        agent_.logWriter_.traceEntry(this , "getTime",
1608:                                columnName, cal);
1609:                    }
1610:                    return getTime(findColumnX(columnName), cal);
1611:                } catch (SqlException se) {
1612:                    throw se.getSQLException();
1613:                }
1614:            }
1615:
1616:            public final java.sql.Timestamp getTimestamp(String columnName)
1617:                    throws SQLException {
1618:                try {
1619:                    if (agent_.loggingEnabled()) {
1620:                        agent_.logWriter_.traceEntry(this , "getTimestamp",
1621:                                columnName);
1622:                    }
1623:                    return getTimestamp(findColumnX(columnName));
1624:                } catch (SqlException se) {
1625:                    throw se.getSQLException();
1626:                }
1627:            }
1628:
1629:            public final java.sql.Timestamp getTimestamp(String columnName,
1630:                    java.util.Calendar cal) throws SQLException {
1631:                try {
1632:                    if (agent_.loggingEnabled()) {
1633:                        agent_.logWriter_.traceEntry(this , "getTimestamp",
1634:                                columnName, cal);
1635:                    }
1636:                    return getTimestamp(findColumnX(columnName), cal);
1637:                } catch (SqlException se) {
1638:                    throw se.getSQLException();
1639:                }
1640:            }
1641:
1642:            public final String getString(String columnName)
1643:                    throws SQLException {
1644:                try {
1645:                    if (agent_.loggingEnabled()) {
1646:                        agent_.logWriter_.traceEntry(this , "getString",
1647:                                columnName);
1648:                    }
1649:                    return getString(findColumnX(columnName));
1650:                } catch (SqlException se) {
1651:                    throw se.getSQLException();
1652:                }
1653:            }
1654:
1655:            public final byte[] getBytes(String columnName) throws SQLException {
1656:                try {
1657:                    if (agent_.loggingEnabled()) {
1658:                        agent_.logWriter_.traceEntry(this , "getBytes",
1659:                                columnName);
1660:                    }
1661:                    return getBytes(findColumnX(columnName));
1662:                } catch (SqlException se) {
1663:                    throw se.getSQLException();
1664:                }
1665:            }
1666:
1667:            public final java.io.InputStream getBinaryStream(String columnName)
1668:                    throws SQLException {
1669:                try {
1670:                    if (agent_.loggingEnabled()) {
1671:                        agent_.logWriter_.traceEntry(this , "getBinaryStream",
1672:                                columnName);
1673:                    }
1674:                    return getBinaryStream(findColumnX(columnName));
1675:                } catch (SqlException se) {
1676:                    throw se.getSQLException();
1677:                }
1678:            }
1679:
1680:            public final java.io.InputStream getAsciiStream(String columnName)
1681:                    throws SQLException {
1682:                try {
1683:                    if (agent_.loggingEnabled()) {
1684:                        agent_.logWriter_.traceEntry(this , "getAsciiStream",
1685:                                columnName);
1686:                    }
1687:                    return getAsciiStream(findColumnX(columnName));
1688:                } catch (SqlException se) {
1689:                    throw se.getSQLException();
1690:                }
1691:            }
1692:
1693:            public final java.io.InputStream getUnicodeStream(String columnName)
1694:                    throws SQLException {
1695:                try {
1696:                    if (agent_.loggingEnabled()) {
1697:                        agent_.logWriter_.traceDeprecatedEntry(this ,
1698:                                "getUnicodeStream", columnName);
1699:                    }
1700:                    return getUnicodeStream(findColumnX(columnName));
1701:                } catch (SqlException se) {
1702:                    throw se.getSQLException();
1703:                }
1704:            }
1705:
1706:            public final java.io.Reader getCharacterStream(String columnName)
1707:                    throws SQLException {
1708:                try {
1709:                    if (agent_.loggingEnabled()) {
1710:                        agent_.logWriter_.traceEntry(this ,
1711:                                "getCharacterStream", columnName);
1712:                    }
1713:                    return getCharacterStream(findColumnX(columnName));
1714:                } catch (SqlException se) {
1715:                    throw se.getSQLException();
1716:                }
1717:            }
1718:
1719:            public final java.sql.Blob getBlob(String columnName)
1720:                    throws SQLException {
1721:                try {
1722:                    if (agent_.loggingEnabled()) {
1723:                        agent_.logWriter_.traceEntry(this , "getBlob",
1724:                                columnName);
1725:                    }
1726:                    return getBlob(findColumnX(columnName));
1727:                } catch (SqlException se) {
1728:                    throw se.getSQLException();
1729:                }
1730:            }
1731:
1732:            public final java.sql.Clob getClob(String columnName)
1733:                    throws SQLException {
1734:                try {
1735:                    if (agent_.loggingEnabled()) {
1736:                        agent_.logWriter_.traceEntry(this , "getClob",
1737:                                columnName);
1738:                    }
1739:                    return getClob(findColumnX(columnName));
1740:                } catch (SqlException se) {
1741:                    throw se.getSQLException();
1742:                }
1743:            }
1744:
1745:            public final java.sql.Array getArray(String columnName)
1746:                    throws SQLException {
1747:                try {
1748:                    if (agent_.loggingEnabled()) {
1749:                        agent_.logWriter_.traceEntry(this , "getArray",
1750:                                columnName);
1751:                    }
1752:                    return getArray(findColumnX(columnName));
1753:                } catch (SqlException se) {
1754:                    throw se.getSQLException();
1755:                }
1756:            }
1757:
1758:            public final java.sql.Ref getRef(String columnName)
1759:                    throws SQLException {
1760:                try {
1761:                    if (agent_.loggingEnabled()) {
1762:                        agent_.logWriter_
1763:                                .traceEntry(this , "getRef", columnName);
1764:                    }
1765:                    return getRef(findColumnX(columnName));
1766:                } catch (SqlException se) {
1767:                    throw se.getSQLException();
1768:                }
1769:            }
1770:
1771:            public final Object getObject(String columnName)
1772:                    throws SQLException {
1773:                try {
1774:                    if (agent_.loggingEnabled()) {
1775:                        agent_.logWriter_.traceEntry(this , "getObject",
1776:                                columnName);
1777:                    }
1778:                    return getObject(findColumnX(columnName));
1779:                } catch (SqlException se) {
1780:                    throw se.getSQLException();
1781:                }
1782:            }
1783:
1784:            public final Object getObject(String columnName, java.util.Map map)
1785:                    throws SQLException {
1786:                try {
1787:                    if (agent_.loggingEnabled()) {
1788:                        agent_.logWriter_.traceEntry(this , "getObject",
1789:                                columnName, map);
1790:                    }
1791:                    return getObject(findColumnX(columnName), map);
1792:                } catch (SqlException se) {
1793:                    throw se.getSQLException();
1794:                }
1795:            }
1796:
1797:            // ----------------Advanced features -----------------------------------------
1798:
1799:            /**
1800:             * Returns the first <code>SQLWarning</code> reported on this
1801:             * <code>ResultSet</code> object, or <code>null</code> if there
1802:             * are no warnings. Subsequent warnings are chained on the
1803:             * returned object.
1804:             *
1805:             * @return the first <code>SQLWarning</code> in the chain, or
1806:             * <code>null</code> if no warnings are reported
1807:             * @exception SQLException if a database error occurs or the
1808:             * result set is closed
1809:             */
1810:            public final java.sql.SQLWarning getWarnings() throws SQLException {
1811:                try {
1812:                    checkForClosedResultSet();
1813:                } catch (SqlException se) {
1814:                    throw se.getSQLException();
1815:                }
1816:                if (agent_.loggingEnabled()) {
1817:                    agent_.logWriter_.traceExit(this , "getWarnings", warnings_);
1818:                }
1819:                return warnings_ == null ? null : warnings_.getSQLWarning();
1820:            }
1821:
1822:            /**
1823:             * Clear all warnings on this <code>ResultSet</code> and make
1824:             * subsequent calls to <code>getWarnings()</code> return
1825:             * <code>null</code> until a new warning is reported.
1826:             *
1827:             * @exception SQLException if a database error occurs or the
1828:             * result set is closed
1829:             */
1830:            public final void clearWarnings() throws SQLException {
1831:                synchronized (connection_) {
1832:                    if (agent_.loggingEnabled()) {
1833:                        agent_.logWriter_.traceEntry(this , "clearWarnings");
1834:                    }
1835:                    try {
1836:                        checkForClosedResultSet();
1837:                    } catch (SqlException se) {
1838:                        throw se.getSQLException();
1839:                    }
1840:                    clearWarningsX();
1841:                }
1842:            }
1843:
1844:            // An untraced version of clearWarnings()
1845:            public final void clearWarningsX() {
1846:                warnings_ = null;
1847:            }
1848:
1849:            public String getCursorName() throws SQLException {
1850:                try {
1851:                    synchronized (connection_) {
1852:                        if (agent_.loggingEnabled()) {
1853:                            agent_.logWriter_.traceEntry(this , "getCursorName");
1854:                        }
1855:                        checkForClosedResultSet();
1856:                        if (generatedSection_ != null) {
1857:                            return "stored procedure generated cursor:"
1858:                                    + generatedSection_.getServerCursorName();
1859:                        }
1860:                        if (statement_.cursorName_ == null) {// cursor name is not assigned yet
1861:                            statement_.cursorName_ = statement_.section_
1862:                                    .getServerCursorName();
1863:                        }
1864:                        if (agent_.loggingEnabled()) {
1865:                            agent_.logWriter_.traceExit(this , "getCursorName",
1866:                                    statement_.cursorName_);
1867:                        }
1868:                        return statement_.cursorName_;
1869:                    }
1870:                } catch (SqlException se) {
1871:                    throw se.getSQLException();
1872:                }
1873:            }
1874:
1875:            public java.sql.ResultSetMetaData getMetaData() throws SQLException {
1876:                try {
1877:                    if (agent_.loggingEnabled()) {
1878:                        agent_.logWriter_.traceEntry(this , "getMetaData");
1879:                    }
1880:                    java.sql.ResultSetMetaData resultSetMetaData = getMetaDataX();
1881:                    if (agent_.loggingEnabled()) {
1882:                        agent_.logWriter_.traceExit(this , "getMetaData",
1883:                                resultSetMetaData);
1884:                    }
1885:                    return resultSetMetaData;
1886:                } catch (SqlException se) {
1887:                    throw se.getSQLException();
1888:                }
1889:            }
1890:
1891:            // used by DBMD
1892:            ColumnMetaData getMetaDataX() throws SqlException {
1893:                checkForClosedResultSet();
1894:                return resultSetMetaData_;
1895:            }
1896:
1897:            public final int findColumn(String columnName) throws SQLException {
1898:                try {
1899:                    synchronized (connection_) {
1900:                        if (agent_.loggingEnabled()) {
1901:                            agent_.logWriter_.traceEntry(this , "findColumn",
1902:                                    columnName);
1903:                        }
1904:                        int column = findColumnX(columnName);
1905:                        if (agent_.loggingEnabled()) {
1906:                            agent_.logWriter_.traceExit(this , "findColumn",
1907:                                    column);
1908:                        }
1909:                        return column;
1910:                    }
1911:                } catch (SqlException se) {
1912:                    throw se.getSQLException();
1913:                }
1914:            }
1915:
1916:            // An untraced version of findColumn()
1917:            private final int findColumnX(String columnName)
1918:                    throws SqlException {
1919:                checkForClosedResultSet();
1920:                return resultSetMetaData_.findColumnX(columnName);
1921:            }
1922:
1923:            //-------------------------- Traversal/Positioning ---------------------------
1924:
1925:            public boolean isBeforeFirst() throws SQLException {
1926:                try {
1927:                    if (agent_.loggingEnabled()) {
1928:                        agent_.logWriter_.traceEntry(this , "isBeforeFirst");
1929:                    }
1930:                    checkForClosedResultSet();
1931:                    checkThatResultSetTypeIsScrollable();
1932:                    // Returns false if the ResultSet contains no rows.
1933:                    boolean isBeforeFirst = isBeforeFirstX();
1934:                    if (agent_.loggingEnabled()) {
1935:                        agent_.logWriter_.traceExit(this , "isBeforeFirst",
1936:                                isBeforeFirst);
1937:                    }
1938:                    return isBeforeFirst;
1939:                } catch (SqlException se) {
1940:                    throw se.getSQLException();
1941:                }
1942:            }
1943:
1944:            private boolean isBeforeFirstX() throws SqlException {
1945:                if (sensitivity_ == sensitivity_sensitive_dynamic__) {
1946:                    return isBeforeFirst_;
1947:                } else
1948:                //return ((resultSetContainsNoRows()) ? false : (currentRowInRowset_ == -1));
1949:                {
1950:                    return ((currentRowInRowset_ == -1) && !resultSetContainsNoRows());
1951:                }
1952:            }
1953:
1954:            public boolean isAfterLast() throws SQLException {
1955:                try {
1956:                    if (agent_.loggingEnabled()) {
1957:                        agent_.logWriter_.traceEntry(this , "isAfterLast");
1958:                    }
1959:                    checkForClosedResultSet();
1960:                    checkThatResultSetTypeIsScrollable();
1961:                    // Returns false if the ResultSet contains no rows.
1962:                    boolean isAfterLast = isAfterLastX();
1963:                    if (agent_.loggingEnabled()) {
1964:                        agent_.logWriter_.traceExit(this , "isAfterLast",
1965:                                isAfterLast);
1966:                    }
1967:                    return isAfterLast;
1968:                } catch (SqlException se) {
1969:                    throw se.getSQLException();
1970:                }
1971:            }
1972:
1973:            private boolean isAfterLastX() throws SqlException {
1974:                if (sensitivity_ == sensitivity_sensitive_dynamic__) {
1975:                    return isAfterLast_;
1976:                } else {
1977:                    return (resultSetContainsNoRows() ? false
1978:                            : (firstRowInRowset_ == currentRowInRowset_
1979:                                    && currentRowInRowset_ == lastRowInRowset_
1980:                                    && lastRowInRowset_ == 0 && absolutePosition_ == (maxRows_ == 0 ? rowCount_ + 1
1981:                                    : maxRows_ + 1)));
1982:                }
1983:            }
1984:
1985:            public boolean isFirst() throws SQLException {
1986:                try {
1987:                    if (agent_.loggingEnabled()) {
1988:                        agent_.logWriter_.traceEntry(this , "isFirst");
1989:                    }
1990:                    checkForClosedResultSet();
1991:                    checkThatResultSetTypeIsScrollable();
1992:                    // Not necessary to get the rowCount_ since currentRowInRowset_ is initialized to -1,
1993:                    // and it will not be changed if there is no rows in the ResultSet.
1994:                    boolean isFirst = isFirstX();
1995:                    if (agent_.loggingEnabled()) {
1996:                        agent_.logWriter_.traceExit(this , "isFirst", isFirst);
1997:                    }
1998:                    return isFirst;
1999:                } catch (SqlException se) {
2000:                    throw se.getSQLException();
2001:                }
2002:            }
2003:
2004:            private boolean isFirstX() {
2005:                if (sensitivity_ == sensitivity_sensitive_dynamic__) {
2006:                    return isFirst_;
2007:                }
2008:                return (firstRowInRowset_ == 1 && currentRowInRowset_ == 0);
2009:            }
2010:
2011:            public boolean isLast() throws SQLException {
2012:                try {
2013:                    if (agent_.loggingEnabled()) {
2014:                        agent_.logWriter_.traceEntry(this , "isLast");
2015:                    }
2016:                    checkForClosedResultSet();
2017:                    checkThatResultSetTypeIsScrollable();
2018:                    // Returns false if the ResultSet contains no rows.
2019:                    boolean isLast = isLastX();
2020:                    if (agent_.loggingEnabled()) {
2021:                        agent_.logWriter_.traceExit(this , "isLast", isLast);
2022:                    }
2023:                    return isLast;
2024:                } catch (SqlException se) {
2025:                    throw se.getSQLException();
2026:                }
2027:            }
2028:
2029:            private boolean isLastX() throws SqlException {
2030:                if (sensitivity_ == sensitivity_sensitive_dynamic__) {
2031:                    return isLast_;
2032:                } else {
2033:                    return (resultSetContainsNoRows() ? false
2034:                            : (firstRowInRowset_ + currentRowInRowset_) == rowCount_);
2035:                }
2036:            }
2037:
2038:            public void beforeFirst() throws SQLException {
2039:                try {
2040:                    synchronized (connection_) {
2041:                        if (agent_.loggingEnabled()) {
2042:                            agent_.logWriter_.traceEntry(this , "beforeFirst");
2043:                        }
2044:                        checkForClosedResultSet();
2045:                        checkThatResultSetTypeIsScrollable();
2046:                        clearWarningsX();
2047:                        beforeFirstX();
2048:                    }
2049:                } catch (SqlException se) {
2050:                    throw se.getSQLException();
2051:                }
2052:            }
2053:
2054:            private void beforeFirstX() throws SqlException {
2055:
2056:                resetRowsetFlags();
2057:                unuseStreams();
2058:
2059:                moveToCurrentRowX();
2060:
2061:                // this method has no effect if the result set has no rows.
2062:                // only send cntqry to position the cursor before first if
2063:                // resultset contains rows and it is not already before first, or
2064:                // if the cursor is a dynamic cursor.
2065:                if (sensitivity_ == sensitivity_sensitive_dynamic__
2066:                        || (!resultSetContainsNoRows() && !isServersCursorPositionBeforeFirst())) {
2067:                    moveToBeforeFirst();
2068:                }
2069:                isBeforeFirst_ = true;
2070:                setRowsetBeforeFirstEvent();
2071:                cursor_.resetDataBuffer();
2072:                resetRowsetSqlca();
2073:                isValidCursorPosition_ = false;
2074:            }
2075:
2076:            public void afterLast() throws SQLException {
2077:                try {
2078:                    synchronized (connection_) {
2079:                        if (agent_.loggingEnabled()) {
2080:                            agent_.logWriter_.traceEntry(this , "afterLast");
2081:                        }
2082:                        checkForClosedResultSet();
2083:                        checkThatResultSetTypeIsScrollable();
2084:                        clearWarningsX();
2085:                        afterLastX();
2086:                    }
2087:                } catch (SqlException se) {
2088:                    throw se.getSQLException();
2089:                }
2090:            }
2091:
2092:            private void afterLastX() throws SqlException {
2093:                resetRowsetFlags();
2094:                unuseStreams();
2095:
2096:                moveToCurrentRowX();
2097:
2098:                // this method has no effect if the result set has no rows.
2099:                // only send cntqry to position the cursor after last if
2100:                // resultset contains rows and it is not already after last, or
2101:                // if the cursor is a dynamic cursor.
2102:                if (sensitivity_ == sensitivity_sensitive_dynamic__
2103:                        || (!resultSetContainsNoRows() && !isServerCursorPositionAfterLast())) {
2104:                    moveToAfterLast();
2105:                }
2106:                isAfterLast_ = true;
2107:                setRowsetAfterLastEvent();
2108:                cursor_.resetDataBuffer();
2109:                resetRowsetSqlca();
2110:                isValidCursorPosition_ = false;
2111:            }
2112:
2113:            public boolean first() throws SQLException {
2114:                try {
2115:                    synchronized (connection_) {
2116:                        if (agent_.loggingEnabled()) {
2117:                            agent_.logWriter_.traceEntry(this , "first");
2118:                        }
2119:                        boolean isValidCursorPosition = firstX();
2120:                        if (agent_.loggingEnabled()) {
2121:                            agent_.logWriter_.traceExit(this , "first",
2122:                                    isValidCursorPosition);
2123:                        }
2124:                        return isValidCursorPosition;
2125:                    }
2126:                } catch (SqlException se) {
2127:                    throw se.getSQLException();
2128:                }
2129:            }
2130:
2131:            private boolean firstX() throws SqlException {
2132:                checkForClosedResultSet();
2133:                checkThatResultSetTypeIsScrollable();
2134:                clearWarningsX();
2135:
2136:                moveToCurrentRowX();
2137:
2138:                wasNull_ = ResultSet.WAS_NULL_UNSET;
2139:
2140:                // discard all previous updates when moving the cursor
2141:                resetUpdatedColumns();
2142:
2143:                resetRowsetFlags();
2144:                unuseStreams();
2145:
2146:                // if first row is not in the current rowset, fetch the first rowset from the server.
2147:                // rowIsInCurrentRowset with orientation first will always return false for dynamic cursors.
2148:                if (rowIsInCurrentRowset(1, scrollOrientation_first__)) {
2149:                    isValidCursorPosition_ = true;
2150:                    currentRowInRowset_ = 0;
2151:                } else {
2152:                    checkAndThrowReceivedQueryTerminatingException();
2153:                    isValidCursorPosition_ = getFirstRowset();
2154:                }
2155:
2156:                if (isValidCursorPosition_) {
2157:                    updateColumnInfoFromCache();
2158:                    isFirst_ = true;
2159:                    // check if there is a non-null SQLCA for the row for rowset cursors
2160:                    checkRowsetSqlca();
2161:                }
2162:
2163:                return isValidCursorPosition_;
2164:            }
2165:
2166:            public boolean last() throws SQLException {
2167:                try {
2168:                    synchronized (connection_) {
2169:                        if (agent_.loggingEnabled()) {
2170:                            agent_.logWriter_.traceEntry(this , "last");
2171:                        }
2172:                        boolean isValidCursorPosition = lastX();
2173:                        if (agent_.loggingEnabled()) {
2174:                            agent_.logWriter_.traceExit(this , "last",
2175:                                    isValidCursorPosition);
2176:                        }
2177:                        return isValidCursorPosition;
2178:                    }
2179:                } catch (SqlException se) {
2180:                    throw se.getSQLException();
2181:                }
2182:            }
2183:
2184:            private boolean lastX() throws SqlException {
2185:                checkForClosedResultSet();
2186:                checkThatResultSetTypeIsScrollable();
2187:                clearWarningsX();
2188:
2189:                moveToCurrentRowX();
2190:
2191:                wasNull_ = ResultSet.WAS_NULL_UNSET;
2192:
2193:                // discard all previous updates when moving the cursor
2194:                resetUpdatedColumns();
2195:
2196:                resetRowsetFlags();
2197:                unuseStreams();
2198:
2199:                // only get the rowCount for static cursors.
2200:                if (rowCountIsUnknown()) {
2201:                    getRowCount();
2202:                }
2203:                long row = rowCount_;
2204:                if (sensitivity_ != sensitivity_sensitive_dynamic__
2205:                        && maxRows_ > 0) {
2206:                    if (rowCount_ > maxRows_) {
2207:                        row = maxRows_;
2208:                    }
2209:                }
2210:
2211:                // rowIsInCurrentRowset with orientation last will always return false for dynamic cursors.
2212:                if (rowIsInCurrentRowset(row, scrollOrientation_last__)) {
2213:                    isValidCursorPosition_ = true;
2214:                    currentRowInRowset_ = row - firstRowInRowset_;
2215:                } else {
2216:                    checkAndThrowReceivedQueryTerminatingException();
2217:                    isValidCursorPosition_ = getLastRowset(row);
2218:                }
2219:
2220:                if (isValidCursorPosition_) {
2221:                    updateColumnInfoFromCache();
2222:                    isLast_ = true;
2223:                    // check if there is a non-null SQLCA for the current row for rowset cursors
2224:                    checkRowsetSqlca();
2225:                }
2226:
2227:                return isValidCursorPosition_;
2228:            }
2229:
2230:            public int getRow() throws SQLException {
2231:                try {
2232:                    synchronized (connection_) {
2233:                        if (agent_.loggingEnabled()) {
2234:                            agent_.logWriter_.traceEntry(this , "getRow");
2235:                        }
2236:                        int row = getRowX();
2237:                        if (agent_.loggingEnabled()) {
2238:                            agent_.logWriter_.traceExit(this , "getRow", row);
2239:                        }
2240:                        return row;
2241:                    }
2242:                } catch (SqlException se) {
2243:                    throw se.getSQLException();
2244:                }
2245:            }
2246:
2247:            private int getRowX() throws SqlException {
2248:                checkForClosedResultSet();
2249:                long row;
2250:                checkThatResultSetIsNotDynamic();
2251:                if (resultSetType_ == java.sql.ResultSet.TYPE_FORWARD_ONLY)
2252:                // for forward-only cursors, getRow() should return 0 if cursor is not on a valid row,
2253:                // i.e. afterlast.
2254:                {
2255:                    row = (cursor_.allRowsReceivedFromServer() && cursor_
2256:                            .currentRowPositionIsEqualToNextRowPosition()) ? 0
2257:                            : cursor_.rowsRead_;
2258:                } else {
2259:                    if (rowCountIsUnknown()) {
2260:                        // commented out here because the following method is called the first thing
2261:                        // inside getRowCount();
2262:                        //checkAndThrowReceivedQueryTerminatingException();
2263:                        getRowCount();
2264:                    }
2265:                    if (rowCount_ == 0 || currentRowInRowset_ < 0) // || currentRowInRowset_ > rowCount_)
2266:                    {
2267:                        row = 0;
2268:                    } else {
2269:                        row = firstRowInRowset_ + currentRowInRowset_;
2270:                    }
2271:                }
2272:                if (row > Integer.MAX_VALUE) {
2273:                    this .accumulateWarning(new SqlWarning(agent_.logWriter_,
2274:                            new ClientMessageId(
2275:                                    SQLState.NUMBER_OF_ROWS_TOO_LARGE_FOR_INT),
2276:                            new Long(row)));
2277:                }
2278:                return (int) row;
2279:            }
2280:
2281:            public boolean absolute(int row) throws SQLException {
2282:                try {
2283:                    synchronized (connection_) {
2284:                        if (agent_.loggingEnabled()) {
2285:                            agent_.logWriter_.traceEntry(this , "absolute", row);
2286:                        }
2287:                        boolean isValidCursorPosition = absoluteX(row);
2288:                        if (agent_.loggingEnabled()) {
2289:                            agent_.logWriter_.traceExit(this , "absolute",
2290:                                    isValidCursorPosition);
2291:                        }
2292:                        return isValidCursorPosition;
2293:                    }
2294:                } catch (SqlException se) {
2295:                    throw se.getSQLException();
2296:                }
2297:            }
2298:
2299:            public boolean absoluteX(int row) throws SqlException {
2300:                checkForClosedResultSet();
2301:                checkThatResultSetTypeIsScrollable();
2302:                clearWarningsX();
2303:
2304:                moveToCurrentRowX();
2305:
2306:                wasNull_ = ResultSet.WAS_NULL_UNSET;
2307:
2308:                // discard all previous updates when moving the cursor.
2309:                resetUpdatedColumns();
2310:
2311:                resetRowsetFlags();
2312:                unuseStreams();
2313:
2314:                if (maxRows_ > 0) {
2315:                    // if "row" is positive and > maxRows, fetch afterLast
2316:                    // else if "row" is negative, and abs(row) > maxRows, fetch beforeFirst
2317:                    if (row > 0 && row > maxRows_) {
2318:                        afterLastX();
2319:                        isValidCursorPosition_ = false;
2320:                        return isValidCursorPosition_;
2321:                    } else if (row <= 0 && java.lang.Math.abs(row) > maxRows_) {
2322:                        beforeFirstX();
2323:                        isValidCursorPosition_ = false;
2324:                        return isValidCursorPosition_;
2325:                    }
2326:                }
2327:
2328:                int fetchAbsoluteRow = 0;
2329:                if (rowCountIsUnknown()) {
2330:                    getRowCount();
2331:                }
2332:                if (sensitivity_ == sensitivity_sensitive_dynamic__) {
2333:                    fetchAbsoluteRow = row;
2334:                } else
2335:                // calculate the positive absolute row number based on rowCount for static or insensitive cursors.
2336:                {
2337:                    fetchAbsoluteRow = (row >= 0) ? row : (int) (rowCount_
2338:                            + row + 1);
2339:                }
2340:
2341:                // rowIsInCurrentRowset with orientation absolute will always return false for dynamic cursors.
2342:                if (rowIsInCurrentRowset(fetchAbsoluteRow,
2343:                        scrollOrientation_absolute__)) {
2344:                    isValidCursorPosition_ = true;
2345:                    currentRowInRowset_ = fetchAbsoluteRow - firstRowInRowset_;
2346:                } else {
2347:                    checkAndThrowReceivedQueryTerminatingException();
2348:                    isValidCursorPosition_ = getAbsoluteRowset(fetchAbsoluteRow);
2349:                }
2350:
2351:                if (isValidCursorPosition_) {
2352:                    updateColumnInfoFromCache();
2353:                    if (row == 1) {
2354:                        isFirst_ = true;
2355:                    }
2356:                    if (row == -1) {
2357:                        isLast_ = true;
2358:                    }
2359:                    // check if there is a non-null SQLCA for the row for rowset cursors
2360:                    checkRowsetSqlca();
2361:                }
2362:
2363:                return isValidCursorPosition_;
2364:            }
2365:
2366:            public boolean relative(int rows) throws SQLException {
2367:                try {
2368:                    synchronized (connection_) {
2369:                        if (agent_.loggingEnabled()) {
2370:                            agent_.logWriter_
2371:                                    .traceEntry(this , "relative", rows);
2372:                        }
2373:                        boolean isValidCursorPosition = relativeX(rows);
2374:                        if (agent_.loggingEnabled()) {
2375:                            agent_.logWriter_.traceExit(this , "relative",
2376:                                    isValidCursorPosition);
2377:                        }
2378:                        return isValidCursorPosition;
2379:                    }
2380:                } catch (SqlException se) {
2381:                    throw se.getSQLException();
2382:                }
2383:            }
2384:
2385:            private boolean relativeX(int rows) throws SqlException {
2386:                checkForClosedResultSet();
2387:                checkThatResultSetTypeIsScrollable();
2388:                clearWarningsX();
2389:
2390:                moveToCurrentRowX();
2391:
2392:                wasNull_ = ResultSet.WAS_NULL_UNSET;
2393:
2394:                // discard all previous updates when moving the cursor.
2395:                resetUpdatedColumns();
2396:
2397:                unuseStreams();
2398:
2399:                // If the resultset is empty, relative(n) is a null operation
2400:                if (resultSetContainsNoRows()) {
2401:                    isValidCursorPosition_ = false;
2402:                    return isValidCursorPosition_;
2403:                }
2404:
2405:                // relative(0) is a null-operation, but the retruned result is
2406:                // dependent on wether the cursorposition is on a row or not.
2407:                // Scroll insensitive updatable should see own changes, so relative(0)
2408:                // has to refetch the row.
2409:                if (rows == 0) {
2410:                    if (resultSetConcurrency_ == ResultSet.CONCUR_UPDATABLE
2411:                            && resultSetType_ == ResultSet.TYPE_SCROLL_INSENSITIVE) {
2412:                        // re-fetch currentRow
2413:                        isValidCursorPosition_ = getAbsoluteRowset(absolutePosition_);
2414:                    } else {
2415:                        if (isBeforeFirstX() || isAfterLastX()) {
2416:                            isValidCursorPosition_ = false;
2417:                        } else {
2418:                            isValidCursorPosition_ = true;
2419:                        }
2420:                    }
2421:                    return isValidCursorPosition_;
2422:                }
2423:
2424:                // Handle special cases when the cursor is before first or
2425:                // after last, since the following code assumes we ar on a
2426:                // valid cursor
2427:                if (isBeforeFirstX()) {
2428:                    if (rows > 0) {
2429:                        nextX();
2430:                        return relativeX(rows - 1);
2431:                    } else {
2432:                        isValidCursorPosition_ = false;
2433:                        return isValidCursorPosition_;
2434:                    }
2435:                }
2436:                if (isAfterLastX()) {
2437:                    if (rows < 0) {
2438:                        previousX();
2439:                        return relativeX(rows + 1);
2440:                    } else {
2441:                        isValidCursorPosition_ = false;
2442:                        return isValidCursorPosition_;
2443:                    }
2444:                }
2445:                // Ok, now we are on a row and ready to do some real positioning.....
2446:
2447:                resetRowsetFlags();
2448:
2449:                // currentAbsoluteRowNumber is used for static cursors only.
2450:                long currentAbsoluteRowNumber = firstRowInRowset_
2451:                        + currentRowInRowset_;
2452:
2453:                // if "rows" is positive, and currentRow+rows > maxRows, fetch afterLast.
2454:                // if "rows" is negative, and if the absolute value of "rows" is greater than
2455:                // the currentrow number, will fetch beforeFirst anyways.  do not need to check
2456:                // for maxRows.
2457:                if (sensitivity_ != sensitivity_sensitive_dynamic__
2458:                        && maxRows_ > 0 && rows > 0
2459:                        && currentAbsoluteRowNumber + rows > maxRows_) {
2460:                    afterLastX();
2461:                    isValidCursorPosition_ = false;
2462:                    return isValidCursorPosition_;
2463:                }
2464:
2465:                if (rowIsInCurrentRowset(currentAbsoluteRowNumber + rows,
2466:                        scrollOrientation_relative__)) {
2467:                    currentRowInRowset_ += rows;
2468:                    isValidCursorPosition_ = true;
2469:                } else {
2470:                    checkAndThrowReceivedQueryTerminatingException();
2471:                    long rowNumber = (sensitivity_ == sensitivity_sensitive_dynamic__) ? currentRowInRowset_
2472:                            + rows
2473:                            : currentAbsoluteRowNumber + rows
2474:                                    - absolutePosition_;
2475:                    if (maxRows_ < Math.abs(rowNumber) && maxRows_ != 0) {
2476:                        if (rowNumber > 0) {
2477:                            afterLastX();
2478:                        } else {
2479:                            beforeFirstX();
2480:                        }
2481:                        isValidCursorPosition_ = false;
2482:                        return isValidCursorPosition_;
2483:                    }
2484:                    isValidCursorPosition_ = getRelativeRowset(rowNumber);
2485:                }
2486:
2487:                if (isValidCursorPosition_) {
2488:                    updateColumnInfoFromCache();
2489:                    // check if there is a non-null SQLCA for the row for rowset cursors
2490:                    checkRowsetSqlca();
2491:                }
2492:
2493:                return isValidCursorPosition_;
2494:            }
2495:
2496:            public boolean previous() throws SQLException {
2497:                try {
2498:                    synchronized (connection_) {
2499:                        if (agent_.loggingEnabled()) {
2500:                            agent_.logWriter_.traceEntry(this , "previous");
2501:                        }
2502:                        boolean isValidCursorPosition = previousX();
2503:                        if (agent_.loggingEnabled()) {
2504:                            agent_.logWriter_.traceExit(this , "previous",
2505:                                    isValidCursorPosition);
2506:                        }
2507:                        return isValidCursorPosition;
2508:                    }
2509:                } catch (SqlException se) {
2510:                    throw se.getSQLException();
2511:                }
2512:            }
2513:
2514:            private boolean previousX() throws SqlException {
2515:                checkForClosedResultSet();
2516:                checkThatResultSetTypeIsScrollable();
2517:                clearWarningsX();
2518:
2519:                moveToCurrentRowX();
2520:
2521:                wasNull_ = ResultSet.WAS_NULL_UNSET;
2522:
2523:                // discard all previous updates when moving the cursor.
2524:                resetUpdatedColumns();
2525:
2526:                unuseStreams();
2527:
2528:                isBeforeFirst_ = false;
2529:                isFirst_ = false;
2530:
2531:                if (rowIsInCurrentRowset(firstRowInRowset_
2532:                        + currentRowInRowset_ - 1, scrollOrientation_prior__)) {
2533:                    isValidCursorPosition_ = true;
2534:                    currentRowInRowset_--;
2535:                } else {
2536:                    checkAndThrowReceivedQueryTerminatingException();
2537:                    isValidCursorPosition_ = getPreviousRowset();
2538:                }
2539:
2540:                if (isValidCursorPosition_) {
2541:                    updateColumnInfoFromCache();
2542:                    // check if there is a non-null SQLCA for the row for rowset cursors
2543:                    checkRowsetSqlca();
2544:                    if (isAfterLast_) {
2545:                        isLast_ = true;
2546:                    }
2547:                    isAfterLast_ = false;
2548:                } else {
2549:                    return isValidCursorPosition_;
2550:                }
2551:
2552:                if (sensitivity_ != sensitivity_sensitive_dynamic__
2553:                        && maxRows_ > 0
2554:                        && (firstRowInRowset_ + currentRowInRowset_ > maxRows_)) {
2555:                    isValidCursorPosition_ = false;
2556:                }
2557:                // auto-close result set if this is the last row from server and return false
2558:                return isValidCursorPosition_;
2559:            }
2560:
2561:            public void setFetchDirection(int direction) throws SQLException {
2562:                try {
2563:                    synchronized (connection_) {
2564:                        if (agent_.loggingEnabled()) {
2565:                            agent_.logWriter_.traceEntry(this ,
2566:                                    "setFetchDirection", direction);
2567:                        }
2568:                        checkForClosedResultSet();
2569:                        checkThatResultSetTypeIsScrollable();
2570:
2571:                        switch (direction) {
2572:                        case java.sql.ResultSet.FETCH_FORWARD:
2573:                        case java.sql.ResultSet.FETCH_REVERSE:
2574:                        case java.sql.ResultSet.FETCH_UNKNOWN:
2575:                            fetchDirection_ = direction;
2576:                            break;
2577:                        default:
2578:                            throw new SqlException(agent_.logWriter_,
2579:                                    new ClientMessageId(
2580:                                            SQLState.INVALID_FETCH_DIRECTION),
2581:                                    new Integer(direction));
2582:                        }
2583:                    }
2584:                } catch (SqlException se) {
2585:                    throw se.getSQLException();
2586:                }
2587:            }
2588:
2589:            public int getFetchDirection() throws SQLException {
2590:                try {
2591:                    checkForClosedResultSet();
2592:                    if (agent_.loggingEnabled()) {
2593:                        agent_.logWriter_.traceExit(this , "getFetchDirection",
2594:                                fetchDirection_);
2595:                    }
2596:                    return fetchDirection_;
2597:                } catch (SqlException se) {
2598:                    throw se.getSQLException();
2599:                }
2600:            }
2601:
2602:            public void setFetchSize(int rows) throws SQLException {
2603:                try {
2604:                    synchronized (connection_) {
2605:                        if (agent_.loggingEnabled()) {
2606:                            agent_.logWriter_.traceEntry(this , "setFetchSize",
2607:                                    rows);
2608:                        }
2609:                        checkForClosedResultSet();
2610:                        if (rows < 0 || (maxRows_ != 0 && rows > maxRows_)) {
2611:                            throw new SqlException(agent_.logWriter_,
2612:                                    new ClientMessageId(
2613:                                            SQLState.INVALID_FETCH_SIZE),
2614:                                    new Integer(rows)).getSQLException();
2615:                        }
2616:                        setFetchSize_(rows);
2617:                    }
2618:                } catch (SqlException se) {
2619:                    throw se.getSQLException();
2620:                }
2621:            }
2622:
2623:            public int getFetchSize() throws SQLException {
2624:                try {
2625:                    if (agent_.loggingEnabled()) {
2626:                        agent_.logWriter_.traceExit(this , "getFetchSize",
2627:                                fetchSize_);
2628:                    }
2629:                    checkForClosedResultSet();
2630:                    return suggestedFetchSize_;
2631:                } catch (SqlException se) {
2632:                    throw se.getSQLException();
2633:                }
2634:            }
2635:
2636:            public int getType() throws SQLException {
2637:                try {
2638:                    if (agent_.loggingEnabled()) {
2639:                        agent_.logWriter_.traceExit(this , "getType",
2640:                                resultSetType_);
2641:                    }
2642:                    checkForClosedResultSet();
2643:                    return resultSetType_;
2644:                } catch (SqlException se) {
2645:                    throw se.getSQLException();
2646:                }
2647:            }
2648:
2649:            public int getConcurrency() throws SQLException {
2650:                try {
2651:                    if (agent_.loggingEnabled()) {
2652:                        agent_.logWriter_.traceExit(this , "getConcurrency",
2653:                                resultSetConcurrency_);
2654:                    }
2655:                    checkForClosedResultSet();
2656:                    return resultSetConcurrency_;
2657:                } catch (SqlException se) {
2658:                    throw se.getSQLException();
2659:                }
2660:            }
2661:
2662:            //----------------------------- Updates --------------------------------------
2663:
2664:            public boolean rowUpdated() throws SQLException {
2665:                try {
2666:                    checkForClosedResultSet();
2667:                    checkPositionedOnPlainRow();
2668:
2669:                    boolean rowUpdated = cursor_.getIsRowUpdated();
2670:
2671:                    if (agent_.loggingEnabled()) {
2672:                        agent_.logWriter_.traceExit(this , "rowUpdated",
2673:                                rowUpdated);
2674:                    }
2675:                    return rowUpdated;
2676:                } catch (SqlException se) {
2677:                    throw se.getSQLException();
2678:                }
2679:            }
2680:
2681:            public boolean rowInserted() throws SQLException {
2682:                try {
2683:                    checkForClosedResultSet();
2684:                    checkPositionedOnPlainRow();
2685:
2686:                    boolean rowInserted = false;
2687:
2688:                    // Not implemented for any result set type,
2689:                    // so it always returns false.
2690:
2691:                    if (agent_.loggingEnabled()) {
2692:                        agent_.logWriter_.traceExit(this , "rowInserted",
2693:                                rowInserted);
2694:                    }
2695:                    return rowInserted;
2696:                } catch (SqlException se) {
2697:                    throw se.getSQLException();
2698:                }
2699:            }
2700:
2701:            public boolean rowDeleted() throws SQLException {
2702:                try {
2703:                    checkForClosedResultSet();
2704:                    checkPositionedOnPlainRow();
2705:
2706:                    boolean rowDeleted = (resultSetType_ == ResultSet.TYPE_SCROLL_INSENSITIVE) ? cursor_
2707:                            .getIsUpdateDeleteHole()
2708:                            : false;
2709:
2710:                    if (agent_.loggingEnabled()) {
2711:                        agent_.logWriter_.traceExit(this , "rowDeleted",
2712:                                rowDeleted);
2713:                    }
2714:                    return rowDeleted;
2715:                } catch (SqlException se) {
2716:                    throw se.getSQLException();
2717:                }
2718:            }
2719:
2720:            // --------------------------- update column methods -------------------------
2721:
2722:            public void updateNull(int column) throws SQLException {
2723:                try {
2724:                    synchronized (connection_) {
2725:                        if (agent_.loggingEnabled()) {
2726:                            agent_.logWriter_.traceEntry(this , "updateNull",
2727:                                    column);
2728:                        }
2729:                        checkUpdatePreconditions(column, "updateNull");
2730:                        if (!resultSetMetaData_.nullable_[column - 1]) {
2731:                            throw new SqlException(agent_.logWriter_,
2732:                                    new ClientMessageId(
2733:                                            SQLState.LANG_NULL_INTO_NON_NULL),
2734:                                    new Integer(column));
2735:                        }
2736:                        updateColumn(column, null);
2737:                    }
2738:                } catch (SqlException se) {
2739:                    throw se.getSQLException();
2740:                }
2741:            }
2742:
2743:            public void updateBoolean(int column, boolean x)
2744:                    throws SQLException {
2745:                try {
2746:                    synchronized (connection_) {
2747:                        if (agent_.loggingEnabled()) {
2748:                            agent_.logWriter_.traceEntry(this , "updateBoolean",
2749:                                    column, x);
2750:                        }
2751:                        checkUpdatePreconditions(column, "updateBoolean");
2752:                        updateColumn(column, agent_.crossConverters_.setObject(
2753:                                resultSetMetaData_.types_[column - 1], x));
2754:                    }
2755:                } catch (SqlException se) {
2756:                    throw se.getSQLException();
2757:                }
2758:            }
2759:
2760:            public void updateByte(int column, byte x) throws SQLException {
2761:                try {
2762:                    synchronized (connection_) {
2763:                        if (agent_.loggingEnabled()) {
2764:                            agent_.logWriter_.traceEntry(this , "updateByte",
2765:                                    column, x);
2766:                        }
2767:                        checkUpdatePreconditions(column, "updateByte");
2768:                        updateColumn(column, agent_.crossConverters_.setObject(
2769:                                resultSetMetaData_.types_[column - 1], x));
2770:                    }
2771:                } catch (SqlException se) {
2772:                    throw se.getSQLException();
2773:                }
2774:            }
2775:
2776:            public void updateShort(int column, short x) throws SQLException {
2777:                try {
2778:                    synchronized (connection_) {
2779:                        if (agent_.loggingEnabled()) {
2780:                            agent_.logWriter_.traceEntry(this , "updateShort",
2781:                                    column, x);
2782:                        }
2783:                        checkUpdatePreconditions(column, "updateShort");
2784:                        updateColumn(column, agent_.crossConverters_.setObject(
2785:                                resultSetMetaData_.types_[column - 1], x));
2786:                    }
2787:                } catch (SqlException se) {
2788:                    throw se.getSQLException();
2789:                }
2790:            }
2791:
2792:            public void updateInt(int column, int x) throws SQLException {
2793:                try {
2794:                    synchronized (connection_) {
2795:                        if (agent_.loggingEnabled()) {
2796:                            agent_.logWriter_.traceEntry(this , "updateInt",
2797:                                    column, x);
2798:                        }
2799:                        checkUpdatePreconditions(column, "updateInt");
2800:                        updateColumn(column, agent_.crossConverters_.setObject(
2801:                                resultSetMetaData_.types_[column - 1], x));
2802:                    }
2803:                } catch (SqlException se) {
2804:                    throw se.getSQLException();
2805:                }
2806:            }
2807:
2808:            public void updateLong(int column, long x) throws SQLException {
2809:                try {
2810:                    synchronized (connection_) {
2811:                        if (agent_.loggingEnabled()) {
2812:                            agent_.logWriter_.traceEntry(this , "updateLong",
2813:                                    column, x);
2814:                        }
2815:                        checkUpdatePreconditions(column, "updateLong");
2816:                        updateColumn(column, agent_.crossConverters_.setObject(
2817:                                resultSetMetaData_.types_[column - 1], x));
2818:                    }
2819:                } catch (SqlException se) {
2820:                    throw se.getSQLException();
2821:                }
2822:            }
2823:
2824:            public void updateFloat(int column, float x) throws SQLException {
2825:                try {
2826:                    synchronized (connection_) {
2827:                        if (agent_.loggingEnabled()) {
2828:                            agent_.logWriter_.traceEntry(this , "updateFloat",
2829:                                    column, x);
2830:                        }
2831:                        checkUpdatePreconditions(column, "updateFloat");
2832:                        updateColumn(column, agent_.crossConverters_.setObject(
2833:                                resultSetMetaData_.types_[column - 1], x));
2834:                    }
2835:                } catch (SqlException se) {
2836:                    throw se.getSQLException();
2837:                }
2838:            }
2839:
2840:            public void updateDouble(int column, double x) throws SQLException {
2841:                try {
2842:                    synchronized (connection_) {
2843:                        if (agent_.loggingEnabled()) {
2844:                            agent_.logWriter_.traceEntry(this , "updateDouble",
2845:                                    column, x);
2846:                        }
2847:                        checkUpdatePreconditions(column, "updateDouble");
2848:                        updateColumn(column, agent_.crossConverters_.setObject(
2849:                                resultSetMetaData_.types_[column - 1], x));
2850:                    }
2851:                } catch (SqlException se) {
2852:                    throw se.getSQLException();
2853:                }
2854:            }
2855:
2856:            public void updateBigDecimal(int column, java.math.BigDecimal x)
2857:                    throws SQLException {
2858:                try {
2859:                    synchronized (connection_) {
2860:                        if (agent_.loggingEnabled()) {
2861:                            agent_.logWriter_.traceEntry(this ,
2862:                                    "updateBigDecimal", column, x);
2863:                        }
2864:                        checkUpdatePreconditions(column, "updateBigDecimal");
2865:                        updateColumn(column, agent_.crossConverters_.setObject(
2866:                                resultSetMetaData_.types_[column - 1], x));
2867:                    }
2868:                } catch (SqlException se) {
2869:                    throw se.getSQLException();
2870:                }
2871:            }
2872:
2873:            public void updateDate(int column, java.sql.Date x)
2874:                    throws SQLException {
2875:                try {
2876:                    synchronized (connection_) {
2877:                        if (agent_.loggingEnabled()) {
2878:                            agent_.logWriter_.traceEntry(this , "updateDate",
2879:                                    column, x);
2880:                        }
2881:                        checkUpdatePreconditions(column, "updateDate");
2882:                        updateColumn(column, agent_.crossConverters_.setObject(
2883:                                resultSetMetaData_.types_[column - 1], x));
2884:                    }
2885:                } catch (SqlException se) {
2886:                    throw se.getSQLException();
2887:                }
2888:            }
2889:
2890:            public void updateTime(int column, java.sql.Time x)
2891:                    throws SQLException {
2892:                try {
2893:                    synchronized (connection_) {
2894:                        if (agent_.loggingEnabled()) {
2895:                            agent_.logWriter_.traceEntry(this , "updateTime",
2896:                                    column, x);
2897:                        }
2898:                        checkUpdatePreconditions(column, "updateTime");
2899:                        updateColumn(column, agent_.crossConverters_.setObject(
2900:                                resultSetMetaData_.types_[column - 1], x));
2901:                    }
2902:                } catch (SqlException se) {
2903:                    throw se.getSQLException();
2904:                }
2905:            }
2906:
2907:            public void updateTimestamp(int column, java.sql.Timestamp x)
2908:                    throws SQLException {
2909:                try {
2910:                    synchronized (connection_) {
2911:                        if (agent_.loggingEnabled()) {
2912:                            agent_.logWriter_.traceEntry(this ,
2913:                                    "updateTimestamp", column, x);
2914:                        }
2915:                        checkUpdatePreconditions(column, "updateTimestamp");
2916:                        updateColumn(column, agent_.crossConverters_.setObject(
2917:                                resultSetMetaData_.types_[column - 1], x));
2918:                    }
2919:                } catch (SqlException se) {
2920:                    throw se.getSQLException();
2921:                }
2922:            }
2923:
2924:            public void updateString(int column, String x) throws SQLException {
2925:                try {
2926:                    synchronized (connection_) {
2927:                        if (agent_.loggingEnabled()) {
2928:                            agent_.logWriter_.traceEntry(this , "updateString",
2929:                                    column, x);
2930:                        }
2931:                        checkUpdatePreconditions(column, "updateString");
2932:                        updateColumn(column, agent_.crossConverters_.setObject(
2933:                                resultSetMetaData_.types_[column - 1], x));
2934:                    }
2935:                } catch (SqlException se) {
2936:                    throw se.getSQLException();
2937:                }
2938:            }
2939:
2940:            public void updateBytes(int column, byte x[]) throws SQLException {
2941:                try {
2942:                    synchronized (connection_) {
2943:                        if (agent_.loggingEnabled()) {
2944:                            agent_.logWriter_.traceEntry(this , "updateBytes",
2945:                                    column, x);
2946:                        }
2947:                        checkUpdatePreconditions(column, "updateBytes");
2948:                        updateColumn(column, agent_.crossConverters_.setObject(
2949:                                resultSetMetaData_.types_[column - 1], x));
2950:                    }
2951:                } catch (SqlException se) {
2952:                    throw se.getSQLException();
2953:                }
2954:            }
2955:
2956:            public void updateBinaryStream(int column, java.io.InputStream x,
2957:                    int length) throws SQLException {
2958:                try {
2959:                    synchronized (connection_) {
2960:                        if (agent_.loggingEnabled()) {
2961:                            agent_.logWriter_.traceEntry(this , "", column, x,
2962:                                    length);
2963:                        }
2964:                        checkUpdatePreconditions(column, "updateBinaryStream");
2965:                        updateColumn(column, agent_.crossConverters_
2966:                                .setObjectFromBinaryStream(
2967:                                        resultSetMetaData_.types_[column - 1],
2968:                                        x, length));
2969:                    }
2970:                } catch (SqlException se) {
2971:                    throw se.getSQLException();
2972:                }
2973:            }
2974:
2975:            public void updateAsciiStream(int column, java.io.InputStream x,
2976:                    int length) throws SQLException {
2977:                try {
2978:                    synchronized (connection_) {
2979:                        if (agent_.loggingEnabled()) {
2980:                            agent_.logWriter_.traceEntry(this ,
2981:                                    "updateAsciiStream", column, x, length);
2982:                        }
2983:                        checkUpdatePreconditions(column, "updateAsciiStream");
2984:                        updateColumn(column, agent_.crossConverters_
2985:                                .setObjectFromCharacterStream(
2986:                                        resultSetMetaData_.types_[column - 1],
2987:                                        x, "US-ASCII", length));
2988:                    }
2989:                } catch (SqlException se) {
2990:                    throw se.getSQLException();
2991:                }
2992:            }
2993:
2994:            public void updateCharacterStream(int column, java.io.Reader x,
2995:                    int length) throws SQLException {
2996:                try {
2997:                    synchronized (connection_) {
2998:                        if (agent_.loggingEnabled()) {
2999:                            agent_.logWriter_.traceEntry(this ,
3000:                                    "updateCharacterStream", column, x, length);
3001:                        }
3002:                        checkUpdatePreconditions(column,
3003:                                "updateCharacterStream");
3004:                        updateColumn(column, agent_.crossConverters_.setObject(
3005:                                resultSetMetaData_.types_[column - 1], x,
3006:                                length));
3007:                    }
3008:                } catch (SqlException se) {
3009:                    throw se.getSQLException();
3010:                }
3011:            }
3012:
3013:            public void updateObject(int column, Object x, int scale)
3014:                    throws SQLException {
3015:                try {
3016:                    synchronized (connection_) {
3017:                        if (agent_.loggingEnabled()) {
3018:                            agent_.logWriter_.traceEntry(this , "updateObject",
3019:                                    column, x, scale);
3020:                        }
3021:                        checkUpdatePreconditions(column, "updateObject");
3022:                        updateColumn(column, agent_.crossConverters_.setObject(
3023:                                resultSetMetaData_.types_[column - 1], x));
3024:                    }
3025:                } catch (SqlException se) {
3026:                    throw se.getSQLException();
3027:                }
3028:            }
3029:
3030:            public void updateObject(int column, Object x) throws SQLException {
3031:                try {
3032:                    synchronized (connection_) {
3033:                        if (agent_.loggingEnabled()) {
3034:                            agent_.logWriter_.traceEntry(this , "updateObject",
3035:                                    column, x);
3036:                        }
3037:                        checkUpdatePreconditions(column, "updateObject");
3038:                        updateColumn(column, agent_.crossConverters_.setObject(
3039:                                resultSetMetaData_.types_[column - 1], x));
3040:                    }
3041:                } catch (SqlException se) {
3042:                    throw se.getSQLException();
3043:                }
3044:            }
3045:
3046:            public void updateNCharacterStream(int columnIndex, Reader x)
3047:                    throws SQLException {
3048:                throw jdbc3MethodNotSupported();
3049:            }
3050:
3051:            public void updateNClob(int columnIndex, Reader reader)
3052:                    throws SQLException {
3053:                throw jdbc3MethodNotSupported();
3054:            }
3055:
3056:            // ---------------------- update on column name methods ----------------------
3057:
3058:            public void updateNull(String columnName) throws SQLException {
3059:                try {
3060:                    if (agent_.loggingEnabled()) {
3061:                        agent_.logWriter_.traceEntry(this , "updateNull",
3062:                                columnName);
3063:                    }
3064:                    updateNull(findColumnX(columnName));
3065:                } catch (SqlException se) {
3066:                    throw se.getSQLException();
3067:                }
3068:            }
3069:
3070:            public void updateBoolean(String columnName, boolean x)
3071:                    throws SQLException {
3072:                try {
3073:                    if (agent_.loggingEnabled()) {
3074:                        agent_.logWriter_.traceEntry(this , "updateBoolean",
3075:                                columnName, x);
3076:                    }
3077:                    updateBoolean(findColumnX(columnName), x);
3078:                } catch (SqlException se) {
3079:                    throw se.getSQLException();
3080:                }
3081:            }
3082:
3083:            public void updateByte(String columnName, byte x)
3084:                    throws SQLException {
3085:                try {
3086:                    if (agent_.loggingEnabled()) {
3087:                        agent_.logWriter_.traceEntry(this , "updateByte",
3088:                                columnName, x);
3089:                    }
3090:                    updateByte(findColumnX(columnName), x);
3091:                } catch (SqlException se) {
3092:                    throw se.getSQLException();
3093:                }
3094:            }
3095:
3096:            public void updateShort(String columnName, short x)
3097:                    throws SQLException {
3098:                try {
3099:                    if (agent_.loggingEnabled()) {
3100:                        agent_.logWriter_.traceEntry(this , "updateShort",
3101:                                columnName, x);
3102:                    }
3103:                    updateShort(findColumnX(columnName), x);
3104:                } catch (SqlException se) {
3105:                    throw se.getSQLException();
3106:                }
3107:            }
3108:
3109:            public void updateInt(String columnName, int x) throws SQLException {
3110:                try {
3111:                    if (agent_.loggingEnabled()) {
3112:                        agent_.logWriter_.traceEntry(this , "updateInt",
3113:                                columnName, x);
3114:                    }
3115:                    updateInt(findColumnX(columnName), x);
3116:                } catch (SqlException se) {
3117:                    throw se.getSQLException();
3118:                }
3119:            }
3120:
3121:            public void updateLong(String columnName, long x)
3122:                    throws SQLException {
3123:                try {
3124:                    if (agent_.loggingEnabled()) {
3125:                        agent_.logWriter_.traceEntry(this , "updateLong",
3126:                                columnName, x);
3127:                    }
3128:                    updateLong(findColumnX(columnName), x);
3129:                } catch (SqlException se) {
3130:                    throw se.getSQLException();
3131:                }
3132:            }
3133:
3134:            public void updateFloat(String columnName, float x)
3135:                    throws SQLException {
3136:                try {
3137:                    if (agent_.loggingEnabled()) {
3138:                        agent_.logWriter_.traceEntry(this , "updateFloat",
3139:                                columnName, x);
3140:                    }
3141:                    updateFloat(findColumnX(columnName), x);
3142:                } catch (SqlException se) {
3143:                    throw se.getSQLException();
3144:                }
3145:            }
3146:
3147:            public void updateDouble(String columnName, double x)
3148:                    throws SQLException {
3149:                try {
3150:                    if (agent_.loggingEnabled()) {
3151:                        agent_.logWriter_.traceEntry(this , "updateDouble",
3152:                                columnName, x);
3153:                    }
3154:                    updateDouble(findColumnX(columnName), x);
3155:                } catch (SqlException se) {
3156:                    throw se.getSQLException();
3157:                }
3158:            }
3159:
3160:            public void updateBigDecimal(String columnName,
3161:                    java.math.BigDecimal x) throws SQLException {
3162:                try {
3163:                    if (agent_.loggingEnabled()) {
3164:                        agent_.logWriter_.traceEntry(this , "updateBigDecimal",
3165:                                columnName, x);
3166:                    }
3167:                    updateBigDecimal(findColumnX(columnName), x);
3168:                } catch (SqlException se) {
3169:                    throw se.getSQLException();
3170:                }
3171:            }
3172:
3173:            public void updateDate(String columnName, java.sql.Date x)
3174:                    throws SQLException {
3175:                try {
3176:                    if (agent_.loggingEnabled()) {
3177:                        agent_.logWriter_.traceEntry(this , "updateDate",
3178:                                columnName, x);
3179:                    }
3180:                    updateDate(findColumnX(columnName), x);
3181:                } catch (SqlException se) {
3182:                    throw se.getSQLException();
3183:                }
3184:            }
3185:
3186:            public void updateTime(String columnName, java.sql.Time x)
3187:                    throws SQLException {
3188:                try {
3189:                    if (agent_.loggingEnabled()) {
3190:                        agent_.logWriter_.traceEntry(this , "updateTime",
3191:                                columnName, x);
3192:                    }
3193:                    updateTime(findColumnX(columnName), x);
3194:                } catch (SqlException se) {
3195:                    throw se.getSQLException();
3196:                }
3197:            }
3198:
3199:            public void updateTimestamp(String columnName, java.sql.Timestamp x)
3200:                    throws SQLException {
3201:                try {
3202:                    if (agent_.loggingEnabled()) {
3203:                        agent_.logWriter_.traceEntry(this , "updateTimestamp",
3204:                                columnName, x);
3205:                    }
3206:                    updateTimestamp(findColumnX(columnName), x);
3207:                } catch (SqlException se) {
3208:                    throw se.getSQLException();
3209:                }
3210:            }
3211:
3212:            public void updateString(String columnName, String x)
3213:                    throws SQLException {
3214:                try {
3215:                    if (agent_.loggingEnabled()) {
3216:                        agent_.logWriter_.traceEntry(this , "updateString",
3217:                                columnName, x);
3218:                    }
3219:                    updateString(findColumnX(columnName), x);
3220:                } catch (SqlException se) {
3221:                    throw se.getSQLException();
3222:                }
3223:            }
3224:
3225:            public void updateBytes(String columnName, byte x[])
3226:                    throws SQLException {
3227:                try {
3228:                    if (agent_.loggingEnabled()) {
3229:                        agent_.logWriter_.traceEntry(this , "updateBytes",
3230:                                columnName, x);
3231:                    }
3232:                    updateBytes(findColumnX(columnName), x);
3233:                } catch (SqlException se) {
3234:                    throw se.getSQLException();
3235:                }
3236:            }
3237:
3238:            public void updateBinaryStream(String columnName,
3239:                    java.io.InputStream x, int length) throws SQLException {
3240:                try {
3241:                    if (agent_.loggingEnabled()) {
3242:                        agent_.logWriter_.traceEntry(this ,
3243:                                "updateBinaryStream", columnName, x, length);
3244:                    }
3245:                    updateBinaryStream(findColumnX(columnName), x, length);
3246:                } catch (SqlException se) {
3247:                    throw se.getSQLException();
3248:                }
3249:            }
3250:
3251:            public void updateAsciiStream(String columnName,
3252:                    java.io.InputStream x, int length) throws SQLException {
3253:                try {
3254:                    if (agent_.loggingEnabled()) {
3255:                        agent_.logWriter_.traceEntry(this , "updateAsciiStream",
3256:                                columnName, x, length);
3257:                    }
3258:                    updateAsciiStream(findColumnX(columnName), x, length);
3259:                } catch (SqlException se) {
3260:                    throw se.getSQLException();
3261:                }
3262:            }
3263:
3264:            public void updateCharacterStream(String columnName,
3265:                    java.io.Reader x, int length) throws SQLException {
3266:                try {
3267:                    if (agent_.loggingEnabled()) {
3268:                        agent_.logWriter_.traceEntry(this ,
3269:                                "updateCharacterStream", columnName, x, length);
3270:                    }
3271:                    updateCharacterStream(findColumnX(columnName), x, length);
3272:                } catch (SqlException se) {
3273:                    throw se.getSQLException();
3274:                }
3275:            }
3276:
3277:            public void updateObject(String columnName, Object x, int scale)
3278:                    throws SQLException {
3279:                try {
3280:                    if (agent_.loggingEnabled()) {
3281:                        agent_.logWriter_.traceEntry(this , "updateObject",
3282:                                columnName, x, scale);
3283:                    }
3284:                    updateObject(findColumnX(columnName), x, scale);
3285:                } catch (SqlException se) {
3286:                    throw se.getSQLException();
3287:                }
3288:            }
3289:
3290:            public void updateObject(String columnName, Object x)
3291:                    throws SQLException {
3292:                try {
3293:                    if (agent_.loggingEnabled()) {
3294:                        agent_.logWriter_.traceEntry(this , "updateObject",
3295:                                columnName, x);
3296:                    }
3297:                    updateObject(findColumnX(columnName), x);
3298:                } catch (SqlException se) {
3299:                    throw se.getSQLException();
3300:                }
3301:            }
3302:
3303:            public void updateNCharacterStream(String columnName, Reader x)
3304:                    throws SQLException {
3305:                throw jdbc3MethodNotSupported();
3306:            }
3307:
3308:            public void updateNClob(String columnName, Reader reader)
3309:                    throws SQLException {
3310:                throw jdbc3MethodNotSupported();
3311:            }
3312:
3313:            // ---------------------------------------------------------------------------
3314:
3315:            public void insertRow() throws SQLException {
3316:                try {
3317:                    synchronized (connection_) {
3318:                        if (agent_.loggingEnabled()) {
3319:                            agent_.logWriter_.traceEntry(this , "insertRow");
3320:                        }
3321:                        insertRowX();
3322:                    }
3323:                } catch (SqlException se) {
3324:                    throw se.getSQLException();
3325:                }
3326:            }
3327:
3328:            private void insertRowX() throws SqlException {
3329:                checkForClosedResultSet();
3330:                checkForUpdatableResultSet("insertRow");
3331:                if (isOnCurrentRow_) {
3332:                    throw new SqlException(
3333:                            agent_.logWriter_,
3334:                            new ClientMessageId(
3335:                                    SQLState.CURSOR_NOT_POSITIONED_ON_INSERT_ROW));
3336:                }
3337:
3338:                // if not on a valid row, then do not accept updateXXX calls
3339:                if (!isValidCursorPosition_) {
3340:                    throw new SqlException(
3341:                            agent_.logWriter_,
3342:                            new ClientMessageId(
3343:                                    SQLState.CURSOR_INVALID_OPERATION_AT_CURRENT_POSITION));
3344:                }
3345:
3346:                // User might not be updating all the updatable columns selected in the
3347:                // select sql and hence every insertRow on the same ResultSet can be
3348:                // potentially different than the previous one. Because of that, we
3349:                // should get a new prepared statement to do inserts every time
3350:                getPreparedStatementForInsert();
3351:
3352:                // build the inputs array for the prepared statement for insert
3353:                int paramNumber = 0;
3354:                for (int i = 0; i < updatedColumns_.length; i++) {
3355:                    if (resultSetMetaData_.sqlxUpdatable_[i] == 1) {
3356:                        // Since user may choose not to update all the columns in the
3357:                        // select list, check first if the column has been updated
3358:                        if (columnUpdated_[i] == true) {
3359:                            paramNumber++;
3360:
3361:                            // column is updated either if the updatedColumns_ entry is not null,
3362:                            // or if the updatedColumns_ entry is null, but columnUpdated is
3363:                            // set to true, which means columns is updated to a null.
3364:                            if (updatedColumns_[i] != null
3365:                                    || (updatedColumns_[i] == null && columnUpdated_[i])) {
3366:                                preparedStatementForInsert_.setInput(
3367:                                        paramNumber, updatedColumns_[i]);
3368:                            }
3369:                        }
3370:                    }
3371:                }
3372:                try {
3373:                    insert();
3374:                } catch (SqlException e) {
3375:                    throw e;
3376:                }
3377:            }
3378:
3379:            public void updateRow() throws java.sql.SQLException {
3380:                try {
3381:                    synchronized (connection_) {
3382:                        if (agent_.loggingEnabled()) {
3383:                            agent_.logWriter_.traceEntry(this , "updateRow");
3384:                        }
3385:                        // If updateXXX were issued on the row before updateRow and
3386:                        // the result set if forward only, then position the ResultSet
3387:                        // to right before the next row after updateRow.
3388:                        if (updateRowX()
3389:                                && (getType() == ResultSet.TYPE_FORWARD_ONLY)) {
3390:                            isValidCursorPosition_ = false;
3391:                        }
3392:                    }
3393:                } catch (SqlException se) {
3394:                    throw se.getSQLException();
3395:                }
3396:            }
3397:
3398:            //if no updateXXX were issued before this updateRow, then return false
3399:            private boolean updateRowX() throws SqlException {
3400:                checkForClosedResultSet();
3401:
3402:                checkForUpdatableResultSet("updateRow");
3403:
3404:                if (isOnInsertRow_) {
3405:                    throw new SqlException(agent_.logWriter_,
3406:                            new ClientMessageId(SQLState.NO_CURRENT_ROW));
3407:                }
3408:
3409:                //if not on a valid row, then do not accept updateXXX calls
3410:                if (!isValidCursorPosition_)
3411:                    throw new SqlException(
3412:                            agent_.logWriter_,
3413:                            new ClientMessageId(
3414:                                    SQLState.CURSOR_INVALID_OPERATION_AT_CURRENT_POSITION));
3415:
3416:                // If no updateXXX has been called on this ResultSet object, then
3417:                // updatedColumns_ will be null and hence no action required
3418:                if (updatedColumns_ == null) {
3419:                    return false;
3420:                }
3421:
3422:                // updateXXX has been called on this ResultSet object, but check if it
3423:                // has been called on the current row. If no column got updated on this
3424:                // current row, then just return.
3425:                boolean didAnyColumnGetUpdated = false;
3426:                for (int i = 0; i < updatedColumns_.length; i++) {
3427:                    if (columnUpdated_[i]) {
3428:                        didAnyColumnGetUpdated = true;
3429:                        break;
3430:                    }
3431:                }
3432:                if (didAnyColumnGetUpdated == false)
3433:                    return false;
3434:
3435:                // User might not be updating all the updatable columns selected in the
3436:                // select sql and hence every updateRow on the same ResultSet can be
3437:                // potentially different than the previous one. Because of that, we
3438:                // should get a new prepared statement to do updates every time
3439:                getPreparedStatementForUpdate();
3440:
3441:                // build the inputs array for the prepared statement for update
3442:                int paramNumber = 0;
3443:                for (int i = 0; i < updatedColumns_.length; i++) {
3444:                    if (resultSetMetaData_.sqlxUpdatable_[i] == 1) {
3445:                        // Since user may choose not to update all the columns in the
3446:                        // select list, check first if the column has been updated
3447:                        if (columnUpdated_[i] == false)
3448:                            continue;
3449:                        paramNumber++;
3450:
3451:                        // column is updated either if the updatedColumns_ entry is not null,
3452:                        // or if the updatedColumns_ entry is null, but columnUpdated_ boolean is
3453:                        // set to true, which means columns is updated to a null.
3454:                        if (updatedColumns_[i] != null
3455:                                || (updatedColumns_[i] == null && columnUpdated_[i])) {
3456:                            preparedStatementForUpdate_.setInput(paramNumber,
3457:                                    updatedColumns_[i]);
3458:                        } else {
3459:                            // Check if the original column is null.  Calling CrossConverters.setObject on a null
3460:                            // column causes "Data Conversion" Exception.
3461:                            Object originalObj;
3462:                            try {
3463:                                originalObj = getObject(i + 1);
3464:                            } catch (SQLException se) {
3465:                                throw new SqlException(se);
3466:                            }
3467:
3468:                            if (originalObj == null) {
3469:                                preparedStatementForUpdate_.setInput(
3470:                                        paramNumber, null);
3471:                            } else {
3472:                                preparedStatementForUpdate_.setInput(
3473:                                        paramNumber,
3474:                                        agent_.crossConverters_.setObject(
3475:                                                resultSetMetaData_.types_[i],
3476:                                                originalObj));
3477:                            }
3478:                        }
3479:                    }
3480:                }
3481:                // need to cancel updates if the actual update was not successful at the server.
3482:                // alternative is to check for updateCount_ in "positionToCurrentRowAndUpdate".
3483:                // cancelRowUpdates if updateCount_ != 1
3484:                try {
3485:                    if (isRowsetCursor_
3486:                            || sensitivity_ == sensitivity_sensitive_dynamic__
3487:                            || sensitivity_ == sensitivity_sensitive_static__) {
3488:                        update();
3489:                    } else {
3490:                        positionToCurrentRowAndUpdate();
3491:                    }
3492:                } finally {
3493:                    resetUpdatedColumns();
3494:                }
3495:
3496:                // Ensure the data is reset
3497:                if (resultSetType_ == ResultSet.TYPE_SCROLL_INSENSITIVE) {
3498:                    if (preparedStatementForUpdate_.updateCount_ > 0) {
3499:                        // This causes a round-trip
3500:                        getAbsoluteRowset(absolutePosition_);
3501:                    }
3502:                }
3503:
3504:                return true;
3505:            }
3506:
3507:            public void deleteRow() throws java.sql.SQLException {
3508:                try {
3509:                    synchronized (connection_) {
3510:                        if (agent_.loggingEnabled()) {
3511:                            agent_.logWriter_.traceEntry(this , "deleteRow");
3512:                        }
3513:                        deleteRowX();
3514:                        //the cursor is not positioned on the deleted row after deleteRow.
3515:                        //User needs to issue ResultSet.next to reposition the ResultSet
3516:                        //on a valid row
3517:                        isValidCursorPosition_ = false;
3518:                    }
3519:                } catch (SqlException se) {
3520:                    throw se.getSQLException();
3521:                }
3522:            }
3523:
3524:            private void deleteRowX() throws SqlException {
3525:                checkForClosedResultSet();
3526:
3527:                checkForUpdatableResultSet("deleteRow");
3528:
3529:                // discard all previous updates
3530:                resetUpdatedColumns();
3531:
3532:                if (isOnInsertRow_) {
3533:                    throw new SqlException(agent_.logWriter_,
3534:                            new ClientMessageId(SQLState.NO_CURRENT_ROW));
3535:                }
3536:
3537:                if (preparedStatementForDelete_ == null) {
3538:                    getPreparedStatementForDelete();
3539:                }
3540:
3541:                if (isRowsetCursor_
3542:                        || sensitivity_ == sensitivity_sensitive_dynamic__
3543:                        || sensitivity_ == sensitivity_sensitive_static__) {
3544:                    delete();
3545:                } else {
3546:                    positionToCurrentRowAndDelete();
3547:                }
3548:
3549:                if (resultSetType_ == java.sql.ResultSet.TYPE_FORWARD_ONLY) {
3550:                    cursor_.isUpdateDeleteHole_ = true;
3551:                } else {
3552:                    if (preparedStatementForDelete_.updateCount_ > 0) {
3553:
3554:                        cursor_.isUpdateDeleteHoleCache_.set(
3555:                                (int) currentRowInRowset_, Cursor.ROW_IS_NULL);
3556:                        cursor_.isUpdateDeleteHole_ = ((Boolean) cursor_.isUpdateDeleteHoleCache_
3557:                                .get((int) currentRowInRowset_)).booleanValue();
3558:                    }
3559:                }
3560:            }
3561:
3562:            public void refreshRow() throws SQLException {
3563:                try {
3564:                    synchronized (connection_) {
3565:                        if (agent_.loggingEnabled()) {
3566:                            agent_.logWriter_.traceEntry(this , "refreshRow");
3567:                        }
3568:                        refreshRowX();
3569:                    }
3570:                } catch (SqlException se) {
3571:                    throw se.getSQLException();
3572:                }
3573:            }
3574:
3575:            private void refreshRowX() throws SqlException {
3576:                checkForClosedResultSet();
3577:                checkThatResultSetTypeIsScrollable();
3578:                checkForUpdatableResultSet("refreshRow");
3579:                if (isBeforeFirstX() || isAfterLastX() || isOnInsertRow_) {
3580:                    throw new SqlException(agent_.logWriter_,
3581:                            new ClientMessageId(SQLState.NO_CURRENT_ROW));
3582:                }
3583:
3584:                // this method does nothing if ResultSet is TYPE_SCROLL_INSENSITIVE
3585:                if (resultSetType_ == java.sql.ResultSet.TYPE_SCROLL_SENSITIVE) {
3586:                    isValidCursorPosition_ = getRefreshRowset();
3587:                    try {
3588:                        cancelRowUpdates();
3589:                    } catch (SQLException sqle) {
3590:                        throw new SqlException(sqle);
3591:                    }
3592:
3593:                    unuseStreams();
3594:
3595:                }
3596:            }
3597:
3598:            public void cancelRowUpdates() throws SQLException {
3599:                try {
3600:                    synchronized (connection_) {
3601:                        if (agent_.loggingEnabled()) {
3602:                            agent_.logWriter_.traceEntry(this ,
3603:                                    "cancelRowUpdates");
3604:                        }
3605:                        checkForClosedResultSet();
3606:                        checkForUpdatableResultSet("cancelRowUpdates");
3607:                        if (isOnInsertRow_) {
3608:                            throw new SqlException(
3609:                                    agent_.logWriter_,
3610:                                    new ClientMessageId(
3611:                                            SQLState.CURSOR_NOT_POSITIONED_ON_INSERT_ROW));
3612:                        }
3613:
3614:                        // if not on a valid row, then do not accept cancelRowUpdates call
3615:                        if (!isValidCursorPosition_)
3616:                            throw new SqlException(
3617:                                    agent_.logWriter_,
3618:                                    new ClientMessageId(
3619:                                            SQLState.CURSOR_INVALID_OPERATION_AT_CURRENT_POSITION));
3620:                        // Reset updated columns
3621:                        resetUpdatedColumns();
3622:                    }
3623:                } catch (SqlException se) {
3624:                    throw se.getSQLException();
3625:                }
3626:            }
3627:
3628:            public void moveToInsertRow() throws SQLException {
3629:                try {
3630:                    synchronized (connection_) {
3631:                        if (agent_.loggingEnabled()) {
3632:                            agent_.logWriter_.traceEntry(this ,
3633:                                    "moveToInsertRow");
3634:                        }
3635:                        checkForClosedResultSet();
3636:                        checkForUpdatableResultSet("moveToInsertRow");
3637:
3638:                        resetUpdatedColumnsForInsert();
3639:
3640:                        isOnInsertRow_ = true;
3641:                        isOnCurrentRow_ = false;
3642:                        isValidCursorPosition_ = true;
3643:                    }
3644:                } catch (SqlException se) {
3645:                    throw se.getSQLException();
3646:                }
3647:            }
3648:
3649:            public void moveToCurrentRow() throws SQLException {
3650:                try {
3651:                    synchronized (connection_) {
3652:                        if (agent_.loggingEnabled()) {
3653:                            agent_.logWriter_.traceEntry(this ,
3654:                                    "moveToCurrentRow");
3655:                        }
3656:                        checkForClosedResultSet();
3657:                        checkForUpdatableResultSet("moveToCurrentRow");
3658:
3659:                        moveToCurrentRowX();
3660:                    }
3661:                } catch (SqlException se) {
3662:                    throw se.getSQLException();
3663:                }
3664:            }
3665:
3666:            private void moveToCurrentRowX() throws SqlException {
3667:                if (isOnInsertRow_) {
3668:                    resetUpdatedColumns();
3669:                    isOnInsertRow_ = false;
3670:                    isOnCurrentRow_ = true;
3671:                    if (currentRowInRowset_ > 0) {
3672:                        updateColumnInfoFromCache();
3673:                    }
3674:                    isValidCursorPosition_ = true;
3675:                }
3676:            }
3677:
3678:            /**
3679:             * Retrieves the <code>Statement</code> object that produced this
3680:             * object, or <code>null</code> if the <code>ResultSet</code> was
3681:             * not produced by a <code>Statement</code> object.
3682:             *
3683:             * @return the <code>Statement</code> that produced this object or
3684:             * <code>null</code>
3685:             * @exception SQLException if a database error occurs or the
3686:             * result set is closed
3687:             */
3688:            public java.sql.Statement getStatement() throws SQLException {
3689:                try {
3690:                    checkForClosedResultSet();
3691:                } catch (SqlException se) {
3692:                    throw se.getSQLException();
3693:                }
3694:                if (agent_.loggingEnabled()) {
3695:                    agent_.logWriter_.traceExit(this , "getStatement",
3696:                            statement_);
3697:                }
3698:                return statement_;
3699:            }
3700:
3701:            //-------------------------- JDBC 3.0 ----------------------------------------
3702:
3703:            public java.net.URL getURL(int columnIndex) throws SQLException {
3704:                throw jdbc3MethodNotSupported();
3705:            }
3706:
3707:            public java.net.URL getURL(String columnName) throws SQLException {
3708:                throw jdbc3MethodNotSupported();
3709:            }
3710:
3711:            public void updateRef(int columnIndex, java.sql.Ref x)
3712:                    throws SQLException {
3713:                throw jdbc3MethodNotSupported();
3714:            }
3715:
3716:            public void updateRef(String columnName, java.sql.Ref x)
3717:                    throws SQLException {
3718:                throw jdbc3MethodNotSupported();
3719:            }
3720:
3721:            public void updateBlob(int columnIndex, java.sql.Blob x)
3722:                    throws SQLException {
3723:                throw jdbc3MethodNotSupported();
3724:            }
3725:
3726:            public void updateBlob(String columnName, java.sql.Blob x)
3727:                    throws SQLException {
3728:                throw jdbc3MethodNotSupported();
3729:            }
3730:
3731:            public void updateClob(int columnIndex, java.sql.Clob x)
3732:                    throws SQLException {
3733:                throw jdbc3MethodNotSupported();
3734:            }
3735:
3736:            public void updateClob(String columnName, java.sql.Clob x)
3737:                    throws SQLException {
3738:                throw jdbc3MethodNotSupported();
3739:            }
3740:
3741:            public void updateArray(int columnIndex, java.sql.Array x)
3742:                    throws SQLException {
3743:                throw jdbc3MethodNotSupported();
3744:            }
3745:
3746:            public void updateArray(String columnName, java.sql.Array x)
3747:                    throws SQLException {
3748:                throw jdbc3MethodNotSupported();
3749:            }
3750:
3751:            public boolean repositionScrollableResultSetBeforeJDBC1PositionedUpdateDelete()
3752:                    throws SqlException {
3753:                boolean repositionedCursor = false;
3754:
3755:                // calculate the absolutePosition of the current row directly.
3756:                long rowToFetch = getRowUncast() - absolutePosition_;
3757:
3758:                // if rowToFetch is zero, already positioned on the current row
3759:                if (rowToFetch != 0) {
3760:                    writePositioningFetch_(
3761:                            (generatedSection_ == null) ? statement_.section_
3762:                                    : generatedSection_,
3763:                            scrollOrientation_relative__, rowToFetch);
3764:                    // adjust the absolute position on the client
3765:                    absolutePosition_ += rowToFetch;
3766:                    repositionedCursor = true;
3767:                }
3768:                return repositionedCursor;
3769:            }
3770:
3771:            //--------------------categorize the methods below -----------------
3772:
3773:            public void flowPositioningFetch(int scrollOrientation,
3774:                    int rowToFetch) throws DisconnectException {
3775:                // need the try-catch block here because agent_.beginWriteChain throws
3776:                // an SqlException
3777:                try {
3778:                    agent_.beginWriteChain(statement_);
3779:
3780:                    writePositioningFetch_(
3781:                            (generatedSection_ == null) ? statement_.section_
3782:                                    : generatedSection_, scrollOrientation,
3783:                            rowToFetch);
3784:
3785:                    agent_.flow(statement_);
3786:                    readPositioningFetch_();
3787:                    agent_.endReadChain();
3788:                } catch (SqlException e) {
3789:                    throw new DisconnectException(agent_, e);
3790:                }
3791:            }
3792:
3793:            protected void positionToCurrentRowAndUpdate() throws SqlException {
3794:                agent_.beginWriteChain(statement_);
3795:
3796:                // calculate the position of the current row relative to the absolute position on server
3797:                long currentRowPosRelativeToAbsoluteRowPos = getRowUncast()
3798:                        - absolutePosition_;
3799:
3800:                // if currentRowPosRelativeToAbsoluteRowPos is zero, already on the current row
3801:                // reposition only if a commit has been sent
3802:                // do not reposition forward-only cursors
3803:                if (resultSetType_ != java.sql.ResultSet.TYPE_FORWARD_ONLY
3804:                        && (currentRowPosRelativeToAbsoluteRowPos != 0 || (currentRowPosRelativeToAbsoluteRowPos == 0 && cursorUnpositionedOnServer_))) {
3805:                    writePositioningFetch_(
3806:                            (generatedSection_ == null) ? statement_.section_
3807:                                    : generatedSection_,
3808:                            scrollOrientation_relative__,
3809:                            currentRowPosRelativeToAbsoluteRowPos);
3810:                }
3811:
3812:                // re-prepare the update statement if repreparing is needed after a commit.
3813:                if (!preparedStatementForUpdate_.openOnServer_) {
3814:                    preparedStatementForUpdate_.materialPreparedStatement_
3815:                            .writePrepare_(preparedStatementForUpdate_.sql_,
3816:                                    preparedStatementForUpdate_.section_);
3817:                }
3818:
3819:                try {
3820:                    writeUpdateRow(false);
3821:                } catch (SQLException se) {
3822:                    throw new SqlException(se);
3823:                }
3824:
3825:                agent_.flow(statement_);
3826:
3827:                // adjust the absolute position on the client
3828:                absolutePosition_ += currentRowPosRelativeToAbsoluteRowPos;
3829:
3830:                if (resultSetType_ != java.sql.ResultSet.TYPE_FORWARD_ONLY
3831:                        && (currentRowPosRelativeToAbsoluteRowPos != 0 || (currentRowPosRelativeToAbsoluteRowPos == 0 && cursorUnpositionedOnServer_))) {
3832:                    readPositioningFetch_();
3833:                    cursorUnpositionedOnServer_ = false;
3834:                    listenToUnitOfWork();
3835:                }
3836:
3837:                // read prepare replies if the update statement is re-prepared after a commit.
3838:                if (!preparedStatementForUpdate_.openOnServer_) {
3839:                    preparedStatementForUpdate_.materialPreparedStatement_
3840:                            .readPrepare_();
3841:                }
3842:                readUpdateRow();
3843:
3844:                agent_.endReadChain();
3845:            }
3846:
3847:            protected void insert() throws SqlException {
3848:                agent_.beginWriteChain(statement_);
3849:
3850:                // re-prepare the insert statement if repreparing is needed after a commit.
3851:                if (!preparedStatementForInsert_.openOnServer_) {
3852:                    preparedStatementForInsert_.materialPreparedStatement_
3853:                            .writePrepare_(preparedStatementForInsert_.sql_,
3854:                                    preparedStatementForInsert_.section_);
3855:                }
3856:
3857:                try {
3858:                    writeInsertRow(false);
3859:                } catch (SQLException se) {
3860:                    throw new SqlException(se);
3861:                }
3862:
3863:                agent_.flow(statement_);
3864:
3865:                // read prepare replies if the update statement is re-prepared after a commit.
3866:                if (!preparedStatementForInsert_.openOnServer_) {
3867:                    preparedStatementForInsert_.materialPreparedStatement_
3868:                            .readPrepare_();
3869:                }
3870:
3871:                readInsertRow();
3872:
3873:                agent_.endReadChain();
3874:            }
3875:
3876:            protected void update() throws SqlException {
3877:                agent_.beginWriteChain(statement_);
3878:
3879:                // re-prepare the update statement if repreparing is needed after a commit.
3880:                if (!preparedStatementForUpdate_.openOnServer_) {
3881:                    preparedStatementForUpdate_.materialPreparedStatement_
3882:                            .writePrepare_(preparedStatementForUpdate_.sql_,
3883:                                    preparedStatementForUpdate_.section_);
3884:                }
3885:
3886:                if (isRowsetCursor_) {
3887:                    try {
3888:                        preparedStatementForUpdate_.setInt(
3889:                                updatedColumns_.length + 1,
3890:                                (int) (currentRowInRowset_ + 1));
3891:                    } catch (SQLException se) {
3892:                        throw new SqlException(se);
3893:                    }
3894:                }
3895:
3896:                boolean chainAutoCommit = connection_
3897:                        .willAutoCommitGenerateFlow();
3898:                try {
3899:                    writeUpdateRow(chainAutoCommit);
3900:                } catch (SQLException se) {
3901:                    throw new SqlException(se);
3902:                }
3903:                if (chainAutoCommit) {
3904:                    connection_.writeCommit();
3905:                }
3906:
3907:                agent_.flow(statement_);
3908:
3909:                // read prepare replies if the update statement is re-prepared after a commit.
3910:                if (!preparedStatementForUpdate_.openOnServer_) {
3911:                    preparedStatementForUpdate_.materialPreparedStatement_
3912:                            .readPrepare_();
3913:                }
3914:
3915:                readUpdateRow();
3916:
3917:                if (chainAutoCommit) {
3918:                    connection_.readCommit();
3919:                }
3920:                agent_.endReadChain();
3921:            }
3922:
3923:            protected void positionToCurrentRowAndDelete() throws SqlException {
3924:                agent_.beginWriteChain(statement_);
3925:
3926:                // calculate the position of the current row relative to the absolute position on server
3927:                long currentRowPosRelativeToAbsoluteRowPos = getRowUncast()
3928:                        - absolutePosition_;
3929:
3930:                // if rowToFetch is zero, already positioned on the current row
3931:                // do not reposition forward-only cursors.
3932:                if (resultSetType_ != java.sql.ResultSet.TYPE_FORWARD_ONLY
3933:                        && (currentRowPosRelativeToAbsoluteRowPos != 0 || (currentRowPosRelativeToAbsoluteRowPos == 0 && cursorUnpositionedOnServer_))) {
3934:                    writePositioningFetch_(
3935:                            (generatedSection_ == null) ? statement_.section_
3936:                                    : generatedSection_,
3937:                            scrollOrientation_relative__,
3938:                            currentRowPosRelativeToAbsoluteRowPos);
3939:                }
3940:
3941:                // re-prepare the update statement if repreparing is needed after a commit.
3942:                if (!preparedStatementForDelete_.openOnServer_) {
3943:                    preparedStatementForDelete_.materialPreparedStatement_
3944:                            .writePrepare_(preparedStatementForDelete_.sql_,
3945:                                    preparedStatementForDelete_.section_);
3946:                }
3947:
3948:                try {
3949:                    writeDeleteRow();
3950:                } catch (SQLException sqle) {
3951:                    throw new SqlException(sqle);
3952:                }
3953:
3954:                agent_.flow(statement_);
3955:
3956:                // adjust the absolute position on the client.
3957:                absolutePosition_ += currentRowPosRelativeToAbsoluteRowPos;
3958:
3959:                if (resultSetType_ != java.sql.ResultSet.TYPE_FORWARD_ONLY
3960:                        && (currentRowPosRelativeToAbsoluteRowPos != 0 || (currentRowPosRelativeToAbsoluteRowPos == 0 && cursorUnpositionedOnServer_))) {
3961:                    readPositioningFetch_();
3962:                    cursorUnpositionedOnServer_ = false;
3963:                    listenToUnitOfWork();
3964:                }
3965:
3966:                // read prepare replies if the update statement is re-prepared after a commit.
3967:                if (!preparedStatementForDelete_.openOnServer_) {
3968:                    preparedStatementForDelete_.materialPreparedStatement_
3969:                            .readPrepare_();
3970:                }
3971:                readDeleteRow();
3972:
3973:                agent_.endReadChain();
3974:            }
3975:
3976:            protected void delete() throws SqlException {
3977:                try {
3978:                    agent_.beginWriteChain(statement_);
3979:
3980:                    // re-prepare the update statement if repreparing is needed after a commit.
3981:                    if (!preparedStatementForDelete_.openOnServer_) {
3982:                        preparedStatementForDelete_.materialPreparedStatement_
3983:                                .writePrepare_(
3984:                                        preparedStatementForDelete_.sql_,
3985:                                        preparedStatementForDelete_.section_);
3986:                    }
3987:
3988:                    if (isRowsetCursor_) {
3989:                        preparedStatementForDelete_.setInt(1,
3990:                                (int) (currentRowInRowset_ + 1));
3991:                    }
3992:
3993:                    writeDeleteRow();
3994:
3995:                    if (connection_.autoCommit_) {
3996:                        connection_.writeAutoCommit();
3997:                    }
3998:
3999:                    agent_.flow(statement_);
4000:
4001:                    // read prepare replies if the update statement is re-prepared after a commit.
4002:                    if (!preparedStatementForDelete_.openOnServer_) {
4003:                        preparedStatementForDelete_.materialPreparedStatement_
4004:                                .readPrepare_();
4005:                    }
4006:                    readDeleteRow();
4007:                    if (connection_.autoCommit_) {
4008:                        connection_.readAutoCommit();
4009:                    }
4010:                    agent_.endReadChain();
4011:                } catch (SQLException se) {
4012:                    throw new SqlException(se);
4013:                }
4014:            }
4015:
4016:            // Resets all rowset related flags.
4017:            // Called by getRowSet() from material layer.
4018:            public void setRowsetAfterLastEvent() throws SqlException {
4019:                firstRowInRowset_ = 0;
4020:                lastRowInRowset_ = 0;
4021:                absolutePosition_ = (maxRows_ == 0) ? rowCount_ + 1
4022:                        : maxRows_ + 1;
4023:                currentRowInRowset_ = 0;
4024:                rowsReceivedInCurrentRowset_ = 0;
4025:            }
4026:
4027:            public void setRowsetBeforeFirstEvent() throws SqlException {
4028:                firstRowInRowset_ = 0;
4029:                lastRowInRowset_ = 0;
4030:                absolutePosition_ = 0;
4031:                currentRowInRowset_ = -1;
4032:                rowsReceivedInCurrentRowset_ = 0;
4033:            }
4034:
4035:            public void setRowsetNoRowsEvent() {
4036:                rowCount_ = 0;
4037:                firstRowInRowset_ = 0;
4038:                lastRowInRowset_ = 0;
4039:                absolutePosition_ = 0;
4040:                currentRowInRowset_ = -1;
4041:                rowsReceivedInCurrentRowset_ = 0;
4042:            }
4043:
4044:            private boolean isServersCursorPositionBeforeFirst()
4045:                    throws SqlException {
4046:                return (isBeforeFirstX() && firstRowInRowset_ == 0
4047:                        && lastRowInRowset_ == 0 && absolutePosition_ == 0);
4048:            }
4049:
4050:            private boolean isServerCursorPositionAfterLast()
4051:                    throws SqlException {
4052:                return (absolutePosition_ == (rowCount_ + 1));
4053:            }
4054:
4055:            public void setValidCursorPosition(boolean isValidCursorPosition) {
4056:                isValidCursorPosition_ = isValidCursorPosition;
4057:            }
4058:
4059:            protected void moveToAfterLast() throws DisconnectException {
4060:                flowPositioningFetch(ResultSet.scrollOrientation_after__, 0);
4061:            }
4062:
4063:            // Positions the cursor at before the first row.
4064:            protected void moveToBeforeFirst() throws DisconnectException {
4065:                flowPositioningFetch(ResultSet.scrollOrientation_before__, 0);
4066:            }
4067:
4068:            // analyze the error handling here, and whether or not can be pushed to common
4069:            // can we make this the common layer fetch method
4070:            // Called by the read/skip Fdoca bytes methods in the net
4071:            // whenever data reads exhaust the internal buffer used by this reply
4072:            public void flowFetch() throws DisconnectException, SqlException {
4073:                agent_.beginWriteChain(statement_);
4074:                writeFetch_((generatedSection_ == null) ? statement_.section_
4075:                        : generatedSection_);
4076:                agent_.flow(statement_);
4077:                readFetch_();
4078:                agent_.endReadChain();
4079:            }
4080:
4081:            public void writeInsertRow(boolean chainedWritesFollowingSetLob)
4082:                    throws SQLException {
4083:                try {
4084:                    preparedStatementForInsert_.materialPreparedStatement_
4085:                            .writeExecute_(
4086:                                    preparedStatementForInsert_.section_,
4087:                                    preparedStatementForInsert_.parameterMetaData_,
4088:                                    preparedStatementForInsert_.parameters_,
4089:                                    (preparedStatementForInsert_.parameterMetaData_ == null ? 0
4090:                                            : preparedStatementForInsert_.parameterMetaData_
4091:                                                    .getColumnCount()), false, // false means we're not expecting output
4092:                                    chainedWritesFollowingSetLob); // chaining after the execute        
4093:                } catch (SqlException se) {
4094:                    throw se.getSQLException();
4095:                }
4096:            }
4097:
4098:            public void writeUpdateRow(boolean chainedWritesFollowingSetLob)
4099:                    throws SQLException {
4100:                try {
4101:                    preparedStatementForUpdate_.materialPreparedStatement_
4102:                            .writeExecute_(
4103:                                    preparedStatementForUpdate_.section_,
4104:                                    preparedStatementForUpdate_.parameterMetaData_,
4105:                                    preparedStatementForUpdate_.parameters_,
4106:                                    preparedStatementForUpdate_.parameterMetaData_
4107:                                            .getColumnCount(), false, // false means we're not expecting output
4108:                                    chainedWritesFollowingSetLob); // chaining after the execute
4109:                } catch (SqlException se) {
4110:                    throw se.getSQLException();
4111:                }
4112:            }
4113:
4114:            public void writeDeleteRow() throws SQLException {
4115:                try {
4116:                    if (isRowsetCursor_) {
4117:                        preparedStatementForDelete_.materialPreparedStatement_
4118:                                .writeExecute_(
4119:                                        preparedStatementForDelete_.section_,
4120:                                        preparedStatementForDelete_.parameterMetaData_,
4121:                                        preparedStatementForDelete_.parameters_,
4122:                                        preparedStatementForDelete_.parameterMetaData_
4123:                                                .getColumnCount(), false, // false means we're not expecting output
4124:                                        false); // false means we don't chain anything after the execute
4125:                    } else {
4126:                        preparedStatementForDelete_.materialPreparedStatement_
4127:                                .writeExecute_(
4128:                                        preparedStatementForDelete_.section_,
4129:                                        null, // do not need parameterMetaData since there is no input
4130:                                        null, // no inputs
4131:                                        0, // number of input columns is 0 for positioned delete
4132:                                        false, // false means we're not expecting output
4133:                                        false); // false means we don't chain anything after the execute
4134:                    }
4135:                } catch (SqlException se) {
4136:                    throw se.getSQLException();
4137:                }
4138:            }
4139:
4140:            public void readInsertRow() throws DisconnectException,
4141:                    SqlException {
4142:                preparedStatementForInsert_.materialPreparedStatement_
4143:                        .readExecute_();
4144:            }
4145:
4146:            public void readUpdateRow() throws DisconnectException,
4147:                    SqlException {
4148:                preparedStatementForUpdate_.materialPreparedStatement_
4149:                        .readExecute_();
4150:                accumulateWarning(preparedStatementForUpdate_.getSqlWarnings());
4151:            }
4152:
4153:            public void readDeleteRow() throws DisconnectException,
4154:                    SqlException {
4155:                preparedStatementForDelete_.materialPreparedStatement_
4156:                        .readExecute_();
4157:                accumulateWarning(preparedStatementForDelete_.getSqlWarnings());
4158:            }
4159:
4160:            //------------------material layer event callback methods-----------------------
4161:
4162:            boolean listenToUnitOfWork_ = false;
4163:
4164:            public void listenToUnitOfWork() {
4165:                if (!listenToUnitOfWork_) {
4166:                    listenToUnitOfWork_ = true;
4167:                    connection_.CommitAndRollbackListeners_.put(this , null);
4168:                }
4169:            }
4170:
4171:            public void completeLocalCommit(java.util.Iterator listenerIterator) {
4172:                cursorUnpositionedOnServer_ = true;
4173:                markAutoCommitted();
4174:                if (!cursorHold_) {
4175:                    // only non-held cursors need to be closed at commit
4176:                    markClosed();
4177:                    nullOutReferenceInStatement();
4178:                    // remove from listener list
4179:                    listenerIterator.remove();
4180:                    listenToUnitOfWork_ = false;
4181:                }
4182:            }
4183:
4184:            public void completeLocalRollback(
4185:                    java.util.Iterator listenerIterator) {
4186:                markAutoCommitted();
4187:                // all cursors need to be closed at rollback
4188:                markClosed();
4189:                nullOutReferenceInStatement();
4190:                // remove from listener list
4191:                listenerIterator.remove();
4192:                listenToUnitOfWork_ = false;
4193:            }
4194:
4195:            private void nullOutReferenceInStatement() {
4196:                if (statement_.resultSet_ == this ) {
4197:                    statement_.resultSet_ = null;
4198:                }
4199:                /*
4200:                 * Aug 10, 2005: Do we really only want to only null out the one resultSet? 
4201:                 * The only time this method is called is from completeLocalCommit or 
4202:                 * completeLocalRollback, both of which affect *all* ResultSets  
4203:                 */
4204:                if (statement_.resultSetList_ != null) {
4205:                    for (int i = 0; i < statement_.resultSetList_.length; i++) {
4206:                        if (statement_.resultSetList_[i] == this ) {
4207:                            statement_.resultSetList_[i] = null;
4208:                        }
4209:                    }
4210:                }
4211:            }
4212:
4213:            /**
4214:             * Mark this ResultSet as closed. The ResultSet will not be
4215:             * removed from the commit and rollback listeners list in
4216:             * <code>org.apache.derby.client.am.Connection</code>.
4217:             */
4218:            void markClosed() {
4219:                markClosed(false);
4220:            }
4221:
4222:            /**
4223:             * Mark this ResultSet as closed.
4224:             *
4225:             * @param removeListener if true the ResultSet will be removed
4226:             * from the commit and rollback listeners list in
4227:             * <code>org.apache.derby.client.am.Connection</code>.
4228:             */
4229:            void markClosed(boolean removeListener) {
4230:                openOnClient_ = false;
4231:                openOnServer_ = false;
4232:                statement_.resetCursorNameAndRemoveFromWhereCurrentOfMappings(); // for SELECT...FOR UPDATE queries
4233:                statement_.removeClientCursorNameFromCache();
4234:                markPositionedUpdateDeletePreparedStatementsClosed();
4235:                if (removeListener) {
4236:                    connection_.CommitAndRollbackListeners_.remove(this );
4237:                }
4238:            }
4239:
4240:            /**
4241:             * Mark this ResultSet as closed on the server.
4242:             */
4243:            public void markClosedOnServer() {
4244:                openOnServer_ = false;
4245:            }
4246:
4247:            void markAutoCommitted() {
4248:                autoCommitted_ = true;
4249:            }
4250:
4251:            // The query was ended at the server because all rows have been retrieved.
4252:            public void earlyCloseComplete(Sqlca sqlca) {
4253:                markClosedOnServer();
4254:                queryTerminatingSqlca_ = sqlca;
4255:                cursor_.setAllRowsReceivedFromServer(true);
4256:            }
4257:
4258:            public int completeSqlca(Sqlca sqlca) {
4259:                if (sqlca == null) {
4260:                    return 0;
4261:                }
4262:                int sqlcode = sqlca.getSqlCode();
4263:                if (sqlcode == 100 || sqlcode == 20237) {
4264:                    cursor_.setAllRowsReceivedFromServer(true);
4265:                } else if (sqlcode < 0) {
4266:                    connection_.agent_
4267:                            .accumulateReadException(new SqlException(
4268:                                    agent_.logWriter_, sqlca));
4269:                } else if (sqlcode > 0) {
4270:                    accumulateWarning(new SqlWarning(agent_.logWriter_, sqlca));
4271:                }
4272:                return sqlcode;
4273:            }
4274:
4275:            // Set rowCount.
4276:            public void setRowCountEvent(long rowCount)
4277:                    throws DisconnectException {
4278:                // Only set the row count if it's unknown, to prevent clobbering of a valid value.
4279:                if (rowCount_ == -1) {
4280:                    rowCount_ = rowCount;
4281:                }
4282:            }
4283:
4284:            // This method will not work if e is chained.
4285:            // It is assumed that e is a single warning and is not chained.
4286:            public void accumulateWarning(SqlWarning e) {
4287:                if (warnings_ == null) {
4288:                    warnings_ = e;
4289:                } else {
4290:                    warnings_.setNextException(e);
4291:                }
4292:            }
4293:
4294:            //-------------------------------helper methods-------------------------------
4295:            protected boolean rowCountIsUnknown() {
4296:                if (sensitivity_ == sensitivity_sensitive_dynamic__) {
4297:                    return false;
4298:                } else {
4299:                    return rowCount_ == -1;
4300:                }
4301:            }
4302:
4303:            protected boolean rowCountIsKnown() {
4304:                return rowCount_ != -1;
4305:            }
4306:
4307:            private void updateColumn(int column, Object value) {
4308:                if (updatedColumns_ == null) {
4309:                    updatedColumns_ = new Object[resultSetMetaData_.columns_];
4310:                }
4311:                if (columnUpdated_ == null) {
4312:                    columnUpdated_ = new boolean[resultSetMetaData_.columns_];
4313:                }
4314:
4315:                updatedColumns_[column - 1] = value;
4316:                columnUpdated_[column - 1] = true;
4317:            }
4318:
4319:            /*
4320:             * Builds the insert statement that will be used well calling insertRow
4321:             * 
4322:             * If no values have been supplied for a column, it will be set 
4323:             * to the column's default value, if any. 
4324:             * If no default value had been defined, the default value of a 
4325:             * nullable column is set to NULL.
4326:             */
4327:            private String buildInsertString() throws SqlException {
4328:                int column;
4329:                boolean foundOneUpdatedColumnAlready = false;
4330:
4331:                StringBuffer insertSQL = new StringBuffer("INSERT INTO ");
4332:                StringBuffer valuesSQL = new StringBuffer("VALUES (");
4333:
4334:                insertSQL.append(getTableName());
4335:                insertSQL.append(" (");
4336:
4337:                for (column = 1; column <= resultSetMetaData_.columns_; column++) {
4338:                    if (foundOneUpdatedColumnAlready) {
4339:                        insertSQL.append(",");
4340:                        valuesSQL.append(",");
4341:                    }
4342:                    //using quotes around the column name to preserve case sensitivity
4343:                    try {
4344:                        insertSQL.append(quoteSqlIdentifier(resultSetMetaData_
4345:                                .getColumnName(column)));
4346:                    } catch (SQLException sqle) {
4347:                        throw new SqlException(sqle);
4348:                    }
4349:                    if (columnUpdated_[column - 1]) {
4350:                        valuesSQL.append("?");
4351:                    } else {
4352:                        valuesSQL.append("DEFAULT");
4353:                    }
4354:                    foundOneUpdatedColumnAlready = true;
4355:                }
4356:
4357:                insertSQL.append(") ");
4358:                valuesSQL.append(") ");
4359:                insertSQL.append(valuesSQL.toString());
4360:
4361:                return (insertSQL.toString());
4362:            }
4363:
4364:            private String buildUpdateString() throws SqlException {
4365:                int column;
4366:                int numColumns = 0;
4367:
4368:                // For Derby, eg update t1 set c1=?, c2=? where current of cursorname
4369:                boolean foundOneUpdatedColumnAlready = false;
4370:                String updateString = "UPDATE " + getTableName() + " SET ";
4371:
4372:                for (column = 1; column <= resultSetMetaData_.columns_; column++) {
4373:                    if (columnUpdated_[column - 1]) {
4374:                        if (foundOneUpdatedColumnAlready) {
4375:                            updateString += ",";
4376:                        }
4377:                        try {
4378:                            updateString += quoteSqlIdentifier(resultSetMetaData_
4379:                                    .getColumnName(column))
4380:                                    + " = ? ";
4381:                        } catch (SQLException sqle) {
4382:                            throw new SqlException(sqle);
4383:                        }
4384:                        numColumns++;
4385:                        foundOneUpdatedColumnAlready = true;
4386:                    }
4387:                }
4388:                if (foundOneUpdatedColumnAlready == false) //no columns updated on this row
4389:                {
4390:                    return null;
4391:                }
4392:                updateString = updateString + " WHERE CURRENT OF "
4393:                        + getServerCursorName();
4394:
4395:                if (isRowsetCursor_) {
4396:                    updateString += " FOR ROW ? OF ROWSET";
4397:                }
4398:
4399:                return updateString;
4400:            }
4401:
4402:            private String buildDeleteString() throws SqlException {
4403:                String deleteString = "DELETE FROM ";
4404:
4405:                // build the delete string using the server's cursor name
4406:                deleteString += (getTableName() + " WHERE CURRENT OF \""
4407:                        + getServerCursorName() + "\"");
4408:
4409:                if (isRowsetCursor_) {
4410:                    deleteString += " FOR ROW ? OF ROWSET";
4411:                }
4412:
4413:                return deleteString;
4414:            }
4415:
4416:            //Go through all the columns in the select list to see if we can find a
4417:            //base table column and use that column's metadata to get the table name
4418:            //But, it is possible to have a sql of the form
4419:            //select 1,2 from t1 for update
4420:            //This sql will not be a good candidate for updateXXX calls(both in embedded
4421:            //and Network Server mode) since there is no updatable column in the select
4422:            //list. But a user can use a sql like that to issue deleteRow. In Network
4423:            //Server mode though, this sql will fail for deleteRow because none of the
4424:            //columns are from base table and w/o a base table column, there is no way
4425:            //to find the table name for delete
4426:            private String getTableName() throws SqlException {
4427:                String tableName = "";
4428:                int baseTableColumn = 0;
4429:                int totalColumns;
4430:                try {
4431:                    totalColumns = resultSetMetaData_.getColumnCount();
4432:                } catch (SQLException sqle) {
4433:                    throw new SqlException(sqle);
4434:                }
4435:                for (; baseTableColumn < totalColumns; baseTableColumn++) {
4436:                    if (resultSetMetaData_.sqlxBasename_[baseTableColumn] != null)
4437:                        break;
4438:                }
4439:
4440:                //if following true, then there are no base table columns in select list
4441:                if (baseTableColumn == totalColumns)
4442:                    baseTableColumn = 0;
4443:
4444:                //dervied column like select 2 from t1, has null schema and table name
4445:                if (resultSetMetaData_.sqlxSchema_[baseTableColumn] != null
4446:                        && !resultSetMetaData_.sqlxSchema_[baseTableColumn]
4447:                                .equals("")) {
4448:                    tableName += quoteSqlIdentifier(resultSetMetaData_.sqlxSchema_[baseTableColumn])
4449:                            + ".";
4450:                }
4451:                if (resultSetMetaData_.sqlxBasename_[baseTableColumn] != null) {
4452:                    tableName += quoteSqlIdentifier(resultSetMetaData_.sqlxBasename_[baseTableColumn]);
4453:                }
4454:                return tableName;
4455:            }
4456:
4457:            private String quoteSqlIdentifier(String orgValue) {
4458:                int i = 0, start = 0;
4459:                String retValue = "";
4460:                while ((i = orgValue.indexOf("\"", start) + 1) > 0) {
4461:                    retValue += orgValue.substring(start, i) + "\"";
4462:                    start = i;
4463:                }
4464:                retValue += orgValue.substring(start, orgValue.length());
4465:                return "\"" + retValue + "\"";
4466:            }
4467:
4468:            private String getServerCursorName() throws SqlException {
4469:                return statement_.section_.getServerCursorName();
4470:            }
4471:
4472:            private void getPreparedStatementForInsert() throws SqlException {
4473:                // each column is associated with a tableName in the extended describe info.
4474:                String insertString = buildInsertString();
4475:
4476:                try {
4477:                    preparedStatementForInsert_ = (PreparedStatement) statement_.connection_
4478:                            .prepareStatement(insertString);
4479:                } catch (SQLException sqle) {
4480:                    throw new SqlException(sqle);
4481:                }
4482:            }
4483:
4484:            private void getPreparedStatementForUpdate() throws SqlException {
4485:                // each column is associated with a tableName in the extended describe info.
4486:                String updateString = buildUpdateString();
4487:
4488:                if (updateString == null) {
4489:                    throw new SqlException(
4490:                            agent_.logWriter_,
4491:                            new ClientMessageId(
4492:                                    SQLState.CURSOR_NO_UPDATE_CALLS_ON_CURRENT_ROW));
4493:                }
4494:                preparedStatementForUpdate_ = statement_.connection_
4495:                        .preparePositionedUpdateStatement(updateString,
4496:                                statement_.section_
4497:                                        .getPositionedUpdateSection());
4498:
4499:            }
4500:
4501:            private void getPreparedStatementForDelete() throws SqlException {
4502:                // each column is associated with a tableName in the extended describe info.
4503:                String deleteString = buildDeleteString();
4504:
4505:                preparedStatementForDelete_ = statement_.connection_
4506:                        .preparePositionedUpdateStatement(deleteString,
4507:                                statement_.section_
4508:                                        .getPositionedUpdateSection()); // update section
4509:            }
4510:
4511:            private final void resetUpdatedColumnsForInsert() {
4512:                // initialize updateColumns with nulls for all columns
4513:                if (updatedColumns_ == null) {
4514:                    updatedColumns_ = new Object[resultSetMetaData_.columns_];
4515:                }
4516:                if (columnUpdated_ != null) {
4517:                    columnUpdated_ = new boolean[resultSetMetaData_.columns_];
4518:                }
4519:                for (int i = 0; i < updatedColumns_.length; i++) {
4520:                    updateColumn(i + 1, null);
4521:                }
4522:                for (int i = 0; i < columnUpdated_.length; i++) {
4523:                    columnUpdated_[i] = false;
4524:                }
4525:            }
4526:
4527:            private final void resetUpdatedColumns() {
4528:                if (updatedColumns_ != null) {
4529:                    for (int i = 0; i < updatedColumns_.length; i++) {
4530:                        updatedColumns_[i] = null;
4531:                    }
4532:                }
4533:                if (columnUpdated_ != null) {
4534:                    for (int i = 0; i < columnUpdated_.length; i++) {
4535:                        columnUpdated_[i] = false;
4536:                    }
4537:                }
4538:            }
4539:
4540:            private final long getRowUncast() {
4541:                return firstRowInRowset_ + currentRowInRowset_;
4542:            }
4543:
4544:            private final void checkGetterPreconditions(int column)
4545:                    throws SqlException {
4546:                checkForClosedResultSet();
4547:                checkForValidColumnIndex(column);
4548:                checkForValidCursorPosition();
4549:            }
4550:
4551:            private final void checkUpdatePreconditions(int column,
4552:                    String operation) throws SqlException {
4553:
4554:                checkForClosedResultSet();
4555:                checkForValidColumnIndex(column);
4556:                checkForUpdatableResultSet(operation);
4557:
4558:                if (!isOnCurrentRow_ && !isOnInsertRow_) {
4559:                    throw new SqlException(
4560:                            agent_.logWriter_,
4561:                            new ClientMessageId(
4562:                                    SQLState.CURSOR_NOT_ON_CURRENT_OR_INSERT_ROW));
4563:                }
4564:
4565:                if (resultSetMetaData_.sqlxUpdatable_ == null
4566:                        || resultSetMetaData_.sqlxUpdatable_[column - 1] != 1) {
4567:                    throw new SqlException(agent_.logWriter_,
4568:                            new ClientMessageId(
4569:                                    SQLState.CURSOR_COLUMN_NOT_UPDATABLE));
4570:                }
4571:
4572:                //if not on a valid row, then do not accept updateXXX calls
4573:                if (!isValidCursorPosition_)
4574:                    throw new SqlException(
4575:                            agent_.logWriter_,
4576:                            new ClientMessageId(
4577:                                    SQLState.CURSOR_INVALID_OPERATION_AT_CURRENT_POSITION));
4578:            }
4579:
4580:            final void checkForValidColumnIndex(int column) throws SqlException {
4581:                if (column < 1 || column > resultSetMetaData_.columns_) {
4582:                    throw new SqlException(agent_.logWriter_,
4583:                            new ClientMessageId(
4584:                                    SQLState.LANG_INVALID_COLUMN_POSITION),
4585:                            new Integer(column), new Integer(
4586:                                    resultSetMetaData_.columns_));
4587:                }
4588:            }
4589:
4590:            protected final void checkForClosedResultSet() throws SqlException {
4591:                if (!openOnClient_) {
4592:                    agent_.checkForDeferredExceptions();
4593:                    throw new SqlException(agent_.logWriter_,
4594:                            new ClientMessageId(
4595:                                    SQLState.CLIENT_RESULT_SET_NOT_OPEN));
4596:                } else {
4597:                    agent_.checkForDeferredExceptions();
4598:                }
4599:            }
4600:
4601:            private final void checkForUpdatableResultSet(String operation)
4602:                    throws SqlException {
4603:                if (resultSetConcurrency_ == java.sql.ResultSet.CONCUR_READ_ONLY) {
4604:                    throw new SqlException(
4605:                            agent_.logWriter_,
4606:                            new ClientMessageId(
4607:                                    SQLState.UPDATABLE_RESULTSET_API_DISALLOWED),
4608:                            operation);
4609:                }
4610:            }
4611:
4612:            private final void checkForValidCursorPosition()
4613:                    throws SqlException {
4614:                if (!isValidCursorPosition_) {
4615:                    throw new SqlException(
4616:                            agent_.logWriter_,
4617:                            new ClientMessageId(
4618:                                    SQLState.CURSOR_INVALID_OPERATION_AT_CURRENT_POSITION));
4619:                }
4620:            }
4621:
4622:            private final void checkPositionedOnPlainRow() throws SqlException {
4623:                if (isOnInsertRow_ || !isValidCursorPosition_) {
4624:                    throw new SqlException(agent_.logWriter_,
4625:                            new ClientMessageId(SQLState.NO_CURRENT_ROW));
4626:                }
4627:            }
4628:
4629:            private final void checkThatResultSetTypeIsScrollable()
4630:                    throws SqlException {
4631:                if (resultSetType_ == java.sql.ResultSet.TYPE_FORWARD_ONLY) {
4632:                    throw new SqlException(agent_.logWriter_,
4633:                            new ClientMessageId(
4634:                                    SQLState.CURSOR_MUST_BE_SCROLLABLE));
4635:                }
4636:            }
4637:
4638:            private final void checkThatResultSetIsNotDynamic()
4639:                    throws SqlException {
4640:                if (sensitivity_ == sensitivity_sensitive_dynamic__) {
4641:                    throw new SqlException(
4642:                            agent_.logWriter_,
4643:                            new ClientMessageId(
4644:                                    SQLState.CURSOR_INVALID_FOR_SENSITIVE_DYNAMIC));
4645:                }
4646:            }
4647:
4648:            private boolean resultSetContainsNoRows() throws SqlException {
4649:                if (rowCountIsUnknown()) {
4650:                    getRowCount();
4651:                }
4652:                return (rowCount_ == 0);
4653:            }
4654:
4655:            private boolean rowIsInCurrentRowset(long rowNumber, int orientation)
4656:                    throws SqlException {
4657:                if (sensitivity_ == sensitivity_sensitive_dynamic__) {
4658:                    switch (orientation) {
4659:                    case scrollOrientation_next__:
4660:                        if (isAfterLast_) {
4661:                            return false;
4662:                        } else {
4663:                            return (currentRowInRowset_ + 1 < rowsReceivedInCurrentRowset_);
4664:                        }
4665:                    case scrollOrientation_prior__:
4666:                        if (isBeforeFirst_) {
4667:                            return false;
4668:                        } else {
4669:                            return (currentRowInRowset_ - 1 >= 0);
4670:                        }
4671:                    case scrollOrientation_relative__:
4672:                        return (rowNumber < rowsReceivedInCurrentRowset_ && rowNumber >= 0);
4673:
4674:                        // for dynamic cursors, we will not be able to check whether a row is in the cache for
4675:                        // FIRST, ABSOLUTE, AND LAST
4676:                    case scrollOrientation_first__:
4677:                    case scrollOrientation_absolute__:
4678:                    case scrollOrientation_last__:
4679:                        return false;
4680:                    default:
4681:                        return false;
4682:                    }
4683:                } else {
4684:                    return rowIsInCurrentRowset(rowNumber);
4685:                }
4686:            }
4687:
4688:            private boolean rowIsInCurrentRowset(long rowNumber)
4689:                    throws SqlException {
4690:                // firstRowInRowset_ is equal to lastRowInRowset_ if there is only one row
4691:                // in the rowset or if fetchSize_ is 1.  however, return false if firstRowInRowset_
4692:                // is equal to lastRowInRowset_ and also equal to zero which means there is no
4693:                // valid row in the current rowset.
4694:                if (firstRowInRowset_ == lastRowInRowset_
4695:                        && firstRowInRowset_ == 0) {
4696:                    return false;
4697:                }
4698:                if (rowNumber >= firstRowInRowset_
4699:                        && rowNumber <= lastRowInRowset_) {
4700:                    return true;
4701:                } else {
4702:                    return false;
4703:                }
4704:            }
4705:
4706:            private void markPositionedUpdateDeletePreparedStatementsClosed() {
4707:                if (preparedStatementForUpdate_ != null) {
4708:                    preparedStatementForUpdate_.markClosed();
4709:                    preparedStatementForUpdate_ = null;
4710:                }
4711:                if (preparedStatementForDelete_ != null) {
4712:                    preparedStatementForDelete_.markClosed();
4713:                    preparedStatementForDelete_ = null;
4714:                }
4715:            }
4716:
4717:            protected void updateColumnInfoFromCache() {
4718:                // currentRowInRowset_ should never be bigger than the max value of an int,
4719:                // because we have a driver imposed limit of fetch size 1000.
4720:                cursor_.columnDataPosition_ = (int[]) cursor_.columnDataPositionCache_
4721:                        .get((int) currentRowInRowset_);
4722:                cursor_.columnDataComputedLength_ = (int[]) cursor_.columnDataLengthCache_
4723:                        .get((int) currentRowInRowset_);
4724:                cursor_.isNull_ = (boolean[]) cursor_.columnDataIsNullCache_
4725:                        .get((int) currentRowInRowset_);
4726:                cursor_.isUpdateDeleteHole_ = ((Boolean) cursor_.isUpdateDeleteHoleCache_
4727:                        .get((int) currentRowInRowset_)).booleanValue();
4728:            }
4729:
4730:            protected final void checkAndThrowReceivedQueryTerminatingException()
4731:                    throws SqlException {
4732:                // If we are in a split row, and before sending CNTQRY, check whether an ENDQRYRM
4733:                // has been received.
4734:                if (!openOnServer_) {
4735:                    SqlException sqlException = null;
4736:                    int sqlcode = org.apache.derby.client.am.Utils
4737:                            .getSqlcodeFromSqlca(queryTerminatingSqlca_);
4738:                    if (sqlcode < 0) {
4739:                        sqlException = new SqlException(agent_.logWriter_,
4740:                                queryTerminatingSqlca_);
4741:                    } else if (sqlcode > 0 && sqlcode != 100) {
4742:                        accumulateWarning(new SqlWarning(agent_.logWriter_,
4743:                                queryTerminatingSqlca_));
4744:                    }
4745:                    try {
4746:                        closeX(); // the auto commit logic is in closeX()
4747:                    } catch (SqlException e) {
4748:                        sqlException.setNextException(e);
4749:                    }
4750:                    if (sqlException != null) {
4751:                        throw sqlException;
4752:                    }
4753:                }
4754:            }
4755:
4756:            public void parseScrollableRowset() throws SqlException {
4757:                // modified check from qrydtaReturned to cursor.dataBufferHasUnprocesseData()
4758:                if (cursor_.dataBufferHasUnprocessedData() && scrollable_) {
4759:                    parseRowset_();
4760:                    adjustFirstRowset();
4761:
4762:                    // This method is only called after open query to parse out the very first rowset
4763:                    // received.
4764:                    if (cursor_.allRowsReceivedFromServer()
4765:                            && rowsReceivedInCurrentRowset_ == 0) {
4766:                        setRowsetNoRowsEvent();
4767:                    }
4768:                }
4769:            }
4770:
4771:            //  determines if a cursor is a:
4772:            //    Return to Client - not to be read by the stored procedure only by client
4773:            //    Return to Caller - only calling JSP can read it, not the client
4774:            public byte getRSReturnability() {
4775:                return rsReturnability_;
4776:            }
4777:
4778:            public void setRSReturnability(byte rsReturnability) { // valid return type set it
4779:                if ((rsReturnability == DDM_RETURN_CALLER)
4780:                        || (rsReturnability == DDM_RETURN_CLIENT)) {
4781:                    rsReturnability_ = rsReturnability;
4782:                } else { // unknown return type, set DDM_RETURN_CALLER
4783:                    rsReturnability_ = DDM_RETURN_CALLER;
4784:                }
4785:            }
4786:
4787:            //------------------------------------------------------------------------------
4788:            // Push the getXXXRowset_() methods up from the material layers
4789:            //------------------------------------------------------------------------------
4790:            // This method is called to retrieve the total number of rows in the result set
4791:            // and then reposition the cursor to where it was before.
4792:            // The rowCount_ comes back in the SQLCA in fields SQLERRD1 and SQLERRD2 when
4793:            // sqlcode is +100.
4794:            protected void getRowCount() throws SqlException {
4795:                // if already received an ENDQRYRM at open, check sqlcode and throw an exception
4796:                checkAndThrowReceivedQueryTerminatingException();
4797:
4798:                agent_.beginWriteChain(statement_);
4799:
4800:                Section section = (generatedSection_ == null) ? statement_.section_
4801:                        : generatedSection_;
4802:
4803:                // send the first CNTQRY to place cursor after last to retrieve the rowCount_.
4804:                writePositioningFetch_(section, scrollOrientation_after__, 0);
4805:                // if this is a non-dynamic rowset cursor, reposition the cursor to the first row in rowset
4806:                // after the fetch after.  Cache info and cursor positions on the client should not change.
4807:                if (isRowsetCursor_
4808:                        && sensitivity_ != sensitivity_sensitive_dynamic__
4809:                        && firstRowInRowset_ != 0) {
4810:                    writePositioningFetch_(section,
4811:                            scrollOrientation_absolute__, firstRowInRowset_);
4812:                }
4813:
4814:                agent_.flow(statement_);
4815:
4816:                readPositioningFetch_();
4817:                if (isRowsetCursor_
4818:                        && sensitivity_ != sensitivity_sensitive_dynamic__
4819:                        && firstRowInRowset_ != 0) {
4820:                    readPositioningFetch_();
4821:                }
4822:
4823:                agent_.endReadChain();
4824:
4825:                // if rowCount_ is not updated, check for exceptions
4826:                if (rowCount_ == -1) {
4827:                    checkAndThrowReceivedQueryTerminatingException();
4828:                }
4829:
4830:                if (isRowsetCursor_
4831:                        && sensitivity_ != sensitivity_sensitive_dynamic__
4832:                        && firstRowInRowset_ != 0) {
4833:                    absolutePosition_ = firstRowInRowset_;
4834:                } else {
4835:                    absolutePosition_ = (maxRows_ == 0) ? rowCount_ + 1
4836:                            : maxRows_ + 1;
4837:                }
4838:            }
4839:
4840:            private void flowGetRowset(int orientation, long rowNumber)
4841:                    throws SqlException {
4842:                // clear lobs before fetching rows
4843:                cursor_.clearLobData_();
4844:                cursor_.resetDataBuffer();
4845:                agent_.beginWriteChain(statement_);
4846:
4847:                writeScrollableFetch_(
4848:                        (generatedSection_ == null) ? statement_.section_
4849:                                : generatedSection_, fetchSize_, orientation,
4850:                        rowNumber, true); // true means to discard any pending partial
4851:                // row and pending query blocks
4852:
4853:                // reset the number of rows received to 0.
4854:                // cannot use rowsRead_ here because this is reset every time a new rowset is fetched
4855:                rowsReceivedInCurrentRowset_ = 0;
4856:
4857:                agent_.flow(statement_);
4858:                readScrollableFetch_();
4859:                agent_.endReadChain();
4860:            }
4861:
4862:            private boolean getNextRowset() throws SqlException {
4863:                // for rowset cursors or dynamic, non-rowset cursors
4864:                if (isRowsetCursor_
4865:                        || sensitivity_ == sensitivity_sensitive_dynamic__) {
4866:                    // check if the next row contains a +100 before fetching from the server.
4867:                    // since index starts from 0, the actual row number for the current row is (currentRowInRowset_+1)
4868:                    // and the actual row number for the next row is (currentRowInRowset_+2)
4869:                    int sqlcode = checkRowsetSqlca((int) currentRowInRowset_ + 2);
4870:                    if (sqlcode == 100) {
4871:                        isAfterLast_ = true;
4872:                        return false;
4873:                    }
4874:                    flowGetRowset(scrollOrientation_next__, 0);
4875:                } else {
4876:                    // for all other cursors:
4877:                    //   sensitive static, insensitive, non-rowset cursors
4878:                    // if already afterLast, return false
4879:                    // if already on the last row and have received a +100, do not fetch again, return false
4880:                    if (resultSetContainsNoRows() || isAfterLastX()) {
4881:                        return false;
4882:                    } else if (firstRowInRowset_ + currentRowInRowset_ == lastRowInRowset_
4883:                            && cursor_.allRowsReceivedFromServer()) {
4884:                        isAfterLast_ = true;
4885:                        setRowsetAfterLastEvent();
4886:                        return false;
4887:                    }
4888:
4889:                    // rowNumber to fetch is 1 if absolute position is equal to the last row
4890:                    // in the rowset
4891:                    long rowNumber = 1;
4892:                    int orientation = scrollOrientation_relative__;
4893:
4894:                    // Normally absolute position is equal to last row in the rowset, but in cases
4895:                    // of previous "update where current of"s, absolute position may be somewhere
4896:                    // else in the current rowset, thus rowNumber needs to be recalculated based on
4897:                    // where in the rowset the absolute position is.
4898:                    if (absolutePosition_ < lastRowInRowset_) {
4899:                        rowNumber = lastRowInRowset_ - absolutePosition_ + 1;
4900:                        absolutePosition_ = lastRowInRowset_;
4901:                    }
4902:                    // the following case happens when a getRowCount() is called and we flow a fetch after
4903:                    // to get the rowCount.
4904:                    else if (absolutePosition_ > lastRowInRowset_) {
4905:                        rowNumber = lastRowInRowset_ + 1;
4906:                        orientation = scrollOrientation_absolute__;
4907:                    }
4908:
4909:                    flowGetRowset(orientation, rowNumber);
4910:                }
4911:
4912:                parseRowset_();
4913:
4914:                // If no row was received but received sqlcode +100, then the cursor is
4915:                // positioned after last.
4916:                if (rowsReceivedInCurrentRowset_ == 0
4917:                        && cursor_.allRowsReceivedFromServer()) {
4918:                    isAfterLast_ = true;
4919:                    setRowsetAfterLastEvent();
4920:                    return false;
4921:                }
4922:
4923:                // adjust the cursor positions for sensitive static or insensitive cursors only
4924:                if (sensitivity_ != sensitivity_sensitive_dynamic__) {
4925:                    adjustNextRowset();
4926:                }
4927:                currentRowInRowset_ = 0;
4928:                return true;
4929:            }
4930:
4931:            private void adjustNextRowset() {
4932:                firstRowInRowset_ = lastRowInRowset_ + 1;
4933:                lastRowInRowset_ = lastRowInRowset_
4934:                        + rowsReceivedInCurrentRowset_;
4935:                setAbsolutePositionBasedOnAllRowsReceived();
4936:                //currentRowInRowset_ = 0;
4937:            }
4938:
4939:            private boolean getPreviousRowset() throws SqlException {
4940:                int orientation = scrollOrientation_relative__;
4941:                long rowNumber = 0;
4942:                boolean isAfterLast = false;
4943:
4944:                // for rowset cursors or dynamic, non-rowset cursors
4945:                if (isRowsetCursor_
4946:                        || sensitivity_ == sensitivity_sensitive_dynamic__) {
4947:                    // check if we already received a +20237 before fetching from the server.
4948:                    if (currentRowInRowset_ == 0 && rowsetSqlca_ != null
4949:                            && rowsetSqlca_[0] != null
4950:                            && rowsetSqlca_[0].getSqlCode() == 20237) {
4951:                        isBeforeFirst_ = true;
4952:                        setRowsetBeforeFirstEvent();
4953:                        return false;
4954:                    }
4955:                    flowGetRowset(scrollOrientation_prior__, 0);
4956:                } else {
4957:                    // for all other cursors:
4958:                    //   sensitive static, insensitive, non-rowset cursors
4959:                    if (resultSetContainsNoRows() || isBeforeFirstX()) {
4960:                        return false;
4961:                    }
4962:                    rowNumber = firstRowInRowset_ - absolutePosition_
4963:                            - fetchSize_;
4964:                    isAfterLast = isAfterLastX();
4965:                    if (isFirstX()) {
4966:                        rowNumber = 0;
4967:                        orientation = scrollOrientation_absolute__;
4968:                    }
4969:                    // If the cursor is after last, fetch the last rowset which includes the last row.
4970:                    else if (isAfterLast) {
4971:                        rowNumber = (-1) * fetchSize_;
4972:                    }
4973:                    // if the distance from the absolute position is less than fetch size, fetch from row 1
4974:                    if (rowNumber * (-1) >= absolutePosition_) {
4975:                        rowNumber = 1;
4976:                        orientation = scrollOrientation_absolute__;
4977:                    }
4978:
4979:                    // If afterLast and maxRows > 0, go backward from maxRows and not 
4980:                    // from last row in the resultSet
4981:                    if (maxRows_ > 0
4982:                            && orientation == scrollOrientation_relative__
4983:                            && isAfterLast) {
4984:                        rowNumber += maxRows_ + 1;
4985:                        orientation = scrollOrientation_absolute__;
4986:                    }
4987:
4988:                    flowGetRowset(orientation, rowNumber);
4989:                }
4990:
4991:                parseRowset_();
4992:
4993:                // If no row was received but received sqlcode +100, then the cursor is
4994:                // positioned before first.
4995:                if (rowsReceivedInCurrentRowset_ == 0
4996:                        && cursor_.allRowsReceivedFromServer()) {
4997:                    isBeforeFirst_ = true;
4998:                    setRowsetBeforeFirstEvent();
4999:                    return false;
5000:                }
5001:
5002:                // adjust the cursor positions for sensitive static or insensitive cursors only
5003:                if (sensitivity_ != sensitivity_sensitive_dynamic__) {
5004:                    adjustPreviousRowset(orientation, rowNumber, isAfterLast);
5005:                } else {
5006:                    currentRowInRowset_ = rowsReceivedInCurrentRowset_ - 1;
5007:                }
5008:                return true;
5009:            }
5010:
5011:            private void adjustPreviousRowset(int orientation, long rowNumber,
5012:                    boolean isAfterLastRow) throws SqlException {
5013:                if (orientation == scrollOrientation_absolute__
5014:                        && rowNumber == 1) {
5015:                    // Subtracting 2 because the currentRowInRowset_ index starts at 0, and all
5016:                    // the other indexes starts at 1.
5017:                    currentRowInRowset_ = (isAfterLastRow) ? absolutePosition_ - 2
5018:                            : firstRowInRowset_ - 2;
5019:                    firstRowInRowset_ = 1;
5020:                    lastRowInRowset_ = rowsReceivedInCurrentRowset_;
5021:                    absolutePosition_ = (isAfterLastRow) ? lastRowInRowset_ + 1
5022:                            : lastRowInRowset_;
5023:                } else {
5024:                    if (maxRows_ == 0)
5025:                        lastRowInRowset_ = (isAfterLastRow) ? rowCount_
5026:                                : firstRowInRowset_ - 1;
5027:                    else
5028:                        lastRowInRowset_ = (isAfterLastRow) ? maxRows_
5029:                                : firstRowInRowset_ - 1;
5030:                    firstRowInRowset_ = lastRowInRowset_
5031:                            - rowsReceivedInCurrentRowset_ + 1;
5032:                    absolutePosition_ = lastRowInRowset_;
5033:                    currentRowInRowset_ = lastRowInRowset_ - firstRowInRowset_;
5034:                }
5035:            }
5036:
5037:            private boolean getAbsoluteRowset(long row) throws SqlException {
5038:                int orientation = scrollOrientation_absolute__;
5039:                // absolute(0) is not allowed on a rowset cursor, will get -644 from the server
5040:                // remap to fetch before.
5041:                if (isRowsetCursor_ && row == 0) {
5042:                    orientation = scrollOrientation_before__;
5043:                } else if (sensitivity_ != sensitivity_sensitive_dynamic__
5044:                        && row < 0) {
5045:                    row = 0;
5046:                }
5047:
5048:                flowGetRowset(orientation, row);
5049:                parseRowset_();
5050:
5051:                // If no row was received but received sqlcode +100, then the cursor is
5052:                // positioned after last or before first.
5053:                if ((rowsReceivedInCurrentRowset_ == 0 && cursor_
5054:                        .allRowsReceivedFromServer())
5055:                        || orientation == scrollOrientation_before__) {
5056:                    if (row > 0) {
5057:                        setRowsetAfterLastEvent();
5058:                        isAfterLast_ = true;
5059:                    } else {
5060:                        setRowsetBeforeFirstEvent();
5061:                        isBeforeFirst_ = true;
5062:                    }
5063:                    return false;
5064:                }
5065:
5066:                // adjust the cursor positions for sensitive static or insensitive cursors only
5067:                if (sensitivity_ != sensitivity_sensitive_dynamic__) {
5068:                    adjustAbsoluteRowset(row);
5069:                }
5070:                currentRowInRowset_ = 0;
5071:                return true;
5072:            }
5073:
5074:            private void adjustAbsoluteRowset(long rowNumber) {
5075:                firstRowInRowset_ = rowNumber;
5076:                lastRowInRowset_ = firstRowInRowset_
5077:                        + rowsReceivedInCurrentRowset_ - 1;
5078:                setAbsolutePositionBasedOnAllRowsReceived();
5079:                //currentRowInRowset_ = 0;
5080:            }
5081:
5082:            private boolean getRelativeRowset(long rows) throws SqlException {
5083:                if (rows == 0
5084:                        && (cursor_.allRowsReceivedFromServer() || absolutePosition_ > rowCount_)) {
5085:                    setRowsetAfterLastEvent();
5086:                    isAfterLast_ = true;
5087:                    return false;
5088:                }
5089:
5090:                flowGetRowset(scrollOrientation_relative__, rows);
5091:                parseRowset_();
5092:
5093:                if (rowsReceivedInCurrentRowset_ == 0
5094:                        && cursor_.allRowsReceivedFromServer()) {
5095:                    if (rows > 0) {
5096:                        setRowsetAfterLastEvent();
5097:                        isAfterLast_ = true;
5098:                    } else {
5099:                        setRowsetBeforeFirstEvent();
5100:                        isBeforeFirst_ = true;
5101:                    }
5102:                    return false;
5103:                }
5104:
5105:                // adjust the cursor positions for sensitive static or insensitive cursors only
5106:                if (sensitivity_ != sensitivity_sensitive_dynamic__) {
5107:                    adjustRelativeRowset(rows);
5108:                }
5109:                currentRowInRowset_ = 0;
5110:                return true;
5111:            }
5112:
5113:            private void adjustRelativeRowset(long rowNumber) {
5114:                firstRowInRowset_ = absolutePosition_ + rowNumber;
5115:                lastRowInRowset_ = firstRowInRowset_
5116:                        + rowsReceivedInCurrentRowset_ - 1;
5117:                setAbsolutePositionBasedOnAllRowsReceived();
5118:            }
5119:
5120:            private boolean getFirstRowset() throws SqlException {
5121:                flowGetRowset(scrollOrientation_absolute__, 1);
5122:                parseRowset_();
5123:
5124:                // If no row was received but received sqlcode +100, then no row in the result set
5125:                if (rowsReceivedInCurrentRowset_ == 0
5126:                        && cursor_.allRowsReceivedFromServer()) {
5127:                    resetRowsetFlags();
5128:                    this .setRowsetNoRowsEvent();
5129:                    return false;
5130:                }
5131:
5132:                // adjust the cursor positions for sensitive static or insensitive cursors only
5133:                if (sensitivity_ != sensitivity_sensitive_dynamic__) {
5134:                    adjustFirstRowset();
5135:                }
5136:                currentRowInRowset_ = 0;
5137:                return true;
5138:            }
5139:
5140:            private void adjustFirstRowset() {
5141:                firstRowInRowset_ = 1;
5142:                lastRowInRowset_ = rowsReceivedInCurrentRowset_;
5143:                setAbsolutePositionBasedOnAllRowsReceived();
5144:                //currentRowInRowset_ = 0;
5145:            }
5146:
5147:            private boolean getLastRowset(long row) throws SqlException {
5148:                if (sensitivity_ != sensitivity_sensitive_dynamic__
5149:                        && rowCount_ == 0) {
5150:                    isAfterLast_ = false;
5151:                    isBeforeFirst_ = false;
5152:                    setRowsetNoRowsEvent();
5153:                    return false;
5154:                } else if (isRowsetCursor_
5155:                        || sensitivity_ == sensitivity_sensitive_dynamic__) {
5156:                    flowGetRowset(scrollOrientation_last__, 0);
5157:                } else {
5158:                    // If fetchSize_ is smaller than the total number of rows in the ResultSet,
5159:                    // then fetch one rowset of fetchSize_ number of rows.  Otherwise, we will
5160:                    // fetch all rows in the ResultSet, so start fetching from row 1.
5161:                    long rowNumber;
5162:                    if (maxRows_ == 0) {
5163:                        rowNumber = (fetchSize_ < row) ? ((-1) * fetchSize_)
5164:                                : 1;
5165:                    } else {
5166:                        rowNumber = (fetchSize_ < row) ? (maxRows_ - fetchSize_) + 1
5167:                                : 1;
5168:                    }
5169:                    flowGetRowset(scrollOrientation_absolute__, rowNumber);
5170:                }
5171:                parseRowset_();
5172:
5173:                if (rowsReceivedInCurrentRowset_ == 0
5174:                        && cursor_.allRowsReceivedFromServer()) {
5175:                    isAfterLast_ = true;
5176:                    setRowsetAfterLastEvent();
5177:                    return false;
5178:                }
5179:
5180:                // adjust the cursor positions for sensitive static or insensitive cursors only
5181:                if (sensitivity_ != sensitivity_sensitive_dynamic__) {
5182:                    adjustLastRowset(row);
5183:                } else {
5184:                    currentRowInRowset_ = rowsReceivedInCurrentRowset_ - 1;
5185:                }
5186:                return true;
5187:            }
5188:
5189:            private void adjustLastRowset(long row) {
5190:                lastRowInRowset_ = row;
5191:                firstRowInRowset_ = lastRowInRowset_
5192:                        - rowsReceivedInCurrentRowset_ + 1;
5193:                if (firstRowInRowset_ <= 0) {
5194:                    firstRowInRowset_ = 1;
5195:                }
5196:                setAbsolutePositionBasedOnAllRowsReceived();
5197:                currentRowInRowset_ = lastRowInRowset_ - firstRowInRowset_;
5198:            }
5199:
5200:            private boolean getRefreshRowset() throws SqlException {
5201:                if (isRowsetCursor_) {
5202:                    flowGetRowset(scrollOrientation_current__, 0);
5203:                } else {
5204:                    flowGetRowset(scrollOrientation_relative__, (-1)
5205:                            * (absolutePosition_ - firstRowInRowset_));
5206:                }
5207:
5208:                parseRowset_();
5209:
5210:                // Rowset indexes do not change when rowset is refreshed.
5211:                // The only exception is absolutePosition_.  It may be different after the refresh.
5212:                if (sensitivity_ != sensitivity_sensitive_dynamic__) {
5213:                    adjustRefreshRowset();
5214:                }
5215:                return true;
5216:            }
5217:
5218:            private void adjustRefreshRowset() {
5219:                setAbsolutePositionBasedOnAllRowsReceived();
5220:                updateColumnInfoFromCache();
5221:            }
5222:
5223:            private void setAbsolutePositionBasedOnAllRowsReceived() {
5224:                absolutePosition_ = (cursor_.allRowsReceivedFromServer()) ? lastRowInRowset_ + 1
5225:                        : lastRowInRowset_;
5226:            }
5227:
5228:            // ------------------------------- abstract box car methods --------------------------------------
5229:            public abstract void writeFetch_(Section section)
5230:                    throws SqlException;
5231:
5232:            public abstract void readFetch_() throws SqlException;
5233:
5234:            public abstract void writeScrollableFetch_(Section section,
5235:                    int fetchSize, // need to send fetchSize in case when we get an
5236:                    // incomplete rowset, the fetchSize is the remaining
5237:                    // number of the rows in the rowset.
5238:                    int orientation, long rowToFetch, boolean resetQueryBlocks)
5239:                    throws SqlException;
5240:
5241:            public abstract void readScrollableFetch_() throws SqlException;
5242:
5243:            public abstract void writePositioningFetch_(Section section,
5244:                    int orientation, long rowToFetch) throws SqlException;
5245:
5246:            public abstract void readPositioningFetch_() throws SqlException;
5247:
5248:            public abstract void writeCursorClose_(Section section)
5249:                    throws SqlException;
5250:
5251:            public abstract void readCursorClose_() throws SqlException;
5252:
5253:            protected abstract void parseRowset_() throws SqlException;
5254:
5255:            public abstract void setFetchSize_(int rows);
5256:
5257:            /**
5258:             * Method that is invoked by <code>closeX()</code> before the
5259:             * result set is actually being closed. Subclasses may override
5260:             * this method if work needs to be done before closing.
5261:             *
5262:             * @exception SqlException
5263:             */
5264:            protected abstract void preClose_() throws SqlException;
5265:
5266:            public ConnectionCallbackInterface getConnectionCallbackInterface() {
5267:                return connection_;
5268:            }
5269:
5270:            public StatementCallbackInterface getStatementCallbackInterface() {
5271:                return statement_;
5272:            }
5273:
5274:            public void expandRowsetSqlca() {
5275:                // rowsetSqlca_ index starts from 1.  entry 0 is reserved for warning +20237
5276:                // if rowset size is n, then the (n+1)th entry is reserved for the +100 if one is received.
5277:                // thus the size of the rowsetSqlca_ needs to be fetchSize_+2
5278:                if (isRowsetCursor_
5279:                        && (rowsetSqlca_ == null || rowsetSqlca_.length < fetchSize_ + 2)) {
5280:                    rowsetSqlca_ = new Sqlca[fetchSize_ + 2];
5281:                }
5282:            }
5283:
5284:            private final int checkRowsetSqlca() throws SqlException {
5285:                return checkRowsetSqlca((int) currentRowInRowset_ + 1);
5286:            }
5287:
5288:            private final int checkRowsetSqlca(int row) throws SqlException {
5289:                int sqlcode = 0;
5290:                if (!isRowsetCursor_ || rowsetSqlca_ == null
5291:                        || rowsetSqlca_[row] == null) {
5292:                    warnings_ = null; // clear any previous warnings
5293:                    return sqlcode;
5294:                }
5295:
5296:                Sqlca sqlca = rowsetSqlca_[row];
5297:                if (sqlca != null) {
5298:                    sqlcode = sqlca.getSqlCode();
5299:                    if (sqlcode < 0) {
5300:                        throw new SqlException(agent_.logWriter_, sqlca);
5301:                    } else if (sqlcode > 0
5302:                            && (sqlcode != 100 && sqlcode != +20237)) {
5303:                        accumulateWarning(new SqlWarning(agent_.logWriter_,
5304:                                sqlca));
5305:                    }
5306:                }
5307:                return sqlcode;
5308:            }
5309:
5310:            private void resetRowsetFlags() {
5311:                isBeforeFirst_ = false;
5312:                isAfterLast_ = false;
5313:                isFirst_ = false;
5314:                isLast_ = false;
5315:            }
5316:
5317:            private void resetRowsetSqlca() {
5318:                if (rowsetSqlca_ != null) {
5319:                    for (int i = 0; i < rowsetSqlca_.length; i++) {
5320:                        rowsetSqlca_[i] = null;
5321:                    }
5322:                }
5323:            }
5324:
5325:            private CloseFilterInputStream createCloseFilterInputStream(
5326:                    java.io.InputStream is) throws SqlException {
5327:
5328:                if (is == null) {
5329:                    return null;
5330:                }
5331:
5332:                if (is_ == is) {
5333:                    return is_;
5334:                }
5335:
5336:                closeCloseFilterInputStream();
5337:
5338:                is_ = new CloseFilterInputStream(is);
5339:
5340:                return is_;
5341:
5342:            }
5343:
5344:            private void closeCloseFilterInputStream() throws SqlException {
5345:
5346:                if (is_ != null) {
5347:                    try {
5348:                        is_.close();
5349:
5350:                    } catch (IOException e) {
5351:                        throw new SqlException(agent_.logWriter_,
5352:                                new ClientMessageId(SQLState.JAVA_EXCEPTION),
5353:                                "java.io.IOException", e.getMessage(), e);
5354:                    }
5355:
5356:                    is_ = null;
5357:
5358:                }
5359:            }
5360:
5361:            void useStream(int columnIndex) throws SqlException {
5362:
5363:                if (streamUsedFlags_[columnIndex - 1]) {
5364:                    throw new SqlException(agent_.logWriter_,
5365:                            new ClientMessageId(
5366:                                    SQLState.LANG_STREAM_RETRIEVED_ALREADY));
5367:                }
5368:
5369:                streamUsedFlags_[columnIndex - 1] = true;
5370:
5371:            }
5372:
5373:            private void unuseStreams() {
5374:
5375:                if (streamUsedFlags_ == null) {
5376:                    streamUsedFlags_ = new boolean[resultSetMetaData_.columns_];
5377:                    return;
5378:                }
5379:
5380:                for (int i = 0; i < streamUsedFlags_.length; i++) {
5381:
5382:                    streamUsedFlags_[i] = false;
5383:
5384:                }
5385:
5386:            }
5387:
5388:            private SQLException jdbc3MethodNotSupported() {
5389:                return new SqlException(agent_.logWriter_, new ClientMessageId(
5390:                        SQLState.JDBC_METHOD_NOT_IMPLEMENTED))
5391:                        .getSQLException();
5392:            }
5393:
5394:            // -------------------------- JDBC 4.0 --------------------------
5395:
5396:            /**
5397:             * Retrieves the holdability for this <code>ResultSet</code>
5398:             * object.
5399:             *
5400:             * @return either <code>ResultSet.HOLD_CURSORS_OVER_COMMIT</code>
5401:             * or <code>ResultSet.CLOSE_CURSORS_AT_COMMIT</code>
5402:             * @exception SQLException if a database error occurs
5403:             */
5404:            public final int getHoldability() throws SQLException {
5405:                if (agent_.loggingEnabled()) {
5406:                    agent_.logWriter_.traceEntry(this , "getHoldability");
5407:                }
5408:                try {
5409:                    checkForClosedResultSet();
5410:                } catch (SqlException se) {
5411:                    throw se.getSQLException();
5412:                }
5413:                if (agent_.loggingEnabled()) {
5414:                    agent_.logWriter_.traceExit(this , "getHoldability",
5415:                            resultSetHoldability_);
5416:                }
5417:                return resultSetHoldability_;
5418:            }
5419:
5420:            /**
5421:             * Checks whether this <code>ResultSet</code> object has been
5422:             * closed, either automatically or because <code>close()</code>
5423:             * has been called.
5424:             *
5425:             * @return <code>true</code> if the <code>ResultSet</code> is
5426:             * closed, <code>false</code> otherwise
5427:             * @exception SQLException if a database error occurs
5428:             */
5429:            public final boolean isClosed() throws SQLException {
5430:                if (agent_.loggingEnabled()) {
5431:                    agent_.logWriter_.traceEntry(this , "isClosed");
5432:                }
5433:                final boolean isClosed = !openOnClient_;
5434:                if (agent_.loggingEnabled()) {
5435:                    agent_.logWriter_.traceExit(this , "isClosed", isClosed);
5436:                }
5437:                return isClosed;
5438:            }
5439:
5440:            /**
5441:             * Updates the designated column with an ascii stream value.
5442:             * The data will be read from the stream as needed until end-of-stream is
5443:             * reached.
5444:             *
5445:             * The updater methods are used to update column values in the current row
5446:             * or the insert row. The updater methods do not update the underlying
5447:             * database; instead the <code>updateRow</code> or <code>insertRow</code>
5448:             * methods are called to update the database.
5449:             *
5450:             * @param columnIndex the first column is 1, the second is 2, ...
5451:             * @param x the new column value
5452:             * @throws SQLException if the columnIndex is not valid; if a database
5453:             *      access error occurs; the result set concurrency is
5454:             *      <code>CONCUR_READ_ONLY</code> or this method is called on a closed
5455:             *      result set
5456:             */
5457:            public void updateAsciiStream(int columnIndex, InputStream x)
5458:                    throws SQLException {
5459:                synchronized (connection_) {
5460:                    if (agent_.loggingEnabled()) {
5461:                        agent_.logWriter_.traceEntry(this , "updateAsciiStream",
5462:                                columnIndex, x);
5463:                    }
5464:                    try {
5465:                        checkUpdatePreconditions(columnIndex,
5466:                                "updateAsciiStream");
5467:                        updateColumn(
5468:                                columnIndex,
5469:                                agent_.crossConverters_
5470:                                        .setObjectFromCharacterStream(
5471:                                                resultSetMetaData_.types_[columnIndex - 1],
5472:                                                x, "US-ASCII",
5473:                                                CrossConverters.UNKNOWN_LENGTH));
5474:                    } catch (SqlException se) {
5475:                        throw se.getSQLException();
5476:                    }
5477:                }
5478:            }
5479:
5480:            /**
5481:             * Update a column with an ascii stream value.
5482:             *
5483:             * The updateXXX() methods are used to update column values in the current
5484:             * row, or the insert row. The updateXXX() methods do not update the
5485:             * underlying database, instead the updateRow() or insertRow() methods are
5486:             * called to update the database.
5487:             *
5488:             * @param columnIndex
5489:             *            the first column is 1, the second is 2, ...
5490:             * @param x
5491:             *            the new column value
5492:             * @param length
5493:             *            the length of the stream
5494:             * @exception SQLException
5495:             *                if a database-access error occurs
5496:             */
5497:            public void updateAsciiStream(int columnIndex, InputStream x,
5498:                    long length) throws SQLException {
5499:                if (length > Integer.MAX_VALUE)
5500:                    throw new SqlException(
5501:                            agent_.logWriter_,
5502:                            new ClientMessageId(
5503:                                    SQLState.CLIENT_LENGTH_OUTSIDE_RANGE_FOR_DATATYPE),
5504:                            new Long(length), new Integer(Integer.MAX_VALUE))
5505:                            .getSQLException();
5506:                else
5507:                    updateAsciiStream(columnIndex, x, (int) length);
5508:            }
5509:
5510:            /**
5511:             * Updates the designated column with a binary stream value.
5512:             * The data will be read from the stream as needed until end-of-stream is
5513:             * reached.
5514:             *
5515:             * The updater methods are used to update column values in the current row
5516:             * or the insert row. The updater methods do not update the underlying
5517:             * database; instead the <code>updateRow</code> or <code>insertRow</code>
5518:             * methods are called to update the database.
5519:             *
5520:             * @param columnIndex the first column is 1, the second is 2, ...
5521:             * @param x the new column value 
5522:             * @throws SQLException if the columnIndex is not valid; if a database
5523:             *      access error occurs; the result set concurrency is
5524:             *      <code>CONCUR_READ_ONLY</code> or this method is called on a closed
5525:             *      result set
5526:             */
5527:            public void updateBinaryStream(int columnIndex, InputStream x)
5528:                    throws SQLException {
5529:                synchronized (connection_) {
5530:                    if (agent_.loggingEnabled()) {
5531:                        agent_.logWriter_.traceEntry(this ,
5532:                                "updateBinaryStream", columnIndex, x);
5533:                    }
5534:                    try {
5535:                        checkUpdatePreconditions(columnIndex,
5536:                                "updateBinaryStream");
5537:                        updateColumn(
5538:                                columnIndex,
5539:                                agent_.crossConverters_
5540:                                        .setObjectFromBinaryStream(
5541:                                                resultSetMetaData_.types_[columnIndex - 1],
5542:                                                x,
5543:                                                CrossConverters.UNKNOWN_LENGTH));
5544:                    } catch (SqlException se) {
5545:                        throw se.getSQLException();
5546:                    }
5547:                }
5548:            }
5549:
5550:            /**
5551:             * Update a column with a binary stream value.
5552:             *
5553:             * The updateXXX() methods are used to update column values in the current
5554:             * row, or the insert row. The updateXXX() methods do not update the
5555:             * underlying database, instead the updateRow() or insertRow() methods are
5556:             * called to update the database.
5557:             *
5558:             * @param columnIndex
5559:             *            the first column is 1, the second is 2, ...
5560:             * @param x
5561:             *            the new column value
5562:             * @param length
5563:             *            the length of the stream
5564:             * @exception SQLException
5565:             *                if a database-access error occurs
5566:             */
5567:            public void updateBinaryStream(int columnIndex, InputStream x,
5568:                    long length) throws SQLException {
5569:                if (length > Integer.MAX_VALUE)
5570:                    throw new SqlException(
5571:                            agent_.logWriter_,
5572:                            new ClientMessageId(
5573:                                    SQLState.CLIENT_LENGTH_OUTSIDE_RANGE_FOR_DATATYPE),
5574:                            new Long(length), new Integer(Integer.MAX_VALUE))
5575:                            .getSQLException();
5576:                else
5577:                    updateBinaryStream(columnIndex, x, (int) length);
5578:
5579:            }
5580:
5581:            /**
5582:             * Updates the designated column using the given input stream.
5583:             * The data will be read from the stream as needed until end-of-stream is
5584:             * reached.
5585:             *
5586:             * The updater methods are used to update column values in the current row
5587:             * or the insert row. The updater methods do not update the underlying
5588:             * database; instead the <code>updateRow</code> or <code>insertRow</code>
5589:             * methods are called to update the database.
5590:             *
5591:             * @param columnIndex the first column is 1, the second is 2, ...
5592:             * @param x the new column value
5593:             * @throws SQLException if the columnIndex is not valid; if a database
5594:             *      access error occurs; the result set concurrency is
5595:             *      <code>CONCUR_READ_ONLY</code> or this method is called on a closed
5596:             *      result set
5597:             */
5598:            public void updateBlob(int columnIndex, InputStream x)
5599:                    throws SQLException {
5600:                synchronized (connection_) {
5601:                    if (agent_.loggingEnabled()) {
5602:                        agent_.logWriter_.traceEntry(this , "updateBlob",
5603:                                columnIndex, x);
5604:                    }
5605:                    try {
5606:                        checkUpdatePreconditions(columnIndex, "updateBlob");
5607:                        updateColumn(
5608:                                columnIndex,
5609:                                agent_.crossConverters_
5610:                                        .setObject(
5611:                                                resultSetMetaData_.types_[columnIndex - 1],
5612:                                                new Blob(agent_, x)));
5613:                    } catch (SqlException se) {
5614:                        throw se.getSQLException();
5615:                    }
5616:                }
5617:            }
5618:
5619:            /**
5620:             * Updates the designated column with a character stream value.
5621:             * The data will be read from the stream as needed until end-of-stream is
5622:             * reached.
5623:             *
5624:             * The updater methods are used to update column values in the current row
5625:             * or the insert row. The updater methods do not update the underlying
5626:             * database; instead the <code>updateRow</code> or <code>insertRow</code>
5627:             * methods are called to update the database.
5628:             *
5629:             * @param columnIndex the first column is 1, the second is 2, ...
5630:             * @param reader the new column value
5631:             * @throws SQLException if the columnLabel is not valid; if a database
5632:             *      access error occurs; the result set concurrency is
5633:             *      <code>CONCUR_READ_ONLY</code> or this method is called on a closed
5634:             *      result set
5635:             */
5636:            public void updateCharacterStream(int columnIndex, Reader reader)
5637:                    throws SQLException {
5638:                synchronized (connection_) {
5639:                    try {
5640:                        if (agent_.loggingEnabled()) {
5641:                            agent_.logWriter_.traceEntry(this ,
5642:                                    "updateCharacterStream", columnIndex,
5643:                                    reader);
5644:                        }
5645:                        checkUpdatePreconditions(columnIndex,
5646:                                "updateCharacterStream");
5647:                        updateColumn(
5648:                                columnIndex,
5649:                                agent_.crossConverters_
5650:                                        .setObject(
5651:                                                resultSetMetaData_.types_[columnIndex - 1],
5652:                                                reader,
5653:                                                CrossConverters.UNKNOWN_LENGTH));
5654:                    } catch (SqlException se) {
5655:                        throw se.getSQLException();
5656:                    }
5657:                }
5658:            }
5659:
5660:            /**
5661:             * Update a column with a character stream value.
5662:             *
5663:             * The updateXXX() methods are used to update column values in the current
5664:             * row, or the insert row. The updateXXX() methods do not update the
5665:             * underlying database, instead the updateRow() or insertRow() methods are
5666:             * called to update the database.
5667:             *
5668:             * @param columnIndex
5669:             *            the first column is 1, the second is 2, ...
5670:             * @param x
5671:             *            the new column value
5672:             * @param length
5673:             *            the length of the stream
5674:             * @exception SQLException
5675:             *                if a database-access error occurs
5676:             */
5677:            public void updateCharacterStream(int columnIndex, Reader x,
5678:                    long length) throws SQLException {
5679:                if (length > Integer.MAX_VALUE)
5680:                    throw new SqlException(
5681:                            agent_.logWriter_,
5682:                            new ClientMessageId(
5683:                                    SQLState.CLIENT_LENGTH_OUTSIDE_RANGE_FOR_DATATYPE),
5684:                            new Long(length), new Integer(Integer.MAX_VALUE))
5685:                            .getSQLException();
5686:                else
5687:                    updateCharacterStream(columnIndex, x, (int) length);
5688:            }
5689:
5690:            /**
5691:             * Updates the designated column using the given <code>Reader</code>
5692:             * object. 
5693:             * The data will be read from the stream as needed until end-of-stream is
5694:             * reached. The JDBC driver will do any necessary conversion from UNICODE
5695:             * to the database char format.
5696:             *
5697:             * The updater methods are used to update column values in the current row
5698:             * or the insert row. The updater methods do not update the underlying
5699:             * database; instead the <code>updateRow</code> or <code>insertRow</code>
5700:             * methods are called to update the database.
5701:             *
5702:             * @param columnIndex the first column is 1, the second is 2, ...
5703:             * @param reader an object that contains the data to set the parameter
5704:             *      value to. 
5705:             * @throws SQLException if the columnIndex is not valid; if a database
5706:             *      access error occurs; the result set concurrency is
5707:             *      <code>CONCUR_READ_ONLY</code> or this method is called on a closed
5708:             *      result set
5709:             */
5710:            public void updateClob(int columnIndex, Reader reader)
5711:                    throws SQLException {
5712:                synchronized (connection_) {
5713:                    if (agent_.loggingEnabled()) {
5714:                        agent_.logWriter_.traceEntry(this , "updateClob",
5715:                                columnIndex, reader);
5716:                    }
5717:                    try {
5718:                        checkUpdatePreconditions(columnIndex, "updateClob");
5719:                        updateColumn(
5720:                                columnIndex,
5721:                                agent_.crossConverters_
5722:                                        .setObject(
5723:                                                resultSetMetaData_.types_[columnIndex - 1],
5724:                                                new Clob(agent_, reader)));
5725:                    } catch (SqlException se) {
5726:                        throw se.getSQLException();
5727:                    }
5728:                }
5729:            }
5730:
5731:            /**
5732:             * Updates the designated column with an ascii stream value.
5733:             * The data will be read from the stream as needed until end-of-stream is
5734:             * reached.
5735:             *
5736:             * The updater methods are used to update column values in the current row
5737:             * or the insert row. The updater methods do not update the underlying
5738:             * database; instead the <code>updateRow</code> or <code>insertRow</code>
5739:             * methods are called to update the database.
5740:             *
5741:             * @param columnName the label for the column specified with the SQL AS
5742:             *      clause. If the SQL AS clause was not specified, then the label is
5743:             *      the name of the column
5744:             * @param x the new column value
5745:             * @throws SQLException if the columnLabel is not valid; if a database
5746:             *      access error occurs; the result set concurrency is
5747:             *      <code>CONCUR_READ_ONLY</code> or this method is called on a closed
5748:             *      result set
5749:             */
5750:            public void updateAsciiStream(String columnName, InputStream x)
5751:                    throws SQLException {
5752:                try {
5753:                    updateAsciiStream(findColumnX(columnName), x);
5754:                } catch (SqlException se) {
5755:                    throw se.getSQLException();
5756:                }
5757:            }
5758:
5759:            /**
5760:             * Update a column with an ascii stream value.
5761:             *
5762:             * The updateXXX() methods are used to update column values in the current
5763:             * row, or the insert row. The updateXXX() methods do not update the
5764:             * underlying database, instead the updateRow() or insertRow() methods are
5765:             * called to update the database.
5766:             *
5767:             * @param columnName
5768:             *            the name of the column
5769:             * @param x
5770:             *            the new column value
5771:             * @param length
5772:             *            of the stream
5773:             * @exception SQLException
5774:             *                if a database-access error occurs
5775:             */
5776:            public void updateAsciiStream(String columnName, InputStream x,
5777:                    long length) throws SQLException {
5778:                try {
5779:                    updateAsciiStream(findColumnX(columnName), x, length);
5780:                } catch (SqlException sqle) {
5781:                    throw sqle.getSQLException();
5782:                }
5783:            }
5784:
5785:            /**
5786:             * Updates the designated column with a binary stream value.
5787:             * The data will be read from the stream as needed until end-of-stream is
5788:             * reached.
5789:             *
5790:             * The updater methods are used to update column values in the current row
5791:             * or the insert row. The updater methods do not update the underlying
5792:             * database; instead the <code>updateRow</code> or <code>insertRow</code>
5793:             * methods are called to update the database.
5794:             *
5795:             * @param columnLabel the label for the column specified with the SQL AS
5796:             *      clause. If the SQL AS clause was not specified, then the label is
5797:             *      the name of the column
5798:             * @param x the new column value 
5799:             * @throws SQLException if the columnLabel is not valid; if a database
5800:             *      access error occurs; the result set concurrency is
5801:             *      <code>CONCUR_READ_ONLY</code> or this method is called on a closed
5802:             *      result set
5803:             */
5804:            public void updateBinaryStream(String columnLabel, InputStream x)
5805:                    throws SQLException {
5806:                try {
5807:                    updateBinaryStream(findColumnX(columnLabel), x);
5808:                } catch (SqlException se) {
5809:                    throw se.getSQLException();
5810:                }
5811:            }
5812:
5813:            /**
5814:             * Update a column with a binary stream value.
5815:             *
5816:             * The updateXXX() methods are used to update column values in the current
5817:             * row, or the insert row. The updateXXX() methods do not update the
5818:             * underlying database, instead the updateRow() or insertRow() methods are
5819:             * called to update the database.
5820:             *
5821:             * @param columnName
5822:             *            the name of the column
5823:             * @param x
5824:             *            the new column value
5825:             * @param length
5826:             *            of the stream
5827:             * @exception SQLException
5828:             *                if a database-access error occurs
5829:             */
5830:            public void updateBinaryStream(String columnName, InputStream x,
5831:                    long length) throws SQLException {
5832:                try {
5833:                    updateBinaryStream(findColumnX(columnName), x, length);
5834:                } catch (SqlException sqle) {
5835:                    throw sqle.getSQLException();
5836:                }
5837:            }
5838:
5839:            /**
5840:             * Updates the designated column using the given input stream.
5841:             * The data will be read from the stream as needed until end-of-stream is
5842:             * reached.
5843:             *
5844:             * The updater methods are used to update column values in the current row
5845:             * or the insert row. The updater methods do not update the underlying
5846:             * database; instead the <code>updateRow</code> or <code>insertRow</code>
5847:             * methods are called to update the database.
5848:             *
5849:             * @param columnLabel the label for the column specified with the SQL AS
5850:             *      clause. If the SQL AS clause was not specified, then the label is
5851:             *      the name of the column
5852:             * @param x the new column value
5853:             * @throws SQLException if the columnLabel is not valid; if a database
5854:             *      access error occurs; the result set concurrency is
5855:             *      <code>CONCUR_READ_ONLY</code> or this method is called on a closed
5856:             *      result set
5857:             */
5858:            public void updateBlob(String columnLabel, InputStream x)
5859:                    throws SQLException {
5860:                try {
5861:                    updateBlob(findColumnX(columnLabel), x);
5862:                } catch (SqlException se) {
5863:                    throw se.getSQLException();
5864:                }
5865:            }
5866:
5867:            /**
5868:             * Updates the designated column with a character stream value.
5869:             * The data will be read from the stream as needed until end-of-stream is
5870:             * reached.
5871:             *
5872:             * The updater methods are used to update column values in the current row
5873:             * or the insert row. The updater methods do not update the underlying
5874:             * database; instead the <code>updateRow</code> or <code>insertRow</code>
5875:             * methods are called to update the database.
5876:             *
5877:             * @param columnLabel the label for the column specified with the SQL AS
5878:             *      clause. If the SQL AS clause was not specified, then the label is
5879:             *      the name of the column
5880:             * @param reader the new column value
5881:             * @throws SQLException if the columnLabel is not valid; if a database
5882:             *      access error occurs; the result set concurrency is
5883:             *      <code>CONCUR_READ_ONLY</code> or this method is called on a closed
5884:             *      result set
5885:             */
5886:            public void updateCharacterStream(String columnLabel, Reader reader)
5887:                    throws SQLException {
5888:                try {
5889:                    updateCharacterStream(findColumnX(columnLabel), reader);
5890:                } catch (SqlException se) {
5891:                    throw se.getSQLException();
5892:                }
5893:            }
5894:
5895:            /**
5896:             * Update a column with a character stream value.
5897:             *
5898:             * The updateXXX() methods are used to update column values in the current
5899:             * row, or the insert row. The updateXXX() methods do not update the
5900:             * underlying database, instead the updateRow() or insertRow() methods are
5901:             * called to update the database.
5902:             *
5903:             * @param columnName
5904:             *            the name of the column
5905:             * @param reader
5906:             *            the new column value
5907:             * @param length
5908:             *            length of the stream
5909:             * @exception SQLException
5910:             *                if a database-access error occurs
5911:             */
5912:            public void updateCharacterStream(String columnName, Reader reader,
5913:                    long length) throws SQLException {
5914:                try {
5915:                    updateCharacterStream(findColumnX(columnName), reader,
5916:                            length);
5917:                } catch (SqlException sqle) {
5918:                    throw sqle.getSQLException();
5919:                }
5920:            }
5921:
5922:            /**
5923:             * Updates the designated column using the given <code>Reader</code>
5924:             * object. 
5925:             * The data will be read from the stream as needed until end-of-stream is
5926:             * reached. The JDBC driver will do any necessary conversion from UNICODE
5927:             * to the database char format.
5928:             *
5929:             * The updater methods are used to update column values in the current row
5930:             * or the insert row. The updater methods do not update the underlying
5931:             * database; instead the <code>updateRow</code> or <code>insertRow</code>
5932:             * methods are called to update the database.
5933:             *
5934:             * @param columnLabel the label for the column specified with the SQL AS
5935:             *      clause. If the SQL AS clause was not specified, then the label is
5936:             *      the name of the column
5937:             * @param reader an object that contains the data to set the parameter
5938:             *      value to. 
5939:             * @throws SQLException if the columnIndex is not valid; if a database
5940:             *      access error occurs; the result set concurrency is
5941:             *      <code>CONCUR_READ_ONLY</code> or this method is called on a closed
5942:             *      result set
5943:             */
5944:            public void updateClob(String columnLabel, Reader reader)
5945:                    throws SQLException {
5946:                try {
5947:                    updateClob(findColumnX(columnLabel), reader);
5948:                } catch (SqlException se) {
5949:                    throw se.getSQLException();
5950:                }
5951:            }
5952:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.