Source Code Cross Referenced for EmbedResultSet.java in  » Database-DBMS » db-derby-10.2 » org » apache » derby » impl » jdbc » 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.impl.jdbc 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:
0003:           Derby - Class org.apache.derby.impl.jdbc.EmbedResultSet
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.impl.jdbc;
0023:
0024:        import org.apache.derby.iapi.services.sanity.SanityManager;
0025:
0026:        import org.apache.derby.iapi.error.StandardException;
0027:
0028:        import org.apache.derby.iapi.jdbc.EngineResultSet;
0029:        import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;
0030:        import org.apache.derby.iapi.sql.conn.StatementContext;
0031:
0032:        import org.apache.derby.iapi.sql.ResultSet;
0033:        import org.apache.derby.iapi.sql.ParameterValueSet;
0034:        import org.apache.derby.iapi.sql.execute.ExecutionFactory;
0035:        import org.apache.derby.iapi.sql.execute.ExecCursorTableReference;
0036:        import org.apache.derby.iapi.sql.execute.ExecRow;
0037:        import org.apache.derby.iapi.sql.execute.NoPutResultSet;
0038:        import org.apache.derby.impl.sql.execute.ScrollInsensitiveResultSet;
0039:
0040:        import org.apache.derby.iapi.sql.Activation;
0041:        import org.apache.derby.iapi.sql.execute.CursorActivation;
0042:
0043:        import org.apache.derby.iapi.types.DataTypeDescriptor;
0044:        import org.apache.derby.iapi.types.DataValueDescriptor;
0045:        import org.apache.derby.iapi.types.RawToBinaryFormatStream;
0046:        import org.apache.derby.iapi.types.ReaderToUTF8Stream;
0047:        import org.apache.derby.iapi.types.UserDataValue;
0048:        import org.apache.derby.iapi.types.VariableSizeDataValue;
0049:        import org.apache.derby.iapi.sql.ResultDescription;
0050:        import org.apache.derby.iapi.services.io.StreamStorable;
0051:
0052:        import org.apache.derby.iapi.services.io.LimitInputStream;
0053:        import org.apache.derby.iapi.services.io.NewByteArrayInputStream;
0054:        import org.apache.derby.iapi.services.io.LimitReader;
0055:        import org.apache.derby.iapi.error.ExceptionSeverity;
0056:        import org.apache.derby.iapi.reference.JDBC20Translation;
0057:        import org.apache.derby.iapi.reference.JDBC30Translation;
0058:        import org.apache.derby.iapi.reference.SQLState;
0059:        import org.apache.derby.iapi.util.StringUtil;
0060:        import org.apache.derby.iapi.util.ReuseFactory;
0061:
0062:        /* can't import these due to name overlap:
0063:         import java.sql.ResultSet;
0064:         */
0065:        import java.sql.Blob;
0066:        import java.sql.Clob;
0067:        import java.sql.Statement;
0068:        import java.sql.SQLException;
0069:        import java.sql.SQLWarning;
0070:        import java.sql.ResultSetMetaData;
0071:        import java.sql.Date;
0072:        import java.sql.Time;
0073:        import java.sql.Timestamp;
0074:        import java.sql.Types;
0075:
0076:        import java.io.Reader;
0077:        import java.io.InputStream;
0078:        import java.io.IOException;
0079:        import java.net.URL;
0080:
0081:        import java.util.Map;
0082:        import java.util.HashMap;
0083:        import java.util.Arrays;
0084:        import java.util.Calendar;
0085:
0086:        /**
0087:         * A EmbedResultSet for results from the EmbedStatement family. 
0088:         <P><B>Supports</B>
0089:         <UL>
0090:         <LI> JSR 169
0091:         </UL>
0092:         * @author ames
0093:         */
0094:
0095:        public abstract class EmbedResultSet extends ConnectionChild implements 
0096:                EngineResultSet, Comparable {
0097:
0098:            // cursor movement
0099:            protected static final int FIRST = 1;
0100:            protected static final int NEXT = 2;
0101:            protected static final int LAST = 3;
0102:            protected static final int PREVIOUS = 4;
0103:            protected static final int BEFOREFIRST = 5;
0104:            protected static final int AFTERLAST = 6;
0105:            protected static final int ABSOLUTE = 7;
0106:            protected static final int RELATIVE = 8;
0107:
0108:            /** 
0109:             * The currentRow contains the data of the current row of the resultset.
0110:             * If the containing row array is null, the cursor is not postioned on a 
0111:             * row 
0112:             */
0113:            private final ExecRow currentRow;
0114:            protected boolean wasNull;
0115:
0116:            /**
0117:             * Set if this ResultSet is definitely closed.
0118:             * If the connection has been closed, or the database
0119:             *  or system shutdown but the ResultSet has not been
0120:             *  closed explictly then this may be false. Once
0121:             *  this object detects the connection is closed
0122:             *  isClosed will be set to true.
0123:             */
0124:            boolean isClosed;
0125:
0126:            private boolean isOnInsertRow;
0127:            private Object currentStream;
0128:
0129:            // immutable state
0130:            private ResultSet theResults;
0131:            private boolean forMetaData;
0132:            private ResultSetMetaData rMetaData;
0133:            private SQLWarning topWarning;
0134:
0135:            /**
0136:             This activation is set by EmbedStatement
0137:             for a single execution Activation. Ie.
0138:             a ResultSet from a Statement.executeQuery().
0139:             In this case the closing of this ResultSet will close
0140:             the activation or the finalization of the ResultSet
0141:             without it being closed will mark the Activation as unused.
0142:             c.f. EmbedPreparedStatement.finalize().
0143:             */
0144:            Activation singleUseActivation;
0145:
0146:            // Order of creation 
0147:            final int order;
0148:
0149:            private final ResultDescription resultDescription;
0150:
0151:            /**
0152:             * A map which maps a column name to a column number.
0153:             * Entries only added when accessing columns with the name.
0154:             */
0155:            private Map columnNameMap;
0156:
0157:            // max rows limit for this result set
0158:            private int maxRows;
0159:            // The Maximum field size limt set for this result set
0160:            private final int maxFieldSize;
0161:
0162:            /*
0163:             * Incase of forward only cursors we limit the number of rows
0164:             * returned if the maxRows is set. The following varible is used
0165:             * to keep the count of number of rows returned to the user.
0166:             */
0167:            private int NumberofFetchedRows;
0168:
0169:            /**
0170:             * The statement object that originally created us.
0171:            	we hang on to the statement to prevent GC from
0172:            	closing it under us
0173:             */
0174:            private final EmbedStatement stmt;
0175:
0176:            /**
0177:             * The statement that currently owns this ResultSet.
0178:             * Statements created in procedures are passed off
0179:             * to the Statement that called the procedure.
0180:             * This is to avoid the ResultSet being closed
0181:             * due to the Statement within the procedure
0182:             * or the nested Connection being closed.
0183:             */
0184:            private EmbedStatement owningStmt;
0185:
0186:            /**
0187:             * Statement object the application used to
0188:             * create this ResultSet.
0189:             */
0190:            private Statement applicationStmt;
0191:
0192:            private long timeoutMillis;
0193:
0194:            private final boolean isAtomic;
0195:
0196:            private final int concurrencyOfThisResultSet;
0197:
0198:            /* updateRow is used to keep the values which are updated with updateXXX() 
0199:             * calls. It is used by both insertRow() and updateRow(). 
0200:             * It is initialized to null if the resultset is not updatable. 
0201:             */
0202:            private final ExecRow updateRow;
0203:
0204:            /* These are the columns which have been updated so far. 
0205:             */
0206:            private boolean[] columnGotUpdated;
0207:            private boolean currentRowHasBeenUpdated; //Gets set to true after first updateXXX on a row. Gets reset to false when the cursor moves off the row
0208:
0209:            private int fetchDirection;
0210:            private int fetchSize;
0211:
0212:            /**
0213:             * Indicates which columns have already been fetched
0214:             * as a stream for a row. Created on-demand by a getXXXStream call.
0215:             */
0216:            private boolean[] streamUsedFlags;
0217:
0218:            /**
0219:             * This class provides the glue between the Cloudscape
0220:             * resultset and the JDBC resultset, mapping calls-to-calls.
0221:             */
0222:            public EmbedResultSet(EmbedConnection conn,
0223:                    ResultSet resultsToWrap, boolean forMetaData,
0224:                    EmbedStatement stmt, boolean isAtomic) throws SQLException {
0225:
0226:                super (conn);
0227:
0228:                if (SanityManager.DEBUG)
0229:                    SanityManager.ASSERT(resultsToWrap != null);
0230:                theResults = resultsToWrap;
0231:
0232:                // ResultSet's for metadata are single use, they are created
0233:                // with a PreparedStatement internally, but that statement is
0234:                // never returned to the application.
0235:                if (this .forMetaData = forMetaData)
0236:                    singleUseActivation = resultsToWrap.getActivation();
0237:                this .applicationStmt = this .stmt = owningStmt = stmt;
0238:
0239:                this .timeoutMillis = stmt == null ? 0L : (long) stmt
0240:                        .getQueryTimeout() * 1000L;
0241:
0242:                this .isAtomic = isAtomic;
0243:
0244:                //If the Statement object has CONCUR_READ_ONLY set on it then the concurrency on the ResultSet object will be CONCUR_READ_ONLY also.
0245:                //But, if the Statement object has CONCUR_UPDATABLE set on it, then the concurrency on the ResultSet object can be
0246:                //CONCUR_READ_ONLY or CONCUR_UPDATABLE depending on whether the underlying language resultset is updateable or not.
0247:                //If the underlying language resultset is not updateable, then the concurrency of the ResultSet object will be CONCUR_READ_ONLY
0248:                //and a warning will be issued on the ResultSet object.
0249:                if (stmt == null)
0250:                    concurrencyOfThisResultSet = JDBC20Translation.CONCUR_READ_ONLY;
0251:                else if (stmt.getResultSetConcurrency() == JDBC20Translation.CONCUR_READ_ONLY)
0252:                    concurrencyOfThisResultSet = JDBC20Translation.CONCUR_READ_ONLY;
0253:                else {
0254:                    if (!isForUpdate()) { //language resultset not updatable
0255:                        concurrencyOfThisResultSet = JDBC20Translation.CONCUR_READ_ONLY;
0256:                        SQLWarning w = StandardException
0257:                                .newWarning(SQLState.QUERY_NOT_QUALIFIED_FOR_UPDATABLE_RESULTSET);
0258:                        addWarning(w);
0259:                    } else
0260:                        concurrencyOfThisResultSet = JDBC20Translation.CONCUR_UPDATABLE;
0261:                }
0262:
0263:                // Fill in the column types
0264:                resultDescription = theResults.getResultDescription();
0265:                final ExecutionFactory factory = conn.getLanguageConnection()
0266:                        .getLanguageConnectionFactory().getExecutionFactory();
0267:                final int columnCount = getMetaData().getColumnCount();
0268:                this .currentRow = factory.getValueRow(columnCount);
0269:                this .columnNameMap = null;
0270:                currentRow.setRowArray(null);
0271:
0272:                // Only incur the cost of allocating and maintaining
0273:                // updated column information if the columns can be updated.
0274:                if (concurrencyOfThisResultSet == JDBC20Translation.CONCUR_UPDATABLE) {
0275:                    //initialize arrays related to updateRow implementation
0276:                    columnGotUpdated = new boolean[columnCount];
0277:                    updateRow = factory.getValueRow(columnCount);
0278:                    for (int i = 1; i <= columnCount; i++) {
0279:                        updateRow.setColumn(i, resultDescription
0280:                                .getColumnDescriptor(i).getType().getNull());
0281:                    }
0282:                    initializeUpdateRowModifiers();
0283:                } else {
0284:                    updateRow = null;
0285:                }
0286:
0287:                // assign the max rows and maxfiled size limit for this result set
0288:                if (stmt != null) {
0289:                    // At connectivity level we handle only for forward only cursor
0290:                    if (stmt.resultSetType == JDBC20Translation.TYPE_FORWARD_ONLY)
0291:                        maxRows = stmt.maxRows;
0292:
0293:                    maxFieldSize = stmt.MaxFieldSize;
0294:                } else
0295:                    maxFieldSize = 0;
0296:
0297:                order = conn.getResultSetOrderId();
0298:            }
0299:
0300:            /**
0301:            	JDBC states that a ResultSet is closed when garbage collected.
0302:            	We simply mark the activation as unused. Some later use
0303:            	of the connection will clean everything up.
0304:
0305:            	@exception Throwable Allows any exception to be thrown during finalize
0306:             */
0307:            protected void finalize() throws Throwable {
0308:                super .finalize();
0309:
0310:                if (singleUseActivation != null) {
0311:                    singleUseActivation.markUnused();
0312:                }
0313:            }
0314:
0315:            private void checkNotOnInsertRow() throws SQLException {
0316:                if (isOnInsertRow) {
0317:                    throw newSQLException(SQLState.NO_CURRENT_ROW);
0318:                }
0319:            }
0320:
0321:            // checkOnRow protects us from making requests of
0322:            // resultSet that would fail with NullPointerExceptions
0323:            // or milder problems due to not having a row.
0324:            protected final void checkOnRow() throws SQLException {
0325:                if (currentRow.getRowArray() == null) {
0326:                    throw newSQLException(SQLState.NO_CURRENT_ROW);
0327:                }
0328:            }
0329:
0330:            /**
0331:             * Initializes the currentRowHasBeenUpdated and columnGotUpdated fields
0332:             */
0333:            private void initializeUpdateRowModifiers() {
0334:                currentRowHasBeenUpdated = false;
0335:                Arrays.fill(columnGotUpdated, false);
0336:            }
0337:
0338:            /**
0339:            	Check the column is in range *and* return the JDBC type of the column.
0340:
0341:            	@exception SQLException ResultSet is not on a row or columnIndex is out of range.
0342:             */
0343:            final int getColumnType(int columnIndex) throws SQLException {
0344:                if (!isOnInsertRow)
0345:                    checkOnRow(); // first make sure there's a row
0346:
0347:                if (columnIndex < 1
0348:                        || columnIndex > resultDescription.getColumnCount())
0349:                    throw newSQLException(SQLState.COLUMN_NOT_FOUND,
0350:                            new Integer(columnIndex));
0351:
0352:                return resultDescription.getColumnDescriptor(columnIndex)
0353:                        .getType().getJDBCTypeId();
0354:            }
0355:
0356:            /*
0357:             * java.sql.ResultSet interface
0358:             */
0359:            /**
0360:             * A ResultSet is initially positioned before its first row; the
0361:             * first call to next makes the first row the current row; the
0362:             * second call makes the second row the current row, etc.
0363:             *
0364:             * <P>If an input stream from the previous row is open, it is
0365:             * implicitly closed. The ResultSet's warning chain is cleared
0366:             * when a new row is read.
0367:             *
0368:             * @return true if the new current row is valid; false if there
0369:             * are no more rows
0370:             * @exception SQLException thrown on failure.
0371:             */
0372:            public boolean next() throws SQLException {
0373:                // we seem to have some trigger paths which don't have
0374:                // statement initialized, may not need this check in those cases
0375:                if (maxRows != 0) {
0376:                    NumberofFetchedRows++;
0377:                    // check whether we hit the maxRows limit 
0378:                    if (NumberofFetchedRows > maxRows) {
0379:                        //we return false for the next call when maxRows is hit
0380:                        closeCurrentStream();
0381:                        return false;
0382:                    }
0383:                }
0384:                return movePosition(NEXT, 0, "next");
0385:            }
0386:
0387:            protected boolean movePosition(int position, String positionText)
0388:                    throws SQLException {
0389:                return movePosition(position, 0, positionText);
0390:            }
0391:
0392:            protected boolean movePosition(int position, int row,
0393:                    String positionText) throws SQLException {
0394:                closeCurrentStream(); // closing currentStream does not depend on the
0395:                // underlying connection.  Do this outside of
0396:                // the connection synchronization.
0397:
0398:                checkExecIfClosed(positionText); // checking result set closure does not depend
0399:                // on the underlying connection.  Do this
0400:                // outside of the connection synchronization.
0401:
0402:                if (isOnInsertRow) {
0403:                    moveToCurrentRow();
0404:                }
0405:
0406:                synchronized (getConnectionSynchronization()) {
0407:
0408:                    setupContextStack();
0409:                    try {
0410:                        LanguageConnectionContext lcc = getEmbedConnection()
0411:                                .getLanguageConnection();
0412:                        final ExecRow newRow;
0413:                        try {
0414:
0415:                            /* Push and pop a StatementContext around a next call
0416:                             * so that the ResultSet will get correctly closed down
0417:                             * on an error.
0418:                             * (Cache the LanguageConnectionContext)
0419:                             */
0420:                            StatementContext statementContext = lcc
0421:                                    .pushStatementContext(
0422:                                            isAtomic,
0423:                                            concurrencyOfThisResultSet == JDBC20Translation.CONCUR_READ_ONLY,
0424:                                            getSQLText(),
0425:                                            getParameterValueSet(), false,
0426:                                            timeoutMillis);
0427:
0428:                            switch (position) {
0429:                            case BEFOREFIRST:
0430:                                newRow = theResults.setBeforeFirstRow();
0431:                                break;
0432:
0433:                            case FIRST:
0434:                                newRow = theResults.getFirstRow();
0435:                                break;
0436:
0437:                            case NEXT:
0438:                                newRow = theResults.getNextRow();
0439:                                break;
0440:
0441:                            case LAST:
0442:                                newRow = theResults.getLastRow();
0443:                                break;
0444:
0445:                            case AFTERLAST:
0446:                                newRow = theResults.setAfterLastRow();
0447:                                break;
0448:
0449:                            case PREVIOUS:
0450:                                newRow = theResults.getPreviousRow();
0451:                                break;
0452:
0453:                            case ABSOLUTE:
0454:                                newRow = theResults.getAbsoluteRow(row);
0455:                                break;
0456:
0457:                            case RELATIVE:
0458:                                newRow = theResults.getRelativeRow(row);
0459:                                break;
0460:
0461:                            default:
0462:                                newRow = null;
0463:                                if (SanityManager.DEBUG) {
0464:                                    SanityManager
0465:                                            .THROWASSERT("Unexpected value for position - "
0466:                                                    + position);
0467:                                }
0468:                            }
0469:
0470:                            lcc.popStatementContext(statementContext, null);
0471:
0472:                        } catch (Throwable t) {
0473:                            /*
0474:                             * Need to close the result set here because the error might
0475:                             * cause us to lose the current connection if this is an XA
0476:                             * connection and we won't be able to do the close later
0477:                             */
0478:                            throw closeOnTransactionError(t);
0479:                        }
0480:
0481:                        SQLWarning w = theResults.getWarnings();
0482:                        if (w != null) {
0483:                            if (topWarning == null)
0484:                                topWarning = w;
0485:                            else
0486:                                topWarning.setNextWarning(w);
0487:                        }
0488:
0489:                        boolean onRow = (newRow != null);
0490:                        if (onRow) {
0491:                            currentRow.setRowArray(newRow.getRowArray());
0492:                        } else {
0493:                            currentRow.setRowArray(null);
0494:                        }
0495:
0496:                        //if (onRow && !(currentRow instanceof org.apache.derby.impl.sql.execute.ValueRow))
0497:                        //	System.out.println(currentRow.getClass());
0498:
0499:                        // The ResultSet may implicitly close when when the ResultSet type 
0500:                        // is TYPE_FORWARD_ONLY and the next method of ResultSet returns 
0501:                        // false. This will cause a commit if autocommit = true.
0502:                        if (!onRow && (position == NEXT)) {
0503:
0504:                            // In case of resultset for MetaData, we will only commit
0505:                            // if we are the only statement currently opened for this
0506:                            // connection; otherwise we don't want to affect other
0507:                            // resultSet's by committing the MetaData one.
0508:                            // There is no internal xact (xact isolation) for MetaData type
0509:                            // of resultSet; therefore committing (to release locks) would end
0510:                            // up committing all the other resultSet for this connection.
0511:                            //
0512:                            // We do synchronize on the connection, therefore Activation count
0513:                            // should be valid and protected.
0514:                            //
0515:                            //LanguageConnectionContext lcc = getEmbedConnection().getLanguageConnection();
0516:                            if (forMetaData && (lcc.getActivationCount() > 1)) {
0517:                                // we do not want to commit here as there seems to be other
0518:                                // statements/resultSets currently opened for this connection.
0519:                            } else if (owningStmt != null
0520:                                    && owningStmt.getResultSetType() == TYPE_FORWARD_ONLY) {
0521:                                // allow the satement to commit if required.
0522:                                owningStmt.resultSetClosing(this );
0523:                            }
0524:                        }
0525:
0526:                        // Clear the indication of which columns were fetched as streams.
0527:                        if (streamUsedFlags != null)
0528:                            Arrays.fill(streamUsedFlags, false);
0529:                        if (columnGotUpdated != null
0530:                                && currentRowHasBeenUpdated) {
0531:                            initializeUpdateRowModifiers();
0532:                        }
0533:
0534:                        return onRow;
0535:                    } finally {
0536:                        restoreContextStack();
0537:                    }
0538:                }
0539:
0540:            }
0541:
0542:            /**
0543:             * In some cases, it is desirable to immediately release a
0544:             * ResultSet's database and JDBC resources instead of waiting for
0545:             * this to happen when it is automatically closed; the close
0546:             * method provides this immediate release.
0547:             *
0548:             * <P><B>Note:</B> A ResultSet is automatically closed by the
0549:             * Statement that generated it when that Statement is closed,
0550:             * re-executed, or is used to retrieve the next result from a
0551:             * sequence of multiple results. A ResultSet is also automatically
0552:             * closed when it is garbage collected.
0553:             * @exception SQLException thrown on failure.
0554:             */
0555:            public void close() throws SQLException {
0556:
0557:                /* if this result is already closed, don't try to close again
0558:                 * we may have closed it earlier because of an error and trying
0559:                 * to close again will cause a different problem if the connection
0560:                 * has been closed as in XA error handling
0561:                 */
0562:                if (isClosed)
0563:                    return;
0564:
0565:                closeCurrentStream(); // closing currentStream does not depend on the
0566:                // underlying connection.  Do this outside of
0567:                // the connection synchronization.
0568:                // Would like to throw an exception if already closed, but
0569:                // some code assumes you can close a ResultSet more than once.
0570:                // checkIfClosed("close");
0571:
0572:                // synchronize out here so the close and the autocommit are
0573:                // both in the same sync block.
0574:                synchronized (getConnectionSynchronization()) {
0575:
0576:                    try {
0577:                        setupContextStack(); // make sure there's context
0578:                    } catch (SQLException se) {
0579:                        // we may get an exception here if this is part of an XA transaction
0580:                        // and the transaction has been committed
0581:                        // just give up and return
0582:                        return;
0583:                    }
0584:
0585:                    try {
0586:                        try {
0587:                            theResults.finish(); // release the result set, don't just close it
0588:
0589:                            if (this .singleUseActivation != null) {
0590:                                this .singleUseActivation.close();
0591:                                this .singleUseActivation = null;
0592:                            }
0593:
0594:                        } catch (Throwable t) {
0595:                            throw handleException(t);
0596:                        }
0597:
0598:                        // In case of resultset for MetaData, we will only commit
0599:                        // if we are the only statement currently opened for this
0600:                        // connection; otherwise we don't want to affect other
0601:                        // resultSet's by committing the MetaData one.
0602:                        // There is no internal xact (xact isolation) for MetaData type
0603:                        // of resultSet; therefore committing (to release locks) would end
0604:                        // up committing all the other resultSet for this connection.
0605:                        //
0606:                        // We do synchronize on the connection, therefore Activation count
0607:                        // should be valid and protected.
0608:                        //
0609:                        if (forMetaData) {
0610:
0611:                            LanguageConnectionContext lcc = getEmbedConnection()
0612:                                    .getLanguageConnection();
0613:                            if (lcc.getActivationCount() > 1) {
0614:                                // we do not want to commit here as there seems to be other
0615:                                // statements/resultSets currently opened for this connection.
0616:                            } else if (owningStmt != null)
0617:                                // allow the satement to commit if required.
0618:                                owningStmt.resultSetClosing(this );
0619:
0620:                        } else if (owningStmt != null) {
0621:                            // allow the satement to commit if required.
0622:                            owningStmt.resultSetClosing(this );
0623:                        }
0624:
0625:                    } finally {
0626:                        isClosed = true;
0627:                        restoreContextStack();
0628:                    }
0629:
0630:                    // the idea is to release resources, so:
0631:                    currentRow.setRowArray(null);
0632:                    rMetaData = null; // let it go, we can make a new one
0633:
0634:                    // we hang on to theResults and messenger
0635:                    // in case more calls come in on this resultSet
0636:                }
0637:
0638:            }
0639:
0640:            /**
0641:             * A column may have the value of SQL NULL; wasNull reports whether
0642:             * the last column read had this special value.
0643:             * Note that you must first call getXXX on a column to try to read
0644:             * its value and then call wasNull() to find if the value was
0645:             * the SQL NULL.
0646:             *
0647:             * <p> we take the least exception approach and simply return false
0648:             * if no column has been read yet.
0649:             *
0650:             * @return true if last column read was SQL NULL
0651:             *
0652:             * @exception SQLException		Thrown if this ResultSet is closed
0653:             */
0654:            public final boolean wasNull() throws SQLException {
0655:                checkIfClosed("wasNull");
0656:                return wasNull;
0657:            }
0658:
0659:            //======================================================================
0660:            // Methods for accessing results by column index
0661:            //======================================================================
0662:
0663:            /**
0664:             * Get the value of a column in the current row as a Java String.
0665:             *
0666:             * @param columnIndex the first column is 1, the second is 2, ...
0667:             * @return the column value; if the value is SQL NULL, the result is null
0668:             * @exception SQLException thrown on failure.
0669:             */
0670:            public final String getString(int columnIndex) throws SQLException {
0671:                checkIfClosed("getString");
0672:
0673:                try {
0674:
0675:                    DataValueDescriptor dvd = getColumn(columnIndex);
0676:
0677:                    if (wasNull = dvd.isNull())
0678:                        return null;
0679:
0680:                    String value = dvd.getString();
0681:
0682:                    // check for the max field size limit 
0683:                    if (maxFieldSize > 0
0684:                            && isMaxFieldSizeType(getColumnType(columnIndex))) {
0685:                        if (value.length() > maxFieldSize) {
0686:                            value = value.substring(0, maxFieldSize);
0687:                        }
0688:                    }
0689:
0690:                    return value;
0691:
0692:                } catch (Throwable t) {
0693:                    throw noStateChangeException(t);
0694:                }
0695:            }
0696:
0697:            /**
0698:             * Get the value of a column in the current row as a Java boolean.
0699:             *
0700:             * @param columnIndex the first column is 1, the second is 2, ...
0701:             * @return the column value; if the value is SQL NULL, the result is false
0702:             * @exception SQLException thrown on failure.
0703:             */
0704:            public final boolean getBoolean(int columnIndex)
0705:                    throws SQLException {
0706:                checkIfClosed("getBoolean");
0707:
0708:                try {
0709:
0710:                    DataValueDescriptor dvd = getColumn(columnIndex);
0711:
0712:                    if (wasNull = dvd.isNull())
0713:                        return false;
0714:
0715:                    return dvd.getBoolean();
0716:
0717:                } catch (StandardException t) {
0718:                    throw noStateChangeException(t);
0719:                }
0720:            }
0721:
0722:            /**
0723:             * Get the value of a column in the current row as a Java byte.
0724:             *
0725:             * @param columnIndex the first column is 1, the second is 2, ...
0726:             * @return the column value; if the value is SQL NULL, the result is 0
0727:             * @exception SQLException thrown on failure.
0728:             */
0729:            public final byte getByte(int columnIndex) throws SQLException {
0730:                checkIfClosed("getByte");
0731:                try {
0732:
0733:                    DataValueDescriptor dvd = getColumn(columnIndex);
0734:
0735:                    if (wasNull = dvd.isNull())
0736:                        return 0;
0737:
0738:                    return dvd.getByte();
0739:
0740:                } catch (StandardException t) {
0741:                    throw noStateChangeException(t);
0742:                }
0743:            }
0744:
0745:            /**
0746:             * Get the value of a column in the current row as a Java short.
0747:             *
0748:             * @param columnIndex the first column is 1, the second is 2, ...
0749:             * @return the column value; if the value is SQL NULL, the result is 0
0750:             * @exception SQLException thrown on failure.
0751:             */
0752:            public final short getShort(int columnIndex) throws SQLException {
0753:                checkIfClosed("getShort");
0754:
0755:                try {
0756:
0757:                    DataValueDescriptor dvd = getColumn(columnIndex);
0758:
0759:                    if (wasNull = dvd.isNull())
0760:                        return 0;
0761:
0762:                    return dvd.getShort();
0763:
0764:                } catch (StandardException t) {
0765:                    throw noStateChangeException(t);
0766:                }
0767:            }
0768:
0769:            /**
0770:             * Get the value of a column in the current row as a Java int.
0771:             *
0772:             * @param columnIndex the first column is 1, the second is 2, ...
0773:             * @return the column value; if the value is SQL NULL, the result is 0
0774:             * @exception SQLException thrown on failure.
0775:             */
0776:            public final int getInt(int columnIndex) throws SQLException {
0777:                checkIfClosed("getInt");
0778:                try {
0779:
0780:                    DataValueDescriptor dvd = getColumn(columnIndex);
0781:
0782:                    if (wasNull = dvd.isNull())
0783:                        return 0;
0784:
0785:                    return dvd.getInt();
0786:
0787:                } catch (StandardException t) {
0788:                    throw noStateChangeException(t);
0789:                }
0790:            }
0791:
0792:            /**
0793:             * Get the value of a column in the current row as a Java long.
0794:             *
0795:             * @param columnIndex the first column is 1, the second is 2, ...
0796:             * @return the column value; if the value is SQL NULL, the result is 0
0797:             * @exception SQLException thrown on failure.
0798:             */
0799:            public final long getLong(int columnIndex) throws SQLException {
0800:                checkIfClosed("getLong");
0801:                try {
0802:
0803:                    DataValueDescriptor dvd = getColumn(columnIndex);
0804:
0805:                    if (wasNull = dvd.isNull())
0806:                        return 0;
0807:
0808:                    return dvd.getLong();
0809:
0810:                } catch (StandardException t) {
0811:                    throw noStateChangeException(t);
0812:                }
0813:            }
0814:
0815:            /**
0816:             * Get the value of a column in the current row as a Java float.
0817:             *
0818:             * @param columnIndex the first column is 1, the second is 2, ...
0819:             * @return the column value; if the value is SQL NULL, the result is 0
0820:             * @exception SQLException thrown on failure.
0821:             */
0822:            public final float getFloat(int columnIndex) throws SQLException {
0823:                checkIfClosed("getFloat");
0824:                try {
0825:
0826:                    DataValueDescriptor dvd = getColumn(columnIndex);
0827:
0828:                    if (wasNull = dvd.isNull())
0829:                        return 0.0F;
0830:
0831:                    return dvd.getFloat();
0832:
0833:                } catch (StandardException t) {
0834:                    throw noStateChangeException(t);
0835:                }
0836:            }
0837:
0838:            /**
0839:             * Get the value of a column in the current row as a Java double.
0840:             *
0841:             * @param columnIndex the first column is 1, the second is 2, ...
0842:             * @return the column value; if the value is SQL NULL, the result is 0
0843:             * @exception SQLException thrown on failure.
0844:             */
0845:            public final double getDouble(int columnIndex) throws SQLException {
0846:                checkIfClosed("getDouble");
0847:                try {
0848:
0849:                    DataValueDescriptor dvd = getColumn(columnIndex);
0850:
0851:                    if (wasNull = dvd.isNull())
0852:                        return 0.0;
0853:
0854:                    return dvd.getDouble();
0855:
0856:                } catch (StandardException t) {
0857:                    throw noStateChangeException(t);
0858:                }
0859:            }
0860:
0861:            /**
0862:             * Get the value of a column in the current row as a Java byte array.
0863:             * The bytes represent the raw values returned by the driver.
0864:             *
0865:             * @param columnIndex the first column is 1, the second is 2, ...
0866:             * @return the column value; if the value is SQL NULL, the result is null
0867:             * @exception SQLException thrown on failure.
0868:             */
0869:            public final byte[] getBytes(int columnIndex) throws SQLException {
0870:                checkIfClosed("getBytes");
0871:                try {
0872:
0873:                    DataValueDescriptor dvd = getColumn(columnIndex);
0874:
0875:                    if (wasNull = dvd.isNull())
0876:                        return null;
0877:
0878:                    byte[] value = dvd.getBytes();
0879:
0880:                    // check for the max field size limit 
0881:                    if (maxFieldSize > 0
0882:                            && isMaxFieldSizeType(getColumnType(columnIndex))) {
0883:                        if (value.length > maxFieldSize) {
0884:                            byte[] limited_value = new byte[maxFieldSize];
0885:                            System.arraycopy(value, 0, limited_value, 0,
0886:                                    maxFieldSize);
0887:                            value = limited_value;
0888:                        }
0889:                    }
0890:
0891:                    return value;
0892:
0893:                } catch (StandardException t) {
0894:                    throw noStateChangeException(t);
0895:                }
0896:            }
0897:
0898:            /**
0899:             * Get the value of a column in the current row as a java.sql.Date object.
0900:             *
0901:             * @param columnIndex the first column is 1, the second is 2, ...
0902:             * @return the column value; if the value is SQL NULL, the result is null
0903:             * @exception SQLException thrown on failure.
0904:             */
0905:            public final Date getDate(int columnIndex) throws SQLException {
0906:                return getDate(columnIndex, (Calendar) null);
0907:            }
0908:
0909:            /**
0910:             * Get the value of a column in the current row as a java.sql.Time object.
0911:             *
0912:             * @param columnIndex the first column is 1, the second is 2, ...
0913:             * @return the column value; if the value is SQL NULL, the result is null
0914:             * @exception SQLException thrown on failure.
0915:             */
0916:            public final Time getTime(int columnIndex) throws SQLException {
0917:                return getTime(columnIndex, (Calendar) null);
0918:            }
0919:
0920:            /**
0921:             * Get the value of a column in the current row as a java.sql.Timestamp object.
0922:             *
0923:             * @param columnIndex the first column is 1, the second is 2, ...
0924:             * @return the column value; if the value is SQL NULL, the result is null
0925:             * @exception SQLException thrown on failure.
0926:             */
0927:            public final Timestamp getTimestamp(int columnIndex)
0928:                    throws SQLException {
0929:                return getTimestamp(columnIndex, (Calendar) null);
0930:            }
0931:
0932:            /**
0933:             * JDBC 2.0
0934:             *
0935:             * Get the value of a column in the current row as a java.sql.Date 
0936:             * object.  Use the calendar to construct an appropriate millisecond
0937:             * value for the Date, if the underlying database doesn't store
0938:             * timezone information.
0939:             *
0940:             * @param columnIndex the first column is 1, the second is 2, ...
0941:             * @param cal the calendar to use in constructing the date
0942:             * @return the column value; if the value is SQL NULL, the result is null
0943:             * @exception SQLException if a database-access error occurs.
0944:             */
0945:            public java.sql.Date getDate(int columnIndex, Calendar cal)
0946:                    throws SQLException {
0947:                checkIfClosed("getDate");
0948:                try {
0949:
0950:                    DataValueDescriptor dvd = getColumn(columnIndex);
0951:
0952:                    if (wasNull = dvd.isNull())
0953:                        return null;
0954:
0955:                    if (cal == null)
0956:                        cal = getCal();
0957:
0958:                    return dvd.getDate(cal);
0959:
0960:                } catch (StandardException t) {
0961:                    throw noStateChangeException(t);
0962:                }
0963:            }
0964:
0965:            /**
0966:             * JDBC 2.0
0967:             *
0968:             * Get the value of a column in the current row as a java.sql.Date 
0969:             * object. Use the calendar to construct an appropriate millisecond
0970:             * value for the Date, if the underlying database doesn't store
0971:             * timezone information.
0972:             *
0973:             * @param columnName is the SQL name of the column
0974:             * @param cal the calendar to use in constructing the date
0975:             * @return the column value; if the value is SQL NULL, the result is null
0976:             * @exception SQLException if a database-access error occurs.
0977:             */
0978:            public java.sql.Date getDate(String columnName, Calendar cal)
0979:                    throws SQLException {
0980:                checkIfClosed("getDate");
0981:                return getDate(findColumnName(columnName), cal);
0982:            }
0983:
0984:            /**
0985:             * JDBC 2.0
0986:             *
0987:             * Get the value of a column in the current row as a java.sql.Time 
0988:             * object. Use the calendar to construct an appropriate millisecond
0989:             * value for the Time, if the underlying database doesn't store
0990:             * timezone information.
0991:             *
0992:             * @param columnIndex the first column is 1, the second is 2, ...
0993:             * @param cal the calendar to use in constructing the time
0994:             * @return the column value; if the value is SQL NULL, the result is null
0995:             * @exception SQLException if a database-access error occurs.
0996:             */
0997:            public java.sql.Time getTime(int columnIndex, Calendar cal)
0998:                    throws SQLException {
0999:                checkIfClosed("getTime");
1000:                try {
1001:
1002:                    DataValueDescriptor dvd = getColumn(columnIndex);
1003:
1004:                    if (wasNull = dvd.isNull())
1005:                        return null;
1006:
1007:                    if (cal == null)
1008:                        cal = getCal();
1009:                    return dvd.getTime(cal);
1010:
1011:                } catch (StandardException t) {
1012:                    throw noStateChangeException(t);
1013:                }
1014:            }
1015:
1016:            /**
1017:             * JDBC 2.0
1018:             *
1019:             * Get the value of a column in the current row as a java.sql.Time 
1020:             * object. Use the calendar to construct an appropriate millisecond
1021:             * value for the Time, if the underlying database doesn't store
1022:             * timezone information.
1023:             *
1024:             * @param columnName is the SQL name of the column
1025:             * @param cal the calendar to use in constructing the time
1026:             * @return the column value; if the value is SQL NULL, the result is null
1027:             * @exception SQLException if a database-access error occurs.
1028:             */
1029:            public java.sql.Time getTime(String columnName, Calendar cal)
1030:                    throws SQLException {
1031:                checkIfClosed("getTime");
1032:                return getTime(findColumnName(columnName), cal);
1033:            }
1034:
1035:            /**
1036:             * JDBC 2.0
1037:             *
1038:             * Get the value of a column in the current row as a java.sql.Timestamp 
1039:             * object. Use the calendar to construct an appropriate millisecond
1040:             * value for the Timestamp, if the underlying database doesn't store
1041:             * timezone information.
1042:             *
1043:             * @param columnName is the SQL name of the column
1044:             * @param cal the calendar to use in constructing the timestamp
1045:             * @return the column value; if the value is SQL NULL, the result is null
1046:             * @exception SQLException if a database-access error occurs.
1047:             */
1048:            public java.sql.Timestamp getTimestamp(String columnName,
1049:                    Calendar cal) throws SQLException {
1050:                checkIfClosed("getTimestamp");
1051:                return getTimestamp(findColumnName(columnName), cal);
1052:            }
1053:
1054:            /**
1055:             * JDBC 2.0
1056:             *
1057:             * Get the value of a column in the current row as a java.sql.Timestamp 
1058:             * object. Use the calendar to construct an appropriate millisecond
1059:             * value for the Timestamp, if the underlying database doesn't store
1060:             * timezone information.
1061:             *
1062:             * @param columnIndex the first column is 1, the second is 2, ...
1063:             * @param cal the calendar to use in constructing the timestamp
1064:             * @return the column value; if the value is SQL NULL, the result is null
1065:             * @exception SQLException if a database-access error occurs.
1066:             */
1067:            public java.sql.Timestamp getTimestamp(int columnIndex, Calendar cal)
1068:                    throws SQLException {
1069:                checkIfClosed("getTimestamp");
1070:                try {
1071:
1072:                    DataValueDescriptor dvd = getColumn(columnIndex);
1073:
1074:                    if (wasNull = dvd.isNull())
1075:                        return null;
1076:
1077:                    if (cal == null)
1078:                        cal = getCal();
1079:                    return dvd.getTimestamp(cal);
1080:
1081:                } catch (StandardException t) {
1082:                    throw noStateChangeException(t);
1083:                }
1084:            }
1085:
1086:            /**
1087:             * JDBC 2.0
1088:             *
1089:             * <p>Get the value of a column in the current row as a java.io.Reader.
1090:             *
1091:             * @exception SQLException database error.
1092:             */
1093:            public final java.io.Reader getCharacterStream(int columnIndex)
1094:                    throws SQLException {
1095:                checkIfClosed("getCharacterStream");
1096:                int lmfs;
1097:                int colType = getColumnType(columnIndex);
1098:                switch (colType) {
1099:                case Types.CHAR:
1100:                case Types.VARCHAR:
1101:                case Types.LONGVARCHAR:
1102:                    lmfs = maxFieldSize;
1103:                    break;
1104:                case Types.CLOB: // Embedded and JCC extension - CLOB is not subject to max field size.
1105:                    lmfs = 0;
1106:                    break;
1107:
1108:                // JDBC says to support these, but no defintion exists for the output.
1109:                // match JCC which treats the bytes as a UTF16-BE stream
1110:                case Types.BINARY:
1111:                case Types.VARBINARY:
1112:                case Types.LONGVARBINARY:
1113:                case Types.BLOB:
1114:                    try {
1115:                        java.io.InputStream is = getBinaryStream(columnIndex);
1116:                        if (is == null)
1117:                            return null;
1118:                        java.io.Reader r = new java.io.InputStreamReader(is,
1119:                                "UTF-16BE");
1120:                        currentStream = r;
1121:                        return r;
1122:                    } catch (java.io.UnsupportedEncodingException uee) {
1123:                        throw new SQLException(uee.getMessage());
1124:                    }
1125:                default:
1126:                    throw dataTypeConversion("java.io.Reader", columnIndex);
1127:                }
1128:
1129:                Object syncLock = getConnectionSynchronization();
1130:
1131:                synchronized (syncLock) {
1132:
1133:                    boolean pushStack = false;
1134:                    try {
1135:
1136:                        useStream(columnIndex);
1137:
1138:                        DataValueDescriptor dvd = getColumn(columnIndex);
1139:
1140:                        if (wasNull = dvd.isNull()) {
1141:                            return null;
1142:                        }
1143:
1144:                        pushStack = true;
1145:                        setupContextStack();
1146:
1147:                        StreamStorable ss = (StreamStorable) dvd;
1148:
1149:                        InputStream stream = ss.returnStream();
1150:
1151:                        if (stream == null) {
1152:
1153:                            String val = dvd.getString();
1154:                            if (lmfs > 0) {
1155:                                if (val.length() > lmfs)
1156:                                    val = val.substring(0, lmfs);
1157:                            }
1158:                            java.io.Reader ret = new java.io.StringReader(val);
1159:                            currentStream = ret;
1160:                            return ret;
1161:                        }
1162:
1163:                        java.io.Reader ret = new UTF8Reader(stream, lmfs, this ,
1164:                                syncLock);
1165:                        currentStream = ret;
1166:                        return ret;
1167:
1168:                    } catch (Throwable t) {
1169:                        throw noStateChangeException(t);
1170:                    } finally {
1171:                        if (pushStack) {
1172:                            restoreContextStack();
1173:                        }
1174:                    }
1175:                }
1176:            }
1177:
1178:            /**
1179:            	Pushes a converter on top of getCharacterStream().
1180:             *
1181:             * @param columnIndex the first column is 1, the second is 2, ...
1182:             * @return a Java input stream that delivers the database column value
1183:             * as a stream of one byte ASCII characters.  If the value is SQL NULL
1184:             * then the result is null.
1185:             * @exception SQLException thrown on failure.
1186:             */
1187:            public final InputStream getAsciiStream(int columnIndex)
1188:                    throws SQLException {
1189:                checkIfClosed("getAsciiStream");
1190:                int colType = getColumnType(columnIndex);
1191:                switch (colType) {
1192:                case Types.CHAR:
1193:                case Types.VARCHAR:
1194:                case Types.LONGVARCHAR:
1195:                case Types.CLOB: // Embedded and JCC extension
1196:                    break;
1197:
1198:                // JDBC says to support these, we match JCC by returning the raw bytes.
1199:                case Types.BINARY:
1200:                case Types.VARBINARY:
1201:                case Types.LONGVARBINARY:
1202:                case Types.BLOB:
1203:                    return getBinaryStream(columnIndex);
1204:
1205:                default:
1206:                    throw dataTypeConversion("java.io.InputStream(ASCII)",
1207:                            columnIndex);
1208:                }
1209:
1210:                java.io.Reader reader = getCharacterStream(columnIndex);
1211:                if (reader == null)
1212:                    return null;
1213:
1214:                return new ReaderToAscii(reader);
1215:            }
1216:
1217:            /**
1218:             * Get the column as an InputStream. If the column is already of type
1219:               InputStream then just return it, otherwise convert the column to a set
1220:               of bytes and create a stream out of the bytes.
1221:             *
1222:             * @param columnIndex the first column is 1, the second is 2, ...
1223:             * @return a Java input stream that delivers the database column value
1224:             * as a stream of uninterpreted bytes.  If the value is SQL NULL
1225:             * then the result is null.
1226:             * @exception SQLException thrown on failure.
1227:             */
1228:            public final InputStream getBinaryStream(int columnIndex)
1229:                    throws SQLException {
1230:                checkIfClosed("getBinaryStream");
1231:                int lmfs;
1232:                int colType = getColumnType(columnIndex);
1233:                switch (colType) {
1234:                case Types.BINARY:
1235:                case Types.VARBINARY:
1236:                case Types.LONGVARBINARY:
1237:                    lmfs = maxFieldSize;
1238:                    break;
1239:                case Types.BLOB:
1240:                    lmfs = 0;
1241:                    break;
1242:
1243:                default:
1244:                    throw dataTypeConversion("java.io.InputStream", columnIndex);
1245:                }
1246:
1247:                Object syncLock = getConnectionSynchronization();
1248:
1249:                synchronized (syncLock) {
1250:
1251:                    boolean pushStack = false;
1252:                    try {
1253:
1254:                        useStream(columnIndex);
1255:
1256:                        DataValueDescriptor dvd = getColumn(columnIndex);
1257:
1258:                        if (wasNull = dvd.isNull()) {
1259:                            return null;
1260:                        }
1261:
1262:                        pushStack = true;
1263:                        setupContextStack();
1264:
1265:                        StreamStorable ss = (StreamStorable) dvd;
1266:
1267:                        InputStream stream = ss.returnStream();
1268:
1269:                        if (stream == null) {
1270:                            stream = new NewByteArrayInputStream(dvd.getBytes());
1271:                        } else {
1272:                            stream = new BinaryToRawStream(stream, dvd);
1273:                        }
1274:
1275:                        if (lmfs > 0) {
1276:                            // Just wrap the InputStream with a LimitInputStream class
1277:                            LimitInputStream limitResultIn = new LimitInputStream(
1278:                                    stream);
1279:                            limitResultIn.setLimit(lmfs);
1280:                            stream = limitResultIn;
1281:                        }
1282:                        currentStream = stream;
1283:                        return stream;
1284:
1285:                    } catch (Throwable t) {
1286:                        throw noStateChangeException(t);
1287:                    } finally {
1288:                        if (pushStack) {
1289:                            restoreContextStack();
1290:                        }
1291:                    }
1292:                }
1293:            }
1294:
1295:            //======================================================================
1296:            // Methods for accessing results by column name
1297:            //======================================================================
1298:
1299:            /**
1300:             * Get the value of a column in the current row as a Java String.
1301:             *
1302:             * @param columnName is the SQL name of the column
1303:             * @return the column value; if the value is SQL NULL, the result is null
1304:             * @exception SQLException thrown on failure.
1305:             */
1306:            public final String getString(String columnName)
1307:                    throws SQLException {
1308:                checkIfClosed("getString");
1309:                return (getString(findColumnName(columnName)));
1310:            }
1311:
1312:            /**
1313:             * Get the value of a column in the current row as a Java boolean.
1314:             *
1315:             * @param columnName is the SQL name of the column
1316:             * @return the column value; if the value is SQL NULL, the result is false
1317:             * @exception SQLException thrown on failure.
1318:             */
1319:            public final boolean getBoolean(String columnName)
1320:                    throws SQLException {
1321:                checkIfClosed("getBoolean");
1322:                return (getBoolean(findColumnName(columnName)));
1323:            }
1324:
1325:            /**
1326:             * Get the value of a column in the current row as a Java byte.
1327:             *
1328:             * @param columnName is the SQL name of the column
1329:             * @return the column value; if the value is SQL NULL, the result is 0
1330:             * @exception SQLException thrown on failure.
1331:             */
1332:            public final byte getByte(String columnName) throws SQLException {
1333:                checkIfClosed("getByte");
1334:                return (getByte(findColumnName(columnName)));
1335:            }
1336:
1337:            /**
1338:             * Get the value of a column in the current row as a Java short.
1339:             *
1340:             * @param columnName is the SQL name of the column
1341:             * @return the column value; if the value is SQL NULL, the result is 0
1342:             * @exception SQLException thrown on failure.
1343:             */
1344:            public final short getShort(String columnName) throws SQLException {
1345:                checkIfClosed("getShort");
1346:                return (getShort(findColumnName(columnName)));
1347:            }
1348:
1349:            /**
1350:             * Get the value of a column in the current row as a Java int.
1351:             *
1352:             * @param columnName is the SQL name of the column
1353:             * @return the column value; if the value is SQL NULL, the result is 0
1354:             * @exception SQLException thrown on failure.
1355:             */
1356:            public final int getInt(String columnName) throws SQLException {
1357:                checkIfClosed("getInt");
1358:                return (getInt(findColumnName(columnName)));
1359:            }
1360:
1361:            /**
1362:             * Get the value of a column in the current row as a Java long.
1363:             *
1364:             * @param columnName is the SQL name of the column
1365:             * @return the column value; if the value is SQL NULL, the result is 0
1366:             * @exception SQLException thrown on failure.
1367:             */
1368:            public final long getLong(String columnName) throws SQLException {
1369:                checkIfClosed("getLong");
1370:                return (getLong(findColumnName(columnName)));
1371:            }
1372:
1373:            /**
1374:             * Get the value of a column in the current row as a Java float.
1375:             *
1376:             * @param columnName is the SQL name of the column
1377:             * @return the column value; if the value is SQL NULL, the result is 0
1378:             * @exception SQLException thrown on failure.
1379:             */
1380:            public final float getFloat(String columnName) throws SQLException {
1381:                checkIfClosed("getFloat");
1382:                return (getFloat(findColumnName(columnName)));
1383:            }
1384:
1385:            /**
1386:             * Get the value of a column in the current row as a Java double.
1387:             *
1388:             * @param columnName is the SQL name of the column
1389:             * @return the column value; if the value is SQL NULL, the result is 0
1390:             * @exception SQLException thrown on failure.
1391:             */
1392:            public final double getDouble(String columnName)
1393:                    throws SQLException {
1394:                checkIfClosed("getDouble");
1395:                return (getDouble(findColumnName(columnName)));
1396:            }
1397:
1398:            /**
1399:             * Get the value of a column in the current row as a Java byte array.
1400:             * The bytes represent the raw values returned by the driver.
1401:             *
1402:             * @param columnName is the SQL name of the column
1403:             * @return the column value; if the value is SQL NULL, the result is null
1404:             * @exception SQLException thrown on failure.
1405:             */
1406:            public final byte[] getBytes(String columnName) throws SQLException {
1407:                checkIfClosed("getBytes");
1408:                return (getBytes(findColumnName(columnName)));
1409:            }
1410:
1411:            /**
1412:             * Get the value of a column in the current row as a java.sql.Date object.
1413:             *
1414:             * @param columnName is the SQL name of the column
1415:             * @return the column value; if the value is SQL NULL, the result is null
1416:             * @exception SQLException thrown on failure.
1417:             */
1418:            public final Date getDate(String columnName) throws SQLException {
1419:                checkIfClosed("getDate");
1420:                return (getDate(findColumnName(columnName)));
1421:            }
1422:
1423:            /**
1424:             * Get the value of a column in the current row as a java.sql.Time object.
1425:             *
1426:             * @param columnName is the SQL name of the column
1427:             * @return the column value; if the value is SQL NULL, the result is null
1428:             * @exception SQLException thrown on failure.
1429:             */
1430:            public final Time getTime(String columnName) throws SQLException {
1431:                checkIfClosed("getTime");
1432:                return (getTime(findColumnName(columnName)));
1433:            }
1434:
1435:            /**
1436:             * Get the value of a column in the current row as a java.sql.Timestamp object.
1437:             *
1438:             * @param columnName is the SQL name of the column
1439:             * @return the column value; if the value is SQL NULL, the result is null
1440:             * @exception SQLException thrown on failure.
1441:             */
1442:            public final Timestamp getTimestamp(String columnName)
1443:                    throws SQLException {
1444:                checkIfClosed("getTimestamp");
1445:                return (getTimestamp(findColumnName(columnName)));
1446:            }
1447:
1448:            /**
1449:             * JDBC 2.0
1450:             *
1451:             * <p>Get the value of a column in the current row as a java.io.Reader.
1452:             *
1453:             * @exception SQLException Feature not implemented for now.
1454:             */
1455:            public final java.io.Reader getCharacterStream(String columnName)
1456:                    throws SQLException {
1457:                checkIfClosed("getCharacterStream");
1458:                return (getCharacterStream(findColumnName(columnName)));
1459:            }
1460:
1461:            /**
1462:             * A column value can be retrieved as a stream of ASCII characters
1463:             * and then read in chunks from the stream.  This method is particularly
1464:             * suitable for retrieving large LONGVARCHAR values.  The JDBC driver will
1465:             * do any necessary conversion from the database format into ASCII.
1466:             *
1467:             * <P><B>Note:</B> All the data in the returned stream must
1468:             * be read prior to getting the value of any other column. The
1469:             * next call to a get method implicitly closes the stream.
1470:             *
1471:             * @param columnName is the SQL name of the column
1472:             * @return a Java input stream that delivers the database column value
1473:             * as a stream of one byte ASCII characters.  If the value is SQL NULL
1474:             * then the result is null.
1475:             * @exception SQLException thrown on failure.
1476:             */
1477:            public final InputStream getAsciiStream(String columnName)
1478:                    throws SQLException {
1479:                checkIfClosed("getAsciiStream");
1480:                return (getAsciiStream(findColumnName(columnName)));
1481:            }
1482:
1483:            /**
1484:             * A column value can be retrieved as a stream of uninterpreted bytes
1485:             * and then read in chunks from the stream.  This method is particularly
1486:             * suitable for retrieving large LONGVARBINARY values.
1487:             *
1488:             * <P><B>Note:</B> All the data in the returned stream must
1489:             * be read prior to getting the value of any other column. The
1490:             * next call to a get method implicitly closes the stream.
1491:             *
1492:             * @param columnName is the SQL name of the column
1493:             * @return a Java input stream that delivers the database column value
1494:             * as a stream of uninterpreted bytes.  If the value is SQL NULL
1495:             * then the result is null.
1496:             * @exception SQLException thrown on failure.
1497:             */
1498:            public final InputStream getBinaryStream(String columnName)
1499:                    throws SQLException {
1500:                checkIfClosed("getBinaryStream");
1501:                return (getBinaryStream(findColumnName(columnName)));
1502:            }
1503:
1504:            /**
1505:             * JDBC 3.0
1506:             * 
1507:             * Retrieves the value of the designated column in the current row of this
1508:             * ResultSet object as a java.net.URL object in the Java programming
1509:             * language.
1510:             * 
1511:             * @param columnIndex -
1512:             *            the first column is 1, the second is 2
1513:             * @return the column value as a java.net.URL object, if the value is SQL
1514:             *         NULL, the value returned is null in the Java programming language
1515:             * @exception SQLException
1516:             *                Feature not implemented for now.
1517:             */
1518:            public URL getURL(int columnIndex) throws SQLException {
1519:                throw Util.notImplemented();
1520:            }
1521:
1522:            /**
1523:             * JDBC 3.0
1524:             * 
1525:             * Retrieves the value of the designated column in the current row of this
1526:             * ResultSet object as a java.net.URL object in the Java programming
1527:             * language.
1528:             * 
1529:             * @param columnName -
1530:             *            the SQL name of the column
1531:             * @return the column value as a java.net.URL object, if the value is SQL
1532:             *         NULL, the value returned is null in the Java programming language
1533:             * @exception SQLException
1534:             *                Feature not implemented for now.
1535:             */
1536:            public URL getURL(String columnName) throws SQLException {
1537:                throw Util.notImplemented();
1538:            }
1539:
1540:            //=====================================================================
1541:            // Advanced features:
1542:            //=====================================================================
1543:
1544:            /**
1545:             * <p>The first warning reported by calls on this ResultSet is
1546:             * returned. Subsequent ResultSet warnings will be chained to this
1547:             * SQLWarning.
1548:             *
1549:             * <P>The warning chain is automatically cleared each time a new
1550:             * row is read.
1551:             *
1552:             * <P><B>Note:</B> This warning chain only covers warnings caused
1553:             * by ResultSet methods.  Any warning caused by statement methods
1554:             * (such as reading OUT parameters) will be chained on the
1555:             * Statement object.
1556:             *
1557:             * @return the first SQLWarning or null
1558:             *
1559:             * @exception SQLException 	Thrown if this ResultSet is closed
1560:             */
1561:            public final SQLWarning getWarnings() throws SQLException {
1562:                checkIfClosed("getWarnings");
1563:                return topWarning;
1564:            }
1565:
1566:            /**
1567:             * After this call getWarnings returns null until a new warning is
1568:             * reported for this ResultSet.
1569:             *
1570:             * @exception SQLException	Thrown if this ResultSet is closed
1571:             */
1572:            public final void clearWarnings() throws SQLException {
1573:                checkIfClosed("clearWarnings");
1574:                topWarning = null;
1575:            }
1576:
1577:            /**
1578:             * Get the name of the SQL cursor used by this ResultSet.
1579:             *
1580:             * <P>In SQL, a result table is retrieved through a cursor that is
1581:             * named. The current row of a result can be updated or deleted
1582:             * using a positioned update/delete statement that references the
1583:             * cursor name.
1584:             *
1585:             * <P>JDBC supports this SQL feature by providing the name of the
1586:             * SQL cursor used by a ResultSet. The current row of a ResultSet
1587:             * is also the current row of this SQL cursor.
1588:             *
1589:             * <P><B>Note:</B> If positioned update is not supported a
1590:             * SQLException is thrown
1591:             *
1592:             * @return the ResultSet's SQL cursor name
1593:             * @exception SQLException thrown on failure.
1594:             */
1595:            public final String getCursorName() throws SQLException {
1596:
1597:                checkIfClosed("getCursorName"); // checking result set closure does not depend
1598:                // on the underlying connection.  Do this
1599:                // outside of the connection synchronization.
1600:
1601:                return theResults.getCursorName();
1602:            }
1603:
1604:            /**
1605:             * The number, types and properties of a ResultSet's columns
1606:             * are provided by the getMetaData method.
1607:             *
1608:             * @return the description of a ResultSet's columns
1609:             * @exception SQLException thrown on failure.
1610:             */
1611:            public ResultSetMetaData getMetaData() throws SQLException {
1612:
1613:                checkIfClosed("getMetaData"); // checking result set closure does not depend
1614:                // on the underlying connection.  Do this
1615:                // outside of the connection synchronization.
1616:
1617:                synchronized (getConnectionSynchronization()) {
1618:
1619:                    if (rMetaData == null) {
1620:                        // cache this object and keep returning it
1621:                        rMetaData = newEmbedResultSetMetaData(resultDescription);
1622:                    }
1623:                    return rMetaData;
1624:                }
1625:            }
1626:
1627:            /**
1628:             * JDBC 4.0
1629:             * 
1630:             * <p>
1631:             * Retrieves the holdability for this <code>ResultSet</code>
1632:             * object.
1633:             * 
1634:             * @return either <code>ResultSet.HOLD_CURSORS_OVER_COMMIT</code>
1635:             *         or <code>ResultSet.CLOSE_CURSORS_AT_COMMIT</code>
1636:             * @exception SQLException
1637:             *                if a database error occurs
1638:             */
1639:            public final int getHoldability() throws SQLException {
1640:                checkIfClosed("getHoldability");
1641:                if (theResults.getActivation().getResultSetHoldability()) {
1642:                    return JDBC30Translation.HOLD_CURSORS_OVER_COMMIT;
1643:                }
1644:                return JDBC30Translation.CLOSE_CURSORS_AT_COMMIT;
1645:            }
1646:
1647:            /**
1648:             * <p>Get the value of a column in the current row as a Java object.
1649:             *
1650:             * <p>This method will return the value of the given column as a
1651:             * Java object.  The type of the Java object will be the default
1652:             * Java Object type corresponding to the column's SQL type,
1653:             * following the mapping specified in the JDBC spec.
1654:             *
1655:             * <p>This method may also be used to read datatabase specific abstract
1656:             * data types.
1657:             *
1658:             * JDBC 2.0
1659:             *
1660:             * New behavior for getObject().
1661:             * The behavior of method getObject() is extended to materialize  
1662:             * data of SQL user-defined types.  When the column @columnIndex is 
1663:             * a structured or distinct value, the behavior of this method is as 
1664:             * if it were a call to: getObject(columnIndex, 
1665:             * this.getStatement().getConnection().getTypeMap()).
1666:             *
1667:             * @param columnIndex the first column is 1, the second is 2, ...
1668:             * @return A java.lang.Object holding the column value.
1669:             * @exception SQLException thrown on failure.
1670:             */
1671:            public final Object getObject(int columnIndex) throws SQLException {
1672:                checkIfClosed("getObject");
1673:
1674:                // need special handling for some types.
1675:                int colType = getColumnType(columnIndex);
1676:                switch (colType) {
1677:                case Types.CHAR:
1678:                case Types.VARCHAR:
1679:                case Types.LONGVARCHAR:
1680:                    // handles maxfield size correctly
1681:                    return getString(columnIndex);
1682:
1683:                case Types.CLOB:
1684:                    return getClob(columnIndex);
1685:
1686:                case Types.BINARY:
1687:                case Types.VARBINARY:
1688:                case Types.LONGVARBINARY:
1689:                    // handles maxfield size correctly
1690:                    return getBytes(columnIndex);
1691:
1692:                case Types.BLOB:
1693:                    return getBlob(columnIndex);
1694:
1695:                default:
1696:                    break;
1697:                }
1698:
1699:                try {
1700:
1701:                    DataValueDescriptor dvd = getColumn(columnIndex);
1702:                    if (wasNull = dvd.isNull())
1703:                        return null;
1704:
1705:                    return dvd.getObject();
1706:
1707:                } catch (StandardException t) {
1708:                    throw noStateChangeException(t);
1709:                }
1710:            }
1711:
1712:            /**
1713:             * <p>Get the value of a column in the current row as a Java object.
1714:             *
1715:             * <p>This method will return the value of the given column as a
1716:             * Java object.  The type of the Java object will be the default
1717:             * Java Object type corresponding to the column's SQL type,
1718:             * following the mapping specified in the JDBC spec.
1719:             *
1720:             * <p>This method may also be used to read datatabase specific abstract
1721:             * data types.
1722:             *
1723:             * JDBC 2.0
1724:             *
1725:             * New behavior for getObject().
1726:             * The behavior of method getObject() is extended to materialize  
1727:             * data of SQL user-defined types.  When the column @columnName is 
1728:             * a structured or distinct value, the behavior of this method is as 
1729:             * if it were a call to: getObject(columnName, 
1730:             * this.getStatement().getConnection().getTypeMap()).
1731:             *
1732:             * @param columnName is the SQL name of the column
1733:             * @return A java.lang.Object holding the column value.
1734:             * @exception SQLException thrown on failure.
1735:             */
1736:            public final Object getObject(String columnName)
1737:                    throws SQLException {
1738:                checkIfClosed("getObject");
1739:                return (getObject(findColumnName(columnName)));
1740:            }
1741:
1742:            //----------------------------------------------------------------
1743:
1744:            /**
1745:             * Map a Resultset column name to a ResultSet column index.
1746:             *
1747:             * @param columnName the name of the column
1748:             * @return the column index
1749:             * @exception SQLException thrown on failure.
1750:             */
1751:            public final int findColumn(String columnName) throws SQLException {
1752:                checkIfClosed("findColumn");
1753:                return findColumnName(columnName);
1754:            }
1755:
1756:            /////////////////////////////////////////////////////////////////////////
1757:            //
1758:            //      JDBC 2.0        -       New public methods
1759:            //
1760:            /////////////////////////////////////////////////////////////////////////
1761:
1762:            //---------------------------------------------------------------------
1763:            // Getter's and Setter's
1764:            //---------------------------------------------------------------------
1765:
1766:            /**
1767:             * JDBC 2.0
1768:             * 
1769:             * Return the Statement that produced the ResultSet.
1770:             * 
1771:             * @return the Statment that produced the result set, or null if the result
1772:             *         was produced some other way.
1773:             * @exception SQLException if a database error occurs or the
1774:             * result set is closed
1775:             */
1776:            public final Statement getStatement() throws SQLException {
1777:                checkIfClosed("getStatement");
1778:                return applicationStmt;
1779:            }
1780:
1781:            /**
1782:             * Set the application Statement object that created this ResultSet.
1783:             * Used when the Statement objects returned to the application
1784:             * are wrapped for XA.
1785:             */
1786:            public final void setApplicationStatement(Statement applicationStmt) {
1787:                this .applicationStmt = applicationStmt;
1788:            }
1789:
1790:            //---------------------------------------------------------------------
1791:            // Traversal/Positioning
1792:            //---------------------------------------------------------------------
1793:
1794:            /**
1795:             * JDBC 2.0
1796:             * 
1797:             * <p>
1798:             * Determine if the cursor is before the first row in the result set.
1799:             * 
1800:             * @return true if before the first row, false otherwise. Returns false when
1801:             *         the result set contains no rows.
1802:             * @exception SQLException
1803:             *                Thrown on error.
1804:             */
1805:            public boolean isBeforeFirst() throws SQLException {
1806:                return checkRowPosition(ResultSet.ISBEFOREFIRST,
1807:                        "isBeforeFirst");
1808:            }
1809:
1810:            /**
1811:             * JDBC 2.0
1812:             * 
1813:             * <p>
1814:             * Determine if the cursor is after the last row in the result set.
1815:             * 
1816:             * @return true if after the last row, false otherwise. Returns false when
1817:             *         the result set contains no rows.
1818:             * @exception SQLException
1819:             *                Thrown on error.
1820:             */
1821:            public boolean isAfterLast() throws SQLException {
1822:                return checkRowPosition(ResultSet.ISAFTERLAST, "isAfterLast");
1823:            }
1824:
1825:            /**
1826:             * JDBC 2.0
1827:             * 
1828:             * <p>
1829:             * Determine if the cursor is on the first row of the result set.
1830:             * 
1831:             * @return true if on the first row, false otherwise.
1832:             * @exception SQLException
1833:             *                Thrown on error.
1834:             */
1835:            public boolean isFirst() throws SQLException {
1836:                return checkRowPosition(ResultSet.ISFIRST, "isFirst");
1837:            }
1838:
1839:            /**
1840:             * JDBC 2.0
1841:             * 
1842:             * <p>
1843:             * Determine if the cursor is on the last row of the result set. Note:
1844:             * Calling isLast() may be expensive since the JDBC driver might need to
1845:             * fetch ahead one row in order to determine whether the current row is the
1846:             * last row in the result set.
1847:             * 
1848:             * @return true if on the last row, false otherwise.
1849:             * @exception SQLException
1850:             *                Thrown on error.
1851:             */
1852:            public boolean isLast() throws SQLException {
1853:                return checkRowPosition(ResultSet.ISLAST, "isLast");
1854:            }
1855:
1856:            /**
1857:             * JDBC 2.0
1858:             * 
1859:             * <p>
1860:             * Moves to the front of the result set, just before the first row. Has no
1861:             * effect if the result set contains no rows.
1862:             * 
1863:             * @exception SQLException
1864:             *                if a database-access error occurs, or result set type is
1865:             *                TYPE_FORWARD_ONLY
1866:             */
1867:            public void beforeFirst() throws SQLException {
1868:                // beforeFirst is only allowed on scroll cursors
1869:                checkScrollCursor("beforeFirst()");
1870:                movePosition(BEFOREFIRST, "beforeFirst");
1871:            }
1872:
1873:            /**
1874:             * JDBC 2.0
1875:             * 
1876:             * <p>
1877:             * Moves to the end of the result set, just after the last row. Has no
1878:             * effect if the result set contains no rows.
1879:             * 
1880:             * @exception SQLException
1881:             *                if a database-access error occurs, or result set type is
1882:             *                TYPE_FORWARD_ONLY.
1883:             */
1884:            public void afterLast() throws SQLException {
1885:                // afterLast is only allowed on scroll cursors
1886:                checkScrollCursor("afterLast()");
1887:                movePosition(AFTERLAST, "afterLast");
1888:            }
1889:
1890:            /**
1891:             * JDBC 2.0
1892:             * 
1893:             * <p>
1894:             * Moves to the first row in the result set.
1895:             * 
1896:             * @return true if on a valid row, false if no rows in the result set.
1897:             * @exception SQLException
1898:             *                if a database-access error occurs, or result set type is
1899:             *                TYPE_FORWARD_ONLY.
1900:             */
1901:            public boolean first() throws SQLException {
1902:                // first is only allowed on scroll cursors
1903:                checkScrollCursor("first()");
1904:                return movePosition(FIRST, "first");
1905:            }
1906:
1907:            /**
1908:             * JDBC 2.0
1909:             * 
1910:             * <p>
1911:             * Moves to the last row in the result set.
1912:             * 
1913:             * @return true if on a valid row, false if no rows in the result set.
1914:             * @exception SQLException
1915:             *                if a database-access error occurs, or result set type is
1916:             *                TYPE_FORWARD_ONLY.
1917:             */
1918:            public boolean last() throws SQLException {
1919:                // last is only allowed on scroll cursors
1920:                checkScrollCursor("last()");
1921:                return movePosition(LAST, "last");
1922:            }
1923:
1924:            /**
1925:             * JDBC 2.0
1926:             * 
1927:             * <p>
1928:             * Determine the current row number. The first row is number 1, the second
1929:             * number 2, etc.
1930:             * 
1931:             * @return the current row number, else return 0 if there is no current row
1932:             * @exception SQLException
1933:             *                if a database-access error occurs.
1934:             */
1935:            public int getRow() throws SQLException {
1936:                // getRow() is only allowed on scroll cursors
1937:                checkScrollCursor("getRow()");
1938:
1939:                /*
1940:                 * * We probably needn't bother getting the text of * the underlying
1941:                 * statement but it is better to be * consistent and we aren't
1942:                 * particularly worried * about performance of getRow().
1943:                 */
1944:                return theResults.getRowNumber();
1945:            }
1946:
1947:            /**
1948:             * JDBC 2.0
1949:             * 
1950:             * <p>
1951:             * Move to an absolute row number in the result set.
1952:             * 
1953:             * <p>
1954:             * If row is positive, moves to an absolute row with respect to the
1955:             * beginning of the result set. The first row is row 1, the second is row 2,
1956:             * etc.
1957:             * 
1958:             * <p>
1959:             * If row is negative, moves to an absolute row position with respect to the
1960:             * end of result set. For example, calling absolute(-1) positions the cursor
1961:             * on the last row, absolute(-2) indicates the next-to-last row, etc.
1962:             * 
1963:             * <p>
1964:             * An attempt to position the cursor beyond the first/last row in the result
1965:             * set, leaves the cursor before/after the first/last row, respectively.
1966:             * 
1967:             * <p>
1968:             * Note: Calling absolute(1) is the same as calling first(). Calling
1969:             * absolute(-1) is the same as calling last().
1970:             * 
1971:             * @return true if on the result set, false if off.
1972:             * @exception SQLException
1973:             *                if a database-access error occurs, or row is 0, or result
1974:             *                set type is TYPE_FORWARD_ONLY.
1975:             */
1976:            public boolean absolute(int row) throws SQLException {
1977:                // absolute is only allowed on scroll cursors
1978:                checkScrollCursor("absolute()");
1979:                return movePosition(ABSOLUTE, row, "absolute");
1980:            }
1981:
1982:            /**
1983:             * JDBC 2.0
1984:             * 
1985:             * <p>
1986:             * Moves a relative number of rows, either positive or negative. Attempting
1987:             * to move beyond the first/last row in the result set positions the cursor
1988:             * before/after the the first/last row. Calling relative(0) is valid, but
1989:             * does not change the cursor position.
1990:             * 
1991:             * <p>
1992:             * Note: Calling relative(1) is different than calling next() since is makes
1993:             * sense to call next() when there is no current row, for example, when the
1994:             * cursor is positioned before the first row or after the last row of the
1995:             * result set.
1996:             * 
1997:             * @return true if on a row, false otherwise.
1998:             * @exception SQLException
1999:             *                if a database-access error occurs, or there is no current
2000:             *                row, or result set type is TYPE_FORWARD_ONLY.
2001:             */
2002:            public boolean relative(int row) throws SQLException {
2003:                // absolute is only allowed on scroll cursors
2004:                checkScrollCursor("relative()");
2005:                return movePosition(RELATIVE, row, "relative");
2006:            }
2007:
2008:            /**
2009:             * JDBC 2.0
2010:             * 
2011:             * <p>
2012:             * Moves to the previous row in the result set.
2013:             * 
2014:             * <p>
2015:             * Note: previous() is not the same as relative(-1) since it makes sense to
2016:             * call previous() when there is no current row.
2017:             * 
2018:             * @return true if on a valid row, false if off the result set.
2019:             * @exception SQLException
2020:             *                if a database-access error occurs, or result set type is
2021:             *                TYPE_FORWAR_DONLY.
2022:             */
2023:            public boolean previous() throws SQLException {
2024:                // previous is only allowed on scroll cursors
2025:                checkScrollCursor("previous()");
2026:                return movePosition(PREVIOUS, "previous");
2027:            }
2028:
2029:            //---------------------------------------------------------------------
2030:            // Properties
2031:            //---------------------------------------------------------------------
2032:
2033:            /**
2034:             * JDBC 2.0
2035:             * 
2036:             * Give a hint as to the direction in which the rows in this result set will
2037:             * be processed. The initial value is determined by the statement that
2038:             * produced the result set. The fetch direction may be changed at any time.
2039:             * 
2040:             * @exception SQLException
2041:             *                if a database-access error occurs, or the result set type
2042:             *                is TYPE_FORWARD_ONLY and direction is not FETCH_FORWARD.
2043:             */
2044:            public void setFetchDirection(int direction) throws SQLException {
2045:                checkScrollCursor("setFetchDirection()");
2046:                /*
2047:                 * FetchDirection is meaningless to us. We just save it off and return
2048:                 * the current value if asked.
2049:                 */
2050:                fetchDirection = direction;
2051:            }
2052:
2053:            /**
2054:             * JDBC 2.0
2055:             * 
2056:             * Return the fetch direction for this result set.
2057:             * 
2058:             * @exception SQLException
2059:             *                if a database-access error occurs
2060:             */
2061:            public int getFetchDirection() throws SQLException {
2062:                checkIfClosed("getFetchDirection");
2063:                if (fetchDirection == 0) {
2064:                    // value is not set at the result set level
2065:                    // get it from the statement level
2066:                    return stmt.getFetchDirection();
2067:                } else
2068:                    return fetchDirection;
2069:            }
2070:
2071:            /**
2072:             * JDBC 2.0
2073:             * 
2074:             * Give the JDBC driver a hint as to the number of rows that should be
2075:             * fetched from the database when more rows are needed for this result set.
2076:             * If the fetch size specified is zero, then the JDBC driver ignores the
2077:             * value, and is free to make its own best guess as to what the fetch size
2078:             * should be. The default value is set by the statement that creates the
2079:             * result set. The fetch size may be changed at any time.
2080:             * 
2081:             * @param rows
2082:             *            the number of rows to fetch
2083:             * @exception SQLException
2084:             *                if a database-access error occurs, or the condition 0 <=
2085:             *                rows <= this.getMaxRows() is not satisfied.
2086:             */
2087:            public void setFetchSize(int rows) throws SQLException {
2088:                checkIfClosed("setFetchSize");
2089:                if (rows < 0
2090:                        || (stmt.getMaxRows() != 0 && rows > stmt.getMaxRows())) {
2091:                    throw Util.generateCsSQLException(
2092:                            SQLState.INVALID_FETCH_SIZE, new Integer(rows));
2093:                } else if (rows > 0) // if it is zero ignore the call
2094:                {
2095:                    fetchSize = rows;
2096:                }
2097:            }
2098:
2099:            /**
2100:             * JDBC 2.0
2101:             * 
2102:             * Return the fetch size for this result set.
2103:             * 
2104:             * @exception SQLException
2105:             *                if a database-access error occurs
2106:             */
2107:            public int getFetchSize() throws SQLException {
2108:                checkIfClosed("getFetchSize");
2109:                if (fetchSize == 0) {
2110:                    // value is not set at the result set level
2111:                    //  get the default value from the statement
2112:                    return stmt.getFetchSize();
2113:                } else
2114:                    return fetchSize;
2115:            }
2116:
2117:            /**
2118:             * JDBC 2.0
2119:             * 
2120:             * Return the type of this result set. The type is determined based on the
2121:             * statement that created the result set.
2122:             * 
2123:             * @return TYPE_FORWARD_ONLY, TYPE_SCROLL_INSENSITIVE, or
2124:             *         TYPE_SCROLL_SENSITIVE
2125:             * @exception SQLException
2126:             *                if a database-access error occurs
2127:             */
2128:            public int getType() throws SQLException {
2129:                checkIfClosed("getType");
2130:                return stmt.getResultSetType();
2131:            }
2132:
2133:            /**
2134:             * JDBC 2.0
2135:             * 
2136:             * Return the concurrency of this result set. The concurrency is determined
2137:             * as follows If Statement object has CONCUR_READ_ONLY concurrency, then
2138:             * ResultSet object will also have the CONCUR_READ_ONLY concurrency. But if
2139:             * Statement object has CONCUR_UPDATABLE concurrency, then the concurrency
2140:             * of ResultSet object depends on whether the underlying language resultset
2141:             * is updatable or not. If the language resultset is updatable, then JDBC
2142:             * ResultSet object will also have the CONCUR_UPDATABLE concurrency. If
2143:             * lanugage resultset is not updatable, then JDBC ResultSet object
2144:             * concurrency will be set to CONCUR_READ_ONLY.
2145:             * 
2146:             * @return the concurrency type, CONCUR_READ_ONLY, etc.
2147:             * @exception SQLException
2148:             *                if a database-access error occurs
2149:             */
2150:            public int getConcurrency() throws SQLException {
2151:                checkIfClosed("getConcurrency");
2152:                return concurrencyOfThisResultSet;
2153:            }
2154:
2155:            //---------------------------------------------------------------------
2156:            // Updates
2157:            //---------------------------------------------------------------------
2158:
2159:            /**
2160:             * JDBC 2.0
2161:             * 
2162:             * Determine if the current row has been updated. The value returned depends
2163:             * on whether or not the result set can detect updates.
2164:             * 
2165:             * @return true if the row has been visibly updated by the owner or another,
2166:             *         and updates are detected
2167:             * @exception SQLException
2168:             *                if a database-access error occurs
2169:             * 
2170:             * @see EmbedDatabaseMetaData#updatesAreDetected
2171:             */
2172:            public boolean rowUpdated() throws SQLException {
2173:                checkIfClosed("rowUpdated");
2174:                checkNotOnInsertRow();
2175:                checkOnRow();
2176:
2177:                boolean rvalue = false;
2178:
2179:                try {
2180:                    if (isForUpdate()
2181:                            && getType() == java.sql.ResultSet.TYPE_SCROLL_INSENSITIVE) {
2182:                        rvalue = ((ScrollInsensitiveResultSet) theResults)
2183:                                .isUpdated();
2184:                    }
2185:                } catch (Throwable t) {
2186:                    handleException(t);
2187:                }
2188:                return rvalue;
2189:            }
2190:
2191:            /**
2192:             * JDBC 2.0
2193:             * 
2194:             * Determine if the current row has been inserted. The value returned
2195:             * depends on whether or not the result set can detect visible inserts.
2196:             * 
2197:             * @return true if inserted and inserts are detected
2198:             * @exception SQLException
2199:             *                if a database-access error occurs
2200:             * 
2201:             * @see EmbedDatabaseMetaData#insertsAreDetected
2202:             */
2203:            public boolean rowInserted() throws SQLException {
2204:                checkIfClosed("rowInserted");
2205:                checkNotOnInsertRow();
2206:                checkOnRow();
2207:
2208:                return false;
2209:            }
2210:
2211:            /**
2212:             * JDBC 2.0
2213:             *
2214:             * Determine if this row has been deleted. A deleted row may leave a visible
2215:             * "hole" in a result set. This method can be used to detect holes in a
2216:             * result set. The value returned depends on whether or not the result set
2217:             * can detect deletions.
2218:             *
2219:             * @return true if deleted and deletes are detected
2220:             * @exception SQLException
2221:             *                if a database-access error occurs
2222:             *
2223:             * @see EmbedDatabaseMetaData#deletesAreDetected
2224:             */
2225:            public boolean rowDeleted() throws SQLException {
2226:                checkIfClosed("rowUpdated");
2227:                checkNotOnInsertRow();
2228:                checkOnRow();
2229:
2230:                boolean rvalue = false;
2231:
2232:                try {
2233:                    if (isForUpdate()
2234:                            && getType() == java.sql.ResultSet.TYPE_SCROLL_INSENSITIVE) {
2235:                        rvalue = ((ScrollInsensitiveResultSet) theResults)
2236:                                .isDeleted();
2237:                    }
2238:                } catch (Throwable t) {
2239:                    handleException(t);
2240:                }
2241:                return rvalue;
2242:            }
2243:
2244:            //do following few checks before accepting updateXXX resultset api
2245:            protected void checksBeforeUpdateXXX(String methodName,
2246:                    int columnIndex) throws SQLException {
2247:                checksBeforeUpdateOrDelete(methodName, columnIndex);
2248:
2249:                //1)Make sure for updateXXX methods, the column position is not out of range
2250:                ResultDescription rd = theResults.getResultDescription();
2251:                if (columnIndex < 1 || columnIndex > rd.getColumnCount())
2252:                    throw Util.generateCsSQLException(
2253:                            SQLState.LANG_INVALID_COLUMN_POSITION, new Integer(
2254:                                    columnIndex), String.valueOf(rd
2255:                                    .getColumnCount()));
2256:
2257:                //2)Make sure the column corresponds to a column in the base table and it is not a derived column
2258:                if (rd.getColumnDescriptor(columnIndex).getSourceTableName() == null)
2259:                    throw Util.generateCsSQLException(
2260:                            SQLState.COLUMN_NOT_FROM_BASE_TABLE, methodName);
2261:
2262:                //3)If column not updatable then throw an exception
2263:                if (!getMetaData().isWritable(columnIndex))
2264:                    throw Util
2265:                            .generateCsSQLException(
2266:                                    SQLState.LANG_COLUMN_NOT_UPDATABLE_IN_CURSOR,
2267:                                    theResults.getResultDescription()
2268:                                            .getColumnDescriptor(columnIndex)
2269:                                            .getName(), getCursorName());
2270:            }
2271:
2272:            //do following few checks before accepting updateRow or deleteRow
2273:            //1)Make sure JDBC ResultSet is not closed
2274:            //2)Make sure this is an updatable ResultSet
2275:            //3)Make sure JDBC ResultSet is positioned on a row
2276:            //4)Make sure underneath language resultset is not closed
2277:            protected void checksBeforeUpdateOrDelete(String methodName,
2278:                    int columnIndex) throws SQLException {
2279:
2280:                //1)Make sure JDBC ResultSet is not closed
2281:                checkIfClosed(methodName);
2282:
2283:                //2)Make sure this is an updatable ResultSet
2284:                checkUpdatableCursor(methodName);
2285:
2286:                //3)Make sure JDBC ResultSet is positioned on a row
2287:                if (!isOnInsertRow)
2288:                    checkOnRow(); // make sure there's a current row
2289:                //in case of autocommit on, if there was an exception which caused runtime rollback in this transaction prior to this call,
2290:                //the rollback code will mark the language resultset closed (it doesn't mark the JDBC ResultSet closed).
2291:                //That is why alongwith the earlier checkIfClosed call in this method, there is a check for language resultset close as well.
2292:
2293:                //4)Make sure underneath language resultset is not closed
2294:                if (theResults.isClosed())
2295:                    throw Util.generateCsSQLException(
2296:                            SQLState.LANG_RESULT_SET_NOT_OPEN, methodName);
2297:            }
2298:
2299:            //mark the column as updated and return DataValueDescriptor for it. It will be used by updateXXX methods to put new values
2300:            protected DataValueDescriptor getDVDforColumnToBeUpdated(
2301:                    int columnIndex, String updateMethodName)
2302:                    throws StandardException, SQLException {
2303:                checksBeforeUpdateXXX(updateMethodName, columnIndex);
2304:                columnGotUpdated[columnIndex - 1] = true;
2305:                currentRowHasBeenUpdated = true;
2306:
2307:                return updateRow.getColumn(columnIndex);
2308:            }
2309:
2310:            /* do following few checks before accepting insertRow
2311:             * 1) Make sure JDBC ResultSet is not closed
2312:             * 2) Make sure this is an updatable ResultSet
2313:             * 3) Make sure JDBC ResultSet is positioned on insertRow
2314:             * 4) Make sure underneath language resultset is not closed
2315:             */
2316:            protected void checksBeforeInsert() throws SQLException {
2317:                // 1)Make sure JDBC ResultSet is not closed
2318:                checkIfClosed("insertRow");
2319:
2320:                // 2)Make sure this is an updatable ResultSet
2321:                // if not updatable resultset, then throw exception
2322:                checkUpdatableCursor("insertRow");
2323:
2324:                // 3)Make sure JDBC ResultSet is positioned on insertRow
2325:                if (!isOnInsertRow) {
2326:                    throw newSQLException(SQLState.CURSOR_NOT_POSITIONED_ON_INSERT_ROW);
2327:                }
2328:
2329:                // 4)Make sure underneath language resultset is not closed
2330:                if (theResults.isClosed()) {
2331:                    throw Util.generateCsSQLException(
2332:                            SQLState.LANG_RESULT_SET_NOT_OPEN, "insertRow");
2333:                }
2334:            }
2335:
2336:            /**
2337:             * Check whether it is OK to update a column using
2338:             * <code>updateAsciiStream()</code>.
2339:             *
2340:             * @param columnIndex the column index (first column is 1)
2341:             * @exception SQLException if the column could not be updated with
2342:             * <code>updateAsciiStream()</code>
2343:             */
2344:            private void checksBeforeUpdateAsciiStream(int columnIndex)
2345:                    throws SQLException {
2346:                checksBeforeUpdateXXX("updateAsciiStream", columnIndex);
2347:                int colType = getColumnType(columnIndex);
2348:                if (!DataTypeDescriptor.isAsciiStreamAssignable(colType)) {
2349:                    throw dataTypeConversion(columnIndex, "java.io.InputStream");
2350:                }
2351:            }
2352:
2353:            /**
2354:             * Check whether it is OK to update a column using
2355:             * <code>updateBinaryStream()</code>.
2356:             *
2357:             * @param columnIndex the column index (first column is 1)
2358:             * @exception SQLException if the column could not be updated with
2359:             * <code>updateBinaryStream()</code>
2360:             */
2361:            private void checksBeforeUpdateBinaryStream(int columnIndex)
2362:                    throws SQLException {
2363:                checksBeforeUpdateXXX("updateBinaryStream", columnIndex);
2364:                int colType = getColumnType(columnIndex);
2365:                if (!DataTypeDescriptor.isBinaryStreamAssignable(colType)) {
2366:                    throw dataTypeConversion(columnIndex, "java.io.InputStream");
2367:                }
2368:            }
2369:
2370:            /**
2371:             * Check whether it is OK to update a column using
2372:             * <code>updateCharacterStream()</code>.
2373:             *
2374:             * @param columnIndex the column index (first column is 1)
2375:             * @exception SQLException if the column could not be updated with
2376:             * <code>updateCharacterStream()</code>
2377:             */
2378:            private void checksBeforeUpdateCharacterStream(int columnIndex)
2379:                    throws SQLException {
2380:                checksBeforeUpdateXXX("updateCharacterStream", columnIndex);
2381:                int colType = getColumnType(columnIndex);
2382:                if (!DataTypeDescriptor.isCharacterStreamAssignable(colType)) {
2383:                    throw dataTypeConversion(columnIndex, "java.io.Reader");
2384:                }
2385:            }
2386:
2387:            /**
2388:             * JDBC 2.0
2389:             * 
2390:             * Give a nullable column a null value.
2391:             * 
2392:             * The updateXXX() methods are used to update column values in the current
2393:             * row, or the insert row. The updateXXX() methods do not update the
2394:             * underlying database, instead the updateRow() or insertRow() methods are
2395:             * called to update the database.
2396:             * 
2397:             * @param columnIndex
2398:             *            the first column is 1, the second is 2, ...
2399:             * @exception SQLException
2400:             *                if a database-access error occurs
2401:             */
2402:            public void updateNull(int columnIndex) throws SQLException {
2403:                try {
2404:                    getDVDforColumnToBeUpdated(columnIndex, "updateNull")
2405:                            .setToNull();
2406:                } catch (StandardException t) {
2407:                    throw noStateChangeException(t);
2408:                }
2409:            }
2410:
2411:            /**
2412:             * JDBC 2.0
2413:             *
2414:             * Update a column with a boolean value.
2415:             *
2416:             * The updateXXX() methods are used to update column values in the current
2417:             * row, or the insert row. The updateXXX() methods do not update the
2418:             * underlying database, instead the updateRow() or insertRow() methods are
2419:             * called to update the database.
2420:             *
2421:             * @param columnIndex
2422:             *            the first column is 1, the second is 2, ...
2423:             * @param x
2424:             *            the new column value
2425:             * @exception SQLException
2426:             *                if a database-access error occurs
2427:             */
2428:            public void updateBoolean(int columnIndex, boolean x)
2429:                    throws SQLException {
2430:                try {
2431:                    getDVDforColumnToBeUpdated(columnIndex, "updateBoolean")
2432:                            .setValue(x);
2433:                } catch (StandardException t) {
2434:                    throw noStateChangeException(t);
2435:                }
2436:            }
2437:
2438:            /**
2439:             * JDBC 2.0
2440:             *
2441:             * Update a column with a byte value.
2442:             *
2443:             * The updateXXX() methods are used to update column values in the current
2444:             * row, or the insert row. The updateXXX() methods do not update the
2445:             * underlying database, instead the updateRow() or insertRow() methods are
2446:             * called to update the database.
2447:             *
2448:             * @param columnIndex
2449:             *            the first column is 1, the second is 2, ...
2450:             * @param x
2451:             *            the new column value
2452:             * @exception SQLException
2453:             *                if a database-access error occurs
2454:             */
2455:            public void updateByte(int columnIndex, byte x) throws SQLException {
2456:                try {
2457:                    getDVDforColumnToBeUpdated(columnIndex, "updateByte")
2458:                            .setValue(x);
2459:                } catch (StandardException t) {
2460:                    throw noStateChangeException(t);
2461:                }
2462:            }
2463:
2464:            /**
2465:             * JDBC 2.0
2466:             *
2467:             * Update a column with a short value.
2468:             *
2469:             * The updateXXX() methods are used to update column values in the current
2470:             * row, or the insert row. The updateXXX() methods do not update the
2471:             * underlying database, instead the updateRow() or insertRow() methods are
2472:             * called to update the database.
2473:             *
2474:             * @param columnIndex
2475:             *            the first column is 1, the second is 2, ...
2476:             * @param x
2477:             *            the new column value
2478:             * @exception SQLException
2479:             *                if a database-access error occurs
2480:             */
2481:            public void updateShort(int columnIndex, short x)
2482:                    throws SQLException {
2483:                try {
2484:                    getDVDforColumnToBeUpdated(columnIndex, "updateShort")
2485:                            .setValue(x);
2486:                } catch (StandardException t) {
2487:                    throw noStateChangeException(t);
2488:                }
2489:            }
2490:
2491:            /**
2492:             * JDBC 2.0
2493:             *
2494:             * Update a column with an integer value.
2495:             *
2496:             * The updateXXX() methods are used to update column values in the current
2497:             * row, or the insert row. The updateXXX() methods do not update the
2498:             * underlying database, instead the updateRow() or insertRow() methods are
2499:             * called to update the database.
2500:             *
2501:             * @param columnIndex
2502:             *            the first column is 1, the second is 2, ...
2503:             * @param x
2504:             *            the new column value
2505:             * @exception SQLException
2506:             *                if a database-access error occurs
2507:             */
2508:            public void updateInt(int columnIndex, int x) throws SQLException {
2509:                try {
2510:                    getDVDforColumnToBeUpdated(columnIndex, "updateInt")
2511:                            .setValue(x);
2512:                } catch (StandardException t) {
2513:                    throw noStateChangeException(t);
2514:                }
2515:            }
2516:
2517:            /**
2518:             * JDBC 2.0
2519:             *
2520:             * Update a column with a long value.
2521:             *
2522:             * The updateXXX() methods are used to update column values in the current
2523:             * row, or the insert row. The updateXXX() methods do not update the
2524:             * underlying database, instead the updateRow() or insertRow() methods are
2525:             * called to update the database.
2526:             *
2527:             * @param columnIndex
2528:             *            the first column is 1, the second is 2, ...
2529:             * @param x
2530:             *            the new column value
2531:             * @exception SQLException
2532:             *                if a database-access error occurs
2533:             */
2534:            public void updateLong(int columnIndex, long x) throws SQLException {
2535:                try {
2536:                    getDVDforColumnToBeUpdated(columnIndex, "updateLong")
2537:                            .setValue(x);
2538:                } catch (StandardException t) {
2539:                    throw noStateChangeException(t);
2540:                }
2541:            }
2542:
2543:            /**
2544:             * JDBC 2.0
2545:             *
2546:             * Update a column with a float value.
2547:             *
2548:             * The updateXXX() methods are used to update column values in the current
2549:             * row, or the insert row. The updateXXX() methods do not update the
2550:             * underlying database, instead the updateRow() or insertRow() methods are
2551:             * called to update the database.
2552:             *
2553:             * @param columnIndex
2554:             *            the first column is 1, the second is 2, ...
2555:             * @param x
2556:             *            the new column value
2557:             * @exception SQLException
2558:             *                if a database-access error occurs
2559:             */
2560:            public void updateFloat(int columnIndex, float x)
2561:                    throws SQLException {
2562:                try {
2563:                    getDVDforColumnToBeUpdated(columnIndex, "updateFloat")
2564:                            .setValue(x);
2565:                } catch (StandardException t) {
2566:                    throw noStateChangeException(t);
2567:                }
2568:            }
2569:
2570:            /**
2571:             * JDBC 2.0
2572:             *
2573:             * Update a column with a Double value.
2574:             *
2575:             * The updateXXX() methods are used to update column values in the current
2576:             * row, or the insert row. The updateXXX() methods do not update the
2577:             * underlying database, instead the updateRow() or insertRow() methods are
2578:             * called to update the database.
2579:             * 
2580:             * @param columnIndex
2581:             *            the first column is 1, the second is 2, ...
2582:             * @param x
2583:             *            the new column value
2584:             * @exception SQLException
2585:             *                if a database-access error occurs
2586:             */
2587:            public void updateDouble(int columnIndex, double x)
2588:                    throws SQLException {
2589:                try {
2590:                    getDVDforColumnToBeUpdated(columnIndex, "updateDouble")
2591:                            .setValue(x);
2592:                } catch (StandardException t) {
2593:                    throw noStateChangeException(t);
2594:                }
2595:            }
2596:
2597:            /**
2598:             * JDBC 2.0
2599:             * 
2600:             * Update a column with a String value.
2601:             * 
2602:             * The updateXXX() methods are used to update column values in the current
2603:             * row, or the insert row. The updateXXX() methods do not update the
2604:             * underlying database, instead the updateRow() or insertRow() methods are
2605:             * called to update the database.
2606:             * 
2607:             * @param columnIndex
2608:             *            the first column is 1, the second is 2, ...
2609:             * @param x
2610:             *            the new column value
2611:             * @exception SQLException
2612:             *                if a database-access error occurs
2613:             */
2614:            public void updateString(int columnIndex, String x)
2615:                    throws SQLException {
2616:                try {
2617:                    getDVDforColumnToBeUpdated(columnIndex, "updateString")
2618:                            .setValue(x);
2619:                } catch (StandardException t) {
2620:                    throw noStateChangeException(t);
2621:                }
2622:            }
2623:
2624:            /**
2625:             * JDBC 2.0
2626:             * 
2627:             * Update a column with a byte array value.
2628:             * 
2629:             * The updateXXX() methods are used to update column values in the current
2630:             * row, or the insert row. The updateXXX() methods do not update the
2631:             * underlying database, instead the updateRow() or insertRow() methods are
2632:             * called to update the database.
2633:             * 
2634:             * @param columnIndex
2635:             *            the first column is 1, the second is 2, ...
2636:             * @param x
2637:             *            the new column value
2638:             * @exception SQLException
2639:             *                if a database-access error occurs
2640:             */
2641:            public void updateBytes(int columnIndex, byte x[])
2642:                    throws SQLException {
2643:                try {
2644:                    getDVDforColumnToBeUpdated(columnIndex, "updateBytes")
2645:                            .setValue(x);
2646:                } catch (StandardException t) {
2647:                    throw noStateChangeException(t);
2648:                }
2649:            }
2650:
2651:            /**
2652:             * JDBC 2.0
2653:             *
2654:             * Update a column with a Date value.
2655:             *
2656:             * The updateXXX() methods are used to update column values in the current
2657:             * row, or the insert row. The updateXXX() methods do not update the
2658:             * underlying database, instead the updateRow() or insertRow() methods are
2659:             * called to update the database.
2660:             *
2661:             * @param columnIndex
2662:             *            the first column is 1, the second is 2, ...
2663:             * @param x
2664:             *            the new column value
2665:             * @exception SQLException
2666:             *                if a database-access error occurs
2667:             */
2668:            public void updateDate(int columnIndex, java.sql.Date x)
2669:                    throws SQLException {
2670:                try {
2671:                    getDVDforColumnToBeUpdated(columnIndex, "updateDate")
2672:                            .setValue(x);
2673:                } catch (StandardException t) {
2674:                    throw noStateChangeException(t);
2675:                }
2676:            }
2677:
2678:            /**
2679:             * JDBC 2.0
2680:             *
2681:             * Update a column with a Time value.
2682:             *
2683:             * The updateXXX() methods are used to update column values in the current
2684:             * row, or the insert row. The updateXXX() methods do not update the
2685:             * underlying database, instead the updateRow() or insertRow() methods are
2686:             * called to update the database.
2687:             *
2688:             * @param columnIndex
2689:             *            the first column is 1, the second is 2, ...
2690:             * @param x
2691:             *            the new column value
2692:             * @exception SQLException
2693:             *                if a database-access error occurs
2694:             */
2695:            public void updateTime(int columnIndex, java.sql.Time x)
2696:                    throws SQLException {
2697:                try {
2698:                    getDVDforColumnToBeUpdated(columnIndex, "updateTime")
2699:                            .setValue(x);
2700:                } catch (StandardException t) {
2701:                    throw noStateChangeException(t);
2702:                }
2703:            }
2704:
2705:            /**
2706:             * JDBC 2.0
2707:             *
2708:             * Update a column with a Timestamp value.
2709:             *
2710:             * The updateXXX() methods are used to update column values in the current
2711:             * row, or the insert row. The updateXXX() methods do not update the
2712:             * underlying database, instead the updateRow() or insertRow() methods are
2713:             * called to update the database.
2714:             *
2715:             * @param columnIndex
2716:             *            the first column is 1, the second is 2, ...
2717:             * @param x
2718:             *            the new column value
2719:             * @exception SQLException
2720:             *                if a database-access error occurs
2721:             */
2722:            public void updateTimestamp(int columnIndex, java.sql.Timestamp x)
2723:                    throws SQLException {
2724:                try {
2725:                    getDVDforColumnToBeUpdated(columnIndex, "updateTimestamp")
2726:                            .setValue(x);
2727:                } catch (StandardException t) {
2728:                    throw noStateChangeException(t);
2729:                }
2730:            }
2731:
2732:            /**
2733:             *
2734:             * Update a column with an ascii stream value.
2735:             *
2736:             * The updateXXX() methods are used to update column values in the current
2737:             * row, or the insert row. The updateXXX() methods do not update the
2738:             * underlying database, instead the updateRow() or insertRow() methods are
2739:             * called to update the database.
2740:             *
2741:             * @param columnIndex
2742:             *            the first column is 1, the second is 2, ...
2743:             * @param x
2744:             *            the new column value
2745:             * @param length
2746:             *            the length of the stream
2747:             * @exception SQLException
2748:             *                if a database-access error occurs
2749:             */
2750:            public void updateAsciiStream(int columnIndex,
2751:                    java.io.InputStream x, long length) throws SQLException {
2752:                checksBeforeUpdateAsciiStream(columnIndex);
2753:
2754:                java.io.Reader r = null;
2755:                if (x != null) {
2756:                    try {
2757:                        r = new java.io.InputStreamReader(x, "ISO-8859-1");
2758:                    } catch (java.io.UnsupportedEncodingException uee) {
2759:                        throw new SQLException(uee.getMessage());
2760:                    }
2761:                }
2762:                updateCharacterStreamInternal(columnIndex, r, false, length,
2763:                        "updateAsciiStream");
2764:            }
2765:
2766:            /**
2767:             * Updates the designated column with a character stream value.
2768:             * The data will be read from the stream as needed until end-of-stream is
2769:             * reached.
2770:             *
2771:             * The updater methods are used to update column values in the current row
2772:             * or the insert row. The updater methods do not update the underlying
2773:             * database; instead the <code>updateRow</code> or </code>insertRow</code>
2774:             * methods are called to update the database.
2775:             *
2776:             * @param columnIndex the first column is 1, the second is 2, ...
2777:             * @param x the new column value
2778:             * @throws SQLException if the columnIndex is not valid; if a database
2779:             *      access error occurs; the result set concurrency is
2780:             *      <code>CONCUR_READ_ONLY</code> or this method is called on a closed
2781:             *      result set
2782:             */
2783:            public void updateAsciiStream(int columnIndex, InputStream x)
2784:                    throws SQLException {
2785:                checksBeforeUpdateAsciiStream(columnIndex);
2786:
2787:                java.io.Reader r = null;
2788:                if (x != null) {
2789:                    try {
2790:                        r = new java.io.InputStreamReader(x, "ISO-8859-1");
2791:                    } catch (java.io.UnsupportedEncodingException uee) {
2792:                        throw new SQLException(uee.getMessage());
2793:                    }
2794:                }
2795:                updateCharacterStreamInternal(columnIndex, r, true, -1,
2796:                        "updateAsciiStream");
2797:            }
2798:
2799:            /**
2800:             *
2801:             * Update a column with a binary stream value.
2802:             *
2803:             * The updateXXX() methods are used to update column values in the current
2804:             * row, or the insert row. The updateXXX() methods do not update the
2805:             * underlying database, instead the updateRow() or insertRow() methods are
2806:             * called to update the database.
2807:             *
2808:             * @param columnIndex
2809:             *            the first column is 1, the second is 2, ...
2810:             * @param x
2811:             *            the new column value
2812:             * @param length
2813:             *            the length of the stream
2814:             * @exception SQLException
2815:             *                if a database-access error occurs
2816:             */
2817:            public void updateBinaryStream(int columnIndex,
2818:                    java.io.InputStream x, long length) throws SQLException {
2819:                checksBeforeUpdateBinaryStream(columnIndex);
2820:
2821:                if (x == null) {
2822:                    updateNull(columnIndex);
2823:                    return;
2824:                }
2825:
2826:                updateBinaryStreamInternal(columnIndex, x, false, length,
2827:                        "updateBinaryStream");
2828:            }
2829:
2830:            /**
2831:             * Updates the designated column with a binary stream value.
2832:             * The data will be read from the stream as needed until end-of-stream is
2833:             * reached.
2834:             *
2835:             * The updater methods are used to update column values in the current row
2836:             * or the insert row. The updater methods do not update the underlying
2837:             * database; instead the <code>updateRow</code> or <code>insertRow</code>
2838:             * methods are called to update the database.
2839:             *
2840:             * @param columnIndex the first column is 1, the second is 2, ...
2841:             * @param x the new column value
2842:             * @throws SQLException if the columnLabel is not valid; if a database
2843:             *      access error occurs; the result set concurrency is
2844:             *      <code>CONCUR_READ_ONLY</code> or this method is called on a closed
2845:             *      result set
2846:             */
2847:            public void updateBinaryStream(int columnIndex, InputStream x)
2848:                    throws SQLException {
2849:                checksBeforeUpdateBinaryStream(columnIndex);
2850:                updateBinaryStreamInternal(columnIndex, x, true, -1,
2851:                        "updateBinaryStream");
2852:            }
2853:
2854:            /**
2855:             * Set the given binary stream for the specified parameter.
2856:             *
2857:             * If <code>lengthLess</code> is <code>true</code>, the following
2858:             * conditions are either not checked or verified at the execution time
2859:             * of <code>updateRow</code>/<code>insertRow</code>:
2860:             * <ol><li>If the stream length is negative.
2861:             *     <li>If the stream's actual length equals the specified length.</ol>
2862:             * The <code>lengthLess</code> variable was added to differentiate between
2863:             * streams with invalid lengths and streams without known lengths.
2864:             *
2865:             * @param columnIndex the 1-based index of the parameter to set.
2866:             * @param x the data.
2867:             * @param lengthLess tells whether we know the length of the data or not.
2868:             * @param length the length of the data. Ignored if <code>lengthLess</code>
2869:             *          is <code>true</code>.
2870:             * @param updateMethodName the name of the method calling us. Used in
2871:             *      error messages.
2872:             * @throws SQLException if reading the data fails, or one of the data
2873:             *      checks fails.
2874:             */
2875:            private void updateBinaryStreamInternal(int columnIndex,
2876:                    InputStream x, final boolean lengthLess, long length,
2877:                    String updateMethodName) throws SQLException {
2878:                RawToBinaryFormatStream rawStream;
2879:                if (!lengthLess) {
2880:                    if (length < 0)
2881:                        throw newSQLException(SQLState.NEGATIVE_STREAM_LENGTH);
2882:
2883:                    // max number of bytes that can be set to be inserted
2884:                    // in Derby is 2Gb-1 (ie Integer.MAX_VALUE).
2885:                    // (e.g into a blob column).
2886:                    if (length > Integer.MAX_VALUE) {
2887:                        throw newSQLException(
2888:                                SQLState.LANG_OUTSIDE_RANGE_FOR_DATATYPE,
2889:                                getColumnSQLType(columnIndex));
2890:                    }
2891:                    rawStream = new RawToBinaryFormatStream(x, (int) length);
2892:                } else {
2893:                    // Force length to -1 if stream is length less.
2894:                    length = -1;
2895:                    rawStream = new RawToBinaryFormatStream(x,
2896:                            getMaxColumnWidth(columnIndex),
2897:                            getColumnSQLType(columnIndex));
2898:                }
2899:
2900:                try {
2901:                    getDVDforColumnToBeUpdated(columnIndex, updateMethodName)
2902:                            .setValue(rawStream, (int) length);
2903:                } catch (StandardException t) {
2904:                    throw noStateChangeException(t);
2905:                }
2906:            }
2907:
2908:            /**
2909:             * JDBC 4.0
2910:             * 
2911:             * Update a column with a character stream value.
2912:             * 
2913:             * The updateXXX() methods are used to update column values in the current
2914:             * row, or the insert row. The updateXXX() methods do not update the
2915:             * underlying database, instead the updateRow() or insertRow() methods are
2916:             * called to update the database.
2917:             * 
2918:             * @param columnIndex
2919:             *            the first column is 1, the second is 2, ...
2920:             * @param x
2921:             *            the new column value
2922:             * @param length
2923:             *            the length of the stream
2924:             * @exception SQLException
2925:             *                if a database-access error occurs
2926:             */
2927:            public void updateCharacterStream(int columnIndex,
2928:                    java.io.Reader x, long length) throws SQLException {
2929:                checksBeforeUpdateCharacterStream(columnIndex);
2930:                updateCharacterStreamInternal(columnIndex, x, false, length,
2931:                        "updateCharacterStream");
2932:            }
2933:
2934:            /**
2935:             * Updates the designated column with a character stream value.
2936:             * The data will be read from the stream as needed until end-of-stream is
2937:             * reached.
2938:             *
2939:             * The updater methods are used to update column values in the current row
2940:             * or the insert row. The updater methods do not update the underlying
2941:             * database; instead the <code>updateRow</code> or </code>insertRow</code>
2942:             * methods are called to update the database.
2943:             *
2944:             * @param columnIndex the first column is 1, the second is 2, ...
2945:             * @param x the new column value
2946:             * @throws SQLException if the columnIndex is not valid; if a database
2947:             *      access error occurs; the result set concurrency is
2948:             *      <code>CONCUR_READ_ONLY</code> or this method is called on a closed
2949:             *      result set
2950:             */
2951:            public void updateCharacterStream(int columnIndex, Reader x)
2952:                    throws SQLException {
2953:                checksBeforeUpdateCharacterStream(columnIndex);
2954:                updateCharacterStreamInternal(columnIndex, x, true, -1,
2955:                        "updateCharacterStream");
2956:            }
2957:
2958:            /**
2959:             * Set the given character stream for the specified parameter.
2960:             *
2961:             * If <code>lengthLess</code> is <code>true</code>, the following
2962:             * conditions are either not checked or verified at the execution time
2963:             * of the prepared statement:
2964:             * <ol><li>If the stream length is negative.
2965:             *     <li>If the stream's actual length equals the specified length.</ol>
2966:             * The <code>lengthLess</code> variable was added to differentiate between
2967:             * streams with invalid lengths and streams without known lengths.
2968:             *
2969:             * @param columnIndex the 1-based index of the parameter to set.
2970:             * @param reader the data.
2971:             * @param lengthLess tells whether we know the length of the data or not.
2972:             * @param length the length of the data. Ignored if <code>lengthLess</code>
2973:             *          is <code>true</code>.
2974:             * @throws SQLException if reading the data fails, or one of the data
2975:             *      checks fails.
2976:             */
2977:            private void updateCharacterStreamInternal(int columnIndex,
2978:                    Reader reader, final boolean lengthLess, long length,
2979:                    String updateMethodName) throws SQLException {
2980:                try {
2981:
2982:                    if (reader == null) {
2983:                        updateNull(columnIndex);
2984:                        return;
2985:                    }
2986:
2987:                    ReaderToUTF8Stream utfIn;
2988:                    int usableLength = -1;
2989:                    if (!lengthLess) {
2990:                        // check for -ve length here
2991:                        if (length < 0)
2992:                            throw newSQLException(SQLState.NEGATIVE_STREAM_LENGTH);
2993:
2994:                        // max number of characters that can be set to be inserted
2995:                        // in Derby is 2Gb-1 (ie Integer.MAX_VALUE).
2996:                        // (e.g into a CLOB column).
2997:                        if (length > Integer.MAX_VALUE) {
2998:                            throw newSQLException(
2999:                                    SQLState.LANG_OUTSIDE_RANGE_FOR_DATATYPE,
3000:                                    getColumnSQLType(columnIndex));
3001:                        }
3002:
3003:                        // length is +ve. at this point, all checks for negative
3004:                        // length has already been done
3005:                        usableLength = (int) length;
3006:                        int truncationLength = 0;
3007:
3008:                        // Currently long varchar does not allow for truncation of
3009:                        // trailing blanks.  For char and varchar types, current
3010:                        // mechanism of materializing when using streams seems fine
3011:                        // given their max limits. This change is fix for DERBY-352:
3012:                        // Insert of clobs using streams should not materialize the
3013:                        // entire stream into memory
3014:                        // In case of clobs, the truncation of trailing blanks is
3015:                        // factored in when reading from the stream without
3016:                        // materializing the entire stream, and so the special casing
3017:                        // for clob below.
3018:                        if (getColumnType(columnIndex) == Types.CLOB) {
3019:                            // Need column width to figure out if truncation is
3020:                            // needed
3021:                            int colWidth = getMaxColumnWidth(columnIndex);
3022:
3023:                            // It is possible that the length of the stream passed in
3024:                            // is greater than the column width, in which case the data
3025:                            // from the stream needs to be truncated.
3026:                            // usableLength is the length of the data from stream
3027:                            // that can be used which is min(colWidth,length) provided
3028:                            // length - colWidth has trailing blanks only
3029:                            if (usableLength > colWidth) {
3030:                                truncationLength = usableLength - colWidth;
3031:                                usableLength = colWidth;
3032:                            }
3033:                        }
3034:
3035:                        utfIn = new ReaderToUTF8Stream(reader, usableLength,
3036:                                truncationLength, getColumnSQLType(columnIndex));
3037:                    } else {
3038:                        int colWidth = getMaxColumnWidth(columnIndex);
3039:                        utfIn = new ReaderToUTF8Stream(reader, colWidth,
3040:                                getColumnSQLType(columnIndex));
3041:                    }
3042:
3043:                    // NOTE: The length argument to setValue is not used. If that
3044:                    //       changes, the value might also have to change.
3045:                    getDVDforColumnToBeUpdated(columnIndex, updateMethodName)
3046:                            .setValue(utfIn, (int) usableLength);
3047:                } catch (StandardException t) {
3048:                    throw noStateChangeException(t);
3049:                }
3050:            }
3051:
3052:            /**
3053:             * JDBC 2.0
3054:             *
3055:             * Update a column with an Object value.
3056:             *
3057:             * The updateXXX() methods are used to update column values in the current
3058:             * row, or the insert row. The updateXXX() methods do not update the
3059:             * underlying database, instead the updateRow() or insertRow() methods are
3060:             * called to update the database.
3061:             *
3062:             * @param columnIndex
3063:             *            the first column is 1, the second is 2, ...
3064:             * @param x
3065:             *            the new column value
3066:             * @param scale
3067:             *            For java.sql.Types.DECIMAL or java.sql.Types.NUMERIC types
3068:             *            this is the number of digits after the decimal. For all other
3069:             *            types this value will be ignored.
3070:             * @exception SQLException
3071:             *                if a database-access error occurs
3072:             */
3073:            public void updateObject(int columnIndex, Object x, int scale)
3074:                    throws SQLException {
3075:                updateObject(columnIndex, x);
3076:                /*
3077:                 * If the parameter type is DECIMAL or NUMERIC, then
3078:                 * we need to set them to the passed scale.
3079:                 */
3080:                int colType = getColumnType(columnIndex);
3081:                if ((colType == Types.DECIMAL) || (colType == Types.NUMERIC)) {
3082:                    if (scale < 0)
3083:                        throw newSQLException(SQLState.BAD_SCALE_VALUE,
3084:                                new Integer(scale));
3085:
3086:                    try {
3087:                        DataValueDescriptor value = updateRow
3088:                                .getColumn(columnIndex);
3089:
3090:                        int origvaluelen = value.getLength();
3091:                        ((VariableSizeDataValue) value).setWidth(
3092:                                VariableSizeDataValue.IGNORE_PRECISION, scale,
3093:                                false);
3094:
3095:                    } catch (StandardException t) {
3096:                        throw EmbedResultSet.noStateChangeException(t);
3097:                    }
3098:                }
3099:            }
3100:
3101:            /**
3102:             * JDBC 2.0
3103:             *
3104:             * Update a column with an Object value.
3105:             *
3106:             * The updateXXX() methods are used to update column values in the current
3107:             * row, or the insert row. The updateXXX() methods do not update the
3108:             * underlying database, instead the updateRow() or insertRow() methods are
3109:             * called to update the database.
3110:             *
3111:             * @param columnIndex
3112:             *            the first column is 1, the second is 2, ...
3113:             * @param x
3114:             *            the new column value
3115:             * @exception SQLException
3116:             *                if a database-access error occurs
3117:             */
3118:            public void updateObject(int columnIndex, Object x)
3119:                    throws SQLException {
3120:                checksBeforeUpdateXXX("updateObject", columnIndex);
3121:                int colType = getColumnType(columnIndex);
3122:                if (colType == org.apache.derby.iapi.reference.JDBC20Translation.SQL_TYPES_JAVA_OBJECT) {
3123:                    try {
3124:                        ((UserDataValue) getDVDforColumnToBeUpdated(
3125:                                columnIndex, "updateObject")).setValue(x);
3126:                        return;
3127:                    } catch (StandardException t) {
3128:                        throw noStateChangeException(t);
3129:                    }
3130:                }
3131:
3132:                if (x == null) {
3133:                    updateNull(columnIndex);
3134:                    return;
3135:                }
3136:
3137:                if (x instanceof  String) {
3138:                    updateString(columnIndex, (String) x);
3139:                    return;
3140:                }
3141:
3142:                if (x instanceof  Boolean) {
3143:                    updateBoolean(columnIndex, ((Boolean) x).booleanValue());
3144:                    return;
3145:                }
3146:
3147:                if (x instanceof  Short) {
3148:                    updateShort(columnIndex, ((Short) x).shortValue());
3149:                    return;
3150:                }
3151:
3152:                if (x instanceof  Integer) {
3153:                    updateInt(columnIndex, ((Integer) x).intValue());
3154:                    return;
3155:                }
3156:
3157:                if (x instanceof  Long) {
3158:                    updateLong(columnIndex, ((Long) x).longValue());
3159:                    return;
3160:                }
3161:
3162:                if (x instanceof  Float) {
3163:                    updateFloat(columnIndex, ((Float) x).floatValue());
3164:                    return;
3165:                }
3166:
3167:                if (x instanceof  Double) {
3168:                    updateDouble(columnIndex, ((Double) x).doubleValue());
3169:                    return;
3170:                }
3171:
3172:                if (x instanceof  byte[]) {
3173:                    updateBytes(columnIndex, (byte[]) x);
3174:                    return;
3175:                }
3176:
3177:                if (x instanceof  Date) {
3178:                    updateDate(columnIndex, (Date) x);
3179:                    return;
3180:                }
3181:
3182:                if (x instanceof  Time) {
3183:                    updateTime(columnIndex, (Time) x);
3184:                    return;
3185:                }
3186:
3187:                if (x instanceof  Timestamp) {
3188:                    updateTimestamp(columnIndex, (Timestamp) x);
3189:                    return;
3190:                }
3191:
3192:                if (x instanceof  Blob) {
3193:                    updateBlob(columnIndex, (Blob) x);
3194:                    return;
3195:                }
3196:
3197:                if (x instanceof  Clob) {
3198:                    updateClob(columnIndex, (Clob) x);
3199:                    return;
3200:                }
3201:
3202:                throw dataTypeConversion(columnIndex, x.getClass().getName());
3203:            }
3204:
3205:            /**
3206:             * JDBC 2.0
3207:             * 
3208:             * Update a column with a null value.
3209:             * 
3210:             * The updateXXX() methods are used to update column values in the current
3211:             * row, or the insert row. The updateXXX() methods do not update the
3212:             * underlying database, instead the updateRow() or insertRow() methods are
3213:             * called to update the database.
3214:             * 
3215:             * @param columnName
3216:             *            the name of the column
3217:             * @exception SQLException
3218:             *                if a database-access error occurs
3219:             */
3220:            public void updateNull(String columnName) throws SQLException {
3221:                checkIfClosed("updateNull");
3222:                updateNull(findColumnName(columnName));
3223:            }
3224:
3225:            /**
3226:             * JDBC 2.0
3227:             * 
3228:             * Update a column with a boolean value.
3229:             * 
3230:             * The updateXXX() methods are used to update column values in the current
3231:             * row, or the insert row. The updateXXX() methods do not update the
3232:             * underlying database, instead the updateRow() or insertRow() methods are
3233:             * called to update the database.
3234:             * 
3235:             * @param columnName
3236:             *            the name of the column
3237:             * @param x
3238:             *            the new column value
3239:             * @exception SQLException
3240:             *                if a database-access error occurs
3241:             */
3242:            public void updateBoolean(String columnName, boolean x)
3243:                    throws SQLException {
3244:                checkIfClosed("updateBoolean");
3245:                updateBoolean(findColumnName(columnName), x);
3246:            }
3247:
3248:            /**
3249:             * JDBC 2.0
3250:             * 
3251:             * Update a column with a byte value.
3252:             * 
3253:             * The updateXXX() methods are used to update column values in the current
3254:             * row, or the insert row. The updateXXX() methods do not update the
3255:             * underlying database, instead the updateRow() or insertRow() methods are
3256:             * called to update the database.
3257:             * 
3258:             * @param columnName
3259:             *            the name of the column
3260:             * @param x
3261:             *            the new column value
3262:             * @exception SQLException
3263:             *                if a database-access error occurs
3264:             */
3265:            public void updateByte(String columnName, byte x)
3266:                    throws SQLException {
3267:                checkIfClosed("updateByte");
3268:                updateByte(findColumnName(columnName), x);
3269:            }
3270:
3271:            /**
3272:             * JDBC 2.0
3273:             * 
3274:             * Update a column with a short value.
3275:             * 
3276:             * The updateXXX() methods are used to update column values in the current
3277:             * row, or the insert row. The updateXXX() methods do not update the
3278:             * underlying database, instead the updateRow() or insertRow() methods are
3279:             * called to update the database.
3280:             * 
3281:             * @param columnName
3282:             *            the name of the column
3283:             * @param x
3284:             *            the new column value
3285:             * @exception SQLException
3286:             *                if a database-access error occurs
3287:             */
3288:            public void updateShort(String columnName, short x)
3289:                    throws SQLException {
3290:                checkIfClosed("updateShort");
3291:                updateShort(findColumnName(columnName), x);
3292:            }
3293:
3294:            /**
3295:             * JDBC 2.0
3296:             * 
3297:             * Update a column with an integer value.
3298:             * 
3299:             * The updateXXX() methods are used to update column values in the current
3300:             * row, or the insert row. The updateXXX() methods do not update the
3301:             * underlying database, instead the updateRow() or insertRow() methods are
3302:             * called to update the database.
3303:             * 
3304:             * @param columnName
3305:             *            the name of the column
3306:             * @param x
3307:             *            the new column value
3308:             * @exception SQLException
3309:             *                if a database-access error occurs
3310:             */
3311:            public void updateInt(String columnName, int x) throws SQLException {
3312:                checkIfClosed("updateInt");
3313:                updateInt(findColumnName(columnName), x);
3314:            }
3315:
3316:            /**
3317:             * JDBC 2.0
3318:             * 
3319:             * Update a column with a long value.
3320:             * 
3321:             * The updateXXX() methods are used to update column values in the current
3322:             * row, or the insert row. The updateXXX() methods do not update the
3323:             * underlying database, instead the updateRow() or insertRow() methods are
3324:             * called to update the database.
3325:             * 
3326:             * @param columnName
3327:             *            the name of the column
3328:             * @param x
3329:             *            the new column value
3330:             * @exception SQLException
3331:             *                if a database-access error occurs
3332:             */
3333:            public void updateLong(String columnName, long x)
3334:                    throws SQLException {
3335:                checkIfClosed("updateLong");
3336:                updateLong(findColumnName(columnName), x);
3337:            }
3338:
3339:            /**
3340:             * JDBC 2.0
3341:             * 
3342:             * Update a column with a float value.
3343:             * 
3344:             * The updateXXX() methods are used to update column values in the current
3345:             * row, or the insert row. The updateXXX() methods do not update the
3346:             * underlying database, instead the updateRow() or insertRow() methods are
3347:             * called to update the database.
3348:             * 
3349:             * @param columnName
3350:             *            the name of the column
3351:             * @param x
3352:             *            the new column value
3353:             * @exception SQLException
3354:             *                if a database-access error occurs
3355:             */
3356:            public void updateFloat(String columnName, float x)
3357:                    throws SQLException {
3358:                checkIfClosed("updateFloat");
3359:                updateFloat(findColumnName(columnName), x);
3360:            }
3361:
3362:            /**
3363:             * JDBC 2.0
3364:             * 
3365:             * Update a column with a double value.
3366:             * 
3367:             * The updateXXX() methods are used to update column values in the current
3368:             * row, or the insert row. The updateXXX() methods do not update the
3369:             * underlying database, instead the updateRow() or insertRow() methods are
3370:             * called to update the database.
3371:             * 
3372:             * @param columnName
3373:             *            the name of the column
3374:             * @param x
3375:             *            the new column value
3376:             * @exception SQLException
3377:             *                if a database-access error occurs
3378:             */
3379:            public void updateDouble(String columnName, double x)
3380:                    throws SQLException {
3381:                checkIfClosed("updateDouble");
3382:                updateDouble(findColumnName(columnName), x);
3383:            }
3384:
3385:            /**
3386:             * JDBC 2.0
3387:             * 
3388:             * Update a column with a String value.
3389:             * 
3390:             * The updateXXX() methods are used to update column values in the current
3391:             * row, or the insert row. The updateXXX() methods do not update the
3392:             * underlying database, instead the updateRow() or insertRow() methods are
3393:             * called to update the database.
3394:             * 
3395:             * @param columnName
3396:             *            the name of the column
3397:             * @param x
3398:             *            the new column value
3399:             * @exception SQLException
3400:             *                if a database-access error occurs
3401:             */
3402:            public void updateString(String columnName, String x)
3403:                    throws SQLException {
3404:                checkIfClosed("updateString");
3405:                updateString(findColumnName(columnName), x);
3406:            }
3407:
3408:            /**
3409:             * JDBC 2.0
3410:             * 
3411:             * Update a column with a byte array value.
3412:             * 
3413:             * The updateXXX() methods are used to update column values in the current
3414:             * row, or the insert row. The updateXXX() methods do not update the
3415:             * underlying database, instead the updateRow() or insertRow() methods are
3416:             * called to update the database.
3417:             * 
3418:             * @param columnName
3419:             *            the name of the column
3420:             * @param x
3421:             *            the new column value
3422:             * @exception SQLException
3423:             *                if a database-access error occurs
3424:             */
3425:            public void updateBytes(String columnName, byte x[])
3426:                    throws SQLException {
3427:                checkIfClosed("updateBytes");
3428:                updateBytes(findColumnName(columnName), x);
3429:            }
3430:
3431:            /**
3432:             * JDBC 2.0
3433:             * 
3434:             * Update a column with a Date value.
3435:             * 
3436:             * The updateXXX() methods are used to update column values in the current
3437:             * row, or the insert row. The updateXXX() methods do not update the
3438:             * underlying database, instead the updateRow() or insertRow() methods are
3439:             * called to update the database.
3440:             * 
3441:             * @param columnName
3442:             *            the name of the column
3443:             * @param x
3444:             *            the new column value
3445:             * @exception SQLException
3446:             *                if a database-access error occurs
3447:             */
3448:            public void updateDate(String columnName, java.sql.Date x)
3449:                    throws SQLException {
3450:                checkIfClosed("updateDate");
3451:                updateDate(findColumnName(columnName), x);
3452:            }
3453:
3454:            /**
3455:             * JDBC 2.0
3456:             * 
3457:             * Update a column with a Time value.
3458:             * 
3459:             * The updateXXX() methods are used to update column values in the current
3460:             * row, or the insert row. The updateXXX() methods do not update the
3461:             * underlying database, instead the updateRow() or insertRow() methods are
3462:             * called to update the database.
3463:             * 
3464:             * @param columnName
3465:             *            the name of the column
3466:             * @param x
3467:             *            the new column value
3468:             * @exception SQLException
3469:             *                if a database-access error occurs
3470:             */
3471:            public void updateTime(String columnName, java.sql.Time x)
3472:                    throws SQLException {
3473:                checkIfClosed("updateTime");
3474:                updateTime(findColumnName(columnName), x);
3475:            }
3476:
3477:            /**
3478:             * JDBC 2.0
3479:             * 
3480:             * Update a column with a Timestamp value.
3481:             * 
3482:             * The updateXXX() methods are used to update column values in the current
3483:             * row, or the insert row. The updateXXX() methods do not update the
3484:             * underlying database, instead the updateRow() or insertRow() methods are
3485:             * called to update the database.
3486:             * 
3487:             * @param columnName
3488:             *            the name of the column
3489:             * @param x
3490:             *            the new column value
3491:             * @exception SQLException
3492:             *                if a database-access error occurs
3493:             */
3494:            public void updateTimestamp(String columnName, java.sql.Timestamp x)
3495:                    throws SQLException {
3496:                checkIfClosed("updateTimestamp");
3497:                updateTimestamp(findColumnName(columnName), x);
3498:            }
3499:
3500:            /**
3501:             * JDBC 2.0
3502:             * 
3503:             * Update a column with an ascii stream value.
3504:             * 
3505:             * The updateXXX() methods are used to update column values in the current
3506:             * row, or the insert row. The updateXXX() methods do not update the
3507:             * underlying database, instead the updateRow() or insertRow() methods are
3508:             * called to update the database.
3509:             * 
3510:             * @param columnName
3511:             *            the name of the column
3512:             * @param x
3513:             *            the new column value
3514:             * @param length
3515:             *            of the stream
3516:             * @exception SQLException
3517:             *                if a database-access error occurs
3518:             */
3519:            public void updateAsciiStream(String columnName,
3520:                    java.io.InputStream x, int length) throws SQLException {
3521:                checkIfClosed("updateAsciiStream");
3522:                updateAsciiStream(findColumnName(columnName), x, length);
3523:            }
3524:
3525:            /**
3526:             * JDBC 2.0
3527:             * 
3528:             * Update a column with a binary stream value.
3529:             * 
3530:             * The updateXXX() methods are used to update column values in the current
3531:             * row, or the insert row. The updateXXX() methods do not update the
3532:             * underlying database, instead the updateRow() or insertRow() methods are
3533:             * called to update the database.
3534:             * 
3535:             * @param columnName
3536:             *            the name of the column
3537:             * @param x
3538:             *            the new column value
3539:             * @param length
3540:             *            of the stream
3541:             * @exception SQLException
3542:             *                if a database-access error occurs
3543:             */
3544:            public void updateBinaryStream(String columnName,
3545:                    java.io.InputStream x, int length) throws SQLException {
3546:                checkIfClosed("updateBinaryStream");
3547:                updateBinaryStream(findColumnName(columnName), x, length);
3548:            }
3549:
3550:            /**
3551:             * JDBC 2.0
3552:             * 
3553:             * Update a column with a character stream value.
3554:             * 
3555:             * The updateXXX() methods are used to update column values in the current
3556:             * row, or the insert row. The updateXXX() methods do not update the
3557:             * underlying database, instead the updateRow() or insertRow() methods are
3558:             * called to update the database.
3559:             * 
3560:             * @param columnName
3561:             *            the name of the column
3562:             * @param reader
3563:             *            the new column value
3564:             * @param length
3565:             *            length of the stream
3566:             * @exception SQLException
3567:             *                if a database-access error occurs
3568:             */
3569:            public void updateCharacterStream(String columnName,
3570:                    java.io.Reader reader, int length) throws SQLException {
3571:                checkIfClosed("updateCharacterStream");
3572:                updateCharacterStream(findColumnName(columnName), reader,
3573:                        length);
3574:            }
3575:
3576:            /**
3577:             * JDBC 2.0
3578:             *
3579:             * Update a column with an Object value.
3580:             *
3581:             * The updateXXX() methods are used to update column values in the
3582:             * current row, or the insert row.  The updateXXX() methods do not
3583:             * update the underlying database, instead the updateRow() or insertRow()
3584:             * methods are called to update the database.
3585:             *
3586:             * @param columnName the name of the column
3587:             * @param x the new column value
3588:             * @param scale For java.sql.Types.DECIMAL or java.sql.Types.NUMERIC types
3589:             *  this is the number of digits after the decimal.  For all other
3590:             *  types this value will be ignored.
3591:             * @exception SQLException if a database-access error occurs
3592:             */
3593:            public void updateObject(String columnName, Object x, int scale)
3594:                    throws SQLException {
3595:                checkIfClosed("updateObject");
3596:                updateObject(findColumnName(columnName), x, scale);
3597:            }
3598:
3599:            /**
3600:             * JDBC 2.0
3601:             *
3602:             * Update a column with an Object value.
3603:             *
3604:             * The updateXXX() methods are used to update column values in the current
3605:             * row, or the insert row. The updateXXX() methods do not update the
3606:             * underlying database, instead the updateRow() or insertRow() methods are
3607:             * called to update the database.
3608:             *
3609:             * @param columnName
3610:             *            the name of the column
3611:             * @param x
3612:             *            the new column value
3613:             * @exception SQLException
3614:             *                if a database-access error occurs
3615:             */
3616:            public void updateObject(String columnName, Object x)
3617:                    throws SQLException {
3618:                checkIfClosed("updateObject");
3619:                updateObject(findColumnName(columnName), x);
3620:            }
3621:
3622:            /**
3623:             * JDBC 2.0
3624:             * 
3625:             * Insert the contents of the insert row into the result set and the
3626:             * database. Must be on the insert row when this method is called.
3627:             * 
3628:             * @exception SQLException
3629:             *                if a database-access error occurs, if called when not on
3630:             *                the insert row, or if all non-nullable columns in the
3631:             *                insert row have not been given a value
3632:             */
3633:            public void insertRow() throws SQLException {
3634:                synchronized (getConnectionSynchronization()) {
3635:                    checksBeforeInsert();
3636:                    setupContextStack();
3637:                    LanguageConnectionContext lcc = null;
3638:                    StatementContext statementContext = null;
3639:                    try {
3640:                        /*
3641:                         * construct the insert statement
3642:                         *
3643:                         * If no values have been supplied for a column, it will be set 
3644:                         * to the column's default value, if any. 
3645:                         * If no default value had been defined, the default value of a 
3646:                         * nullable column is set to NULL.
3647:                         */
3648:
3649:                        boolean foundOneColumnAlready = false;
3650:                        StringBuffer insertSQL = new StringBuffer(
3651:                                "INSERT INTO ");
3652:                        StringBuffer valuesSQL = new StringBuffer("VALUES (");
3653:                        CursorActivation activation = getEmbedConnection()
3654:                                .getLanguageConnection()
3655:                                .lookupCursorActivation(getCursorName());
3656:
3657:                        ExecCursorTableReference targetTable = activation
3658:                                .getPreparedStatement().getTargetTable();
3659:                        // got the underlying (schema.)table name
3660:                        insertSQL.append(getFullBaseTableName(targetTable));
3661:                        ResultDescription rd = theResults
3662:                                .getResultDescription();
3663:
3664:                        insertSQL.append(" (");
3665:                        // in this for loop we are constructing list of column-names 
3666:                        // and values (?) ,... part of the insert sql
3667:                        for (int i = 1; i <= rd.getColumnCount(); i++) {
3668:                            if (foundOneColumnAlready) {
3669:                                insertSQL.append(",");
3670:                                valuesSQL.append(",");
3671:                            }
3672:                            // using quotes around the column name 
3673:                            // to preserve case sensitivity
3674:                            insertSQL.append(quoteSqlIdentifier(rd
3675:                                    .getColumnDescriptor(i).getName()));
3676:                            if (columnGotUpdated[i - 1]) {
3677:                                valuesSQL.append("?");
3678:                            } else {
3679:                                valuesSQL.append("DEFAULT");
3680:                            }
3681:                            foundOneColumnAlready = true;
3682:                        }
3683:                        insertSQL.append(") ");
3684:                        valuesSQL.append(") ");
3685:                        insertSQL.append(valuesSQL);
3686:
3687:                        lcc = getEmbedConnection().getLanguageConnection();
3688:
3689:                        // Context used for preparing, don't set any timeout (use 0)
3690:                        statementContext = lcc.pushStatementContext(isAtomic,
3691:                                false, insertSQL.toString(), null, false, 0L);
3692:                        org.apache.derby.iapi.sql.PreparedStatement ps = lcc
3693:                                .prepareInternalStatement(insertSQL.toString());
3694:                        Activation act = ps.getActivation(lcc, false);
3695:
3696:                        // in this for loop we are assigning values for parameters 
3697:                        //in sql constructed earlier VALUES (?, ..)
3698:                        for (int i = 1, paramPosition = 0; i <= rd
3699:                                .getColumnCount(); i++) {
3700:                            // if the column got updated, do following
3701:                            if (columnGotUpdated[i - 1]) {
3702:                                act.getParameterValueSet().getParameterForSet(
3703:                                        paramPosition++).setValue(
3704:                                        updateRow.getColumn(i));
3705:                            }
3706:                        }
3707:                        // Don't see any timeout when inserting rows (use 0)
3708:                        //execute the insert
3709:                        org.apache.derby.iapi.sql.ResultSet rs = ps.execute(
3710:                                act, true, 0L);
3711:                        rs.close();
3712:                        rs.finish();
3713:
3714:                        lcc.popStatementContext(statementContext, null);
3715:                    } catch (StandardException t) {
3716:                        throw closeOnTransactionError(t);
3717:                    } finally {
3718:                        if (statementContext != null)
3719:                            lcc.popStatementContext(statementContext, null);
3720:                        restoreContextStack();
3721:                    }
3722:                }
3723:            }
3724:
3725:            /**
3726:             * JDBC 2.0
3727:             *
3728:             * Update the underlying database with the new contents of the
3729:             * current row.  Cannot be called when on the insert row.
3730:             *
3731:             * @exception SQLException if a database-access error occurs, or
3732:             * if called when on the insert row
3733:             */
3734:            public void updateRow() throws SQLException {
3735:                synchronized (getConnectionSynchronization()) {
3736:                    checksBeforeUpdateOrDelete("updateRow", -1);
3737:
3738:                    // Check that the cursor is not positioned on insertRow
3739:                    checkNotOnInsertRow();
3740:
3741:                    setupContextStack();
3742:                    LanguageConnectionContext lcc = null;
3743:                    StatementContext statementContext = null;
3744:                    try {
3745:                        if (currentRowHasBeenUpdated == false) //nothing got updated on this row 
3746:                            return; //nothing to do since no updates were made to this row
3747:
3748:                        //now construct the update where current of sql
3749:                        boolean foundOneColumnAlready = false;
3750:                        StringBuffer updateWhereCurrentOfSQL = new StringBuffer(
3751:                                "UPDATE ");
3752:                        CursorActivation activation = getEmbedConnection()
3753:                                .getLanguageConnection()
3754:                                .lookupCursorActivation(getCursorName());
3755:
3756:                        ExecCursorTableReference targetTable = activation
3757:                                .getPreparedStatement().getTargetTable();
3758:                        updateWhereCurrentOfSQL
3759:                                .append(getFullBaseTableName(targetTable));//got the underlying (schema.)table name
3760:                        updateWhereCurrentOfSQL.append(" SET ");
3761:                        ResultDescription rd = theResults
3762:                                .getResultDescription();
3763:
3764:                        for (int i = 1; i <= rd.getColumnCount(); i++) { //in this for loop we are constructing columnname=?,... part of the update sql
3765:                            if (columnGotUpdated[i - 1]) { //if the column got updated, do following
3766:                                if (foundOneColumnAlready)
3767:                                    updateWhereCurrentOfSQL.append(",");
3768:                                //using quotes around the column name to preserve case sensitivity
3769:                                updateWhereCurrentOfSQL
3770:                                        .append(quoteSqlIdentifier(rd
3771:                                                .getColumnDescriptor(i)
3772:                                                .getName())
3773:                                                + "=?");
3774:                                foundOneColumnAlready = true;
3775:                            }
3776:                        }
3777:                        //using quotes around the cursor name to preserve case sensitivity
3778:                        updateWhereCurrentOfSQL.append(" WHERE CURRENT OF "
3779:                                + quoteSqlIdentifier(getCursorName()));
3780:                        lcc = getEmbedConnection().getLanguageConnection();
3781:
3782:                        // Context used for preparing, don't set any timeout (use 0)
3783:                        statementContext = lcc.pushStatementContext(isAtomic,
3784:                                false, updateWhereCurrentOfSQL.toString(),
3785:                                null, false, 0L);
3786:                        org.apache.derby.iapi.sql.PreparedStatement ps = lcc
3787:                                .prepareInternalStatement(updateWhereCurrentOfSQL
3788:                                        .toString());
3789:                        Activation act = ps.getActivation(lcc, false);
3790:
3791:                        //in this for loop we are assigning values for parameters in sql constructed earlier with columnname=?,... 
3792:                        for (int i = 1, paramPosition = 0; i <= rd
3793:                                .getColumnCount(); i++) {
3794:                            if (columnGotUpdated[i - 1]) //if the column got updated, do following
3795:                                act.getParameterValueSet().getParameterForSet(
3796:                                        paramPosition++).setValue(
3797:                                        updateRow.getColumn(i));
3798:                        }
3799:                        // Don't set any timeout when updating rows (use 0)
3800:                        // Execute the update where current of sql.
3801:                        org.apache.derby.iapi.sql.ResultSet rs = ps.execute(
3802:                                act, true, 0L);
3803:                        SQLWarning w = act.getWarnings();
3804:                        if (w != null) {
3805:                            addWarning(w);
3806:                        }
3807:                        rs.close();
3808:                        rs.finish();
3809:                        //For forward only resultsets, after a update, the ResultSet will be positioned right before the next row.
3810:                        if (getType() == TYPE_FORWARD_ONLY) {
3811:                            currentRow.setRowArray(null);
3812:                        } else {
3813:                            movePosition(RELATIVE, 0, "relative");
3814:                        }
3815:                        lcc.popStatementContext(statementContext, null);
3816:                    } catch (StandardException t) {
3817:                        throw closeOnTransactionError(t);
3818:                    } finally {
3819:                        if (statementContext != null)
3820:                            lcc.popStatementContext(statementContext, null);
3821:                        restoreContextStack();
3822:                        initializeUpdateRowModifiers();
3823:                    }
3824:                }
3825:            }
3826:
3827:            /**
3828:             * JDBC 2.0
3829:             *
3830:             * Delete the current row from the result set and the underlying
3831:             * database.  Cannot be called when on the insert row.
3832:             *
3833:             * @exception SQLException if a database-access error occurs, or if
3834:             * called when on the insert row.
3835:             */
3836:            public void deleteRow() throws SQLException {
3837:                synchronized (getConnectionSynchronization()) {
3838:                    checksBeforeUpdateOrDelete("deleteRow", -1);
3839:
3840:                    // Check that the cursor is not positioned on insertRow
3841:                    checkNotOnInsertRow();
3842:
3843:                    setupContextStack();
3844:
3845:                    LanguageConnectionContext lcc = null;
3846:                    StatementContext statementContext = null;
3847:
3848:                    //now construct the delete where current of sql
3849:                    try {
3850:                        StringBuffer deleteWhereCurrentOfSQL = new StringBuffer(
3851:                                "DELETE FROM ");
3852:                        CursorActivation activation = getEmbedConnection()
3853:                                .getLanguageConnection()
3854:                                .lookupCursorActivation(getCursorName());
3855:                        deleteWhereCurrentOfSQL
3856:                                .append(getFullBaseTableName(activation
3857:                                        .getPreparedStatement()
3858:                                        .getTargetTable()));//get the underlying (schema.)table name
3859:                        //using quotes around the cursor name to preserve case sensitivity
3860:                        deleteWhereCurrentOfSQL.append(" WHERE CURRENT OF "
3861:                                + quoteSqlIdentifier(getCursorName()));
3862:
3863:                        lcc = getEmbedConnection().getLanguageConnection();
3864:
3865:                        // Context used for preparing, don't set any timeout (use 0)
3866:                        statementContext = lcc.pushStatementContext(isAtomic,
3867:                                false, deleteWhereCurrentOfSQL.toString(),
3868:                                null, false, 0L);
3869:                        org.apache.derby.iapi.sql.PreparedStatement ps = lcc
3870:                                .prepareInternalStatement(deleteWhereCurrentOfSQL
3871:                                        .toString());
3872:                        // Get activation, so that we can get the warning from it
3873:                        Activation act = ps.getActivation(lcc, false);
3874:                        // Don't set any timeout when deleting rows (use 0)
3875:                        //execute delete where current of sql
3876:                        org.apache.derby.iapi.sql.ResultSet rs = ps.execute(
3877:                                act, true, 0L);
3878:                        SQLWarning w = act.getWarnings();
3879:                        if (w != null) {
3880:                            addWarning(w);
3881:                        }
3882:                        rs.close();
3883:                        rs.finish();
3884:                        //After a delete, the ResultSet will be positioned right before 
3885:                        //the next row.
3886:                        currentRow.setRowArray(null);
3887:                        lcc.popStatementContext(statementContext, null);
3888:                    } catch (StandardException t) {
3889:                        throw closeOnTransactionError(t);
3890:                    } finally {
3891:                        if (statementContext != null)
3892:                            lcc.popStatementContext(statementContext, null);
3893:                        restoreContextStack();
3894:                        initializeUpdateRowModifiers();
3895:                    }
3896:                }
3897:            }
3898:
3899:            private String getFullBaseTableName(
3900:                    ExecCursorTableReference targetTable) {
3901:                //using quotes to preserve case sensitivity
3902:                if (targetTable.getSchemaName() != null)
3903:                    return quoteSqlIdentifier(targetTable.getSchemaName())
3904:                            + "."
3905:                            + quoteSqlIdentifier(targetTable.getBaseName());
3906:                else
3907:                    return quoteSqlIdentifier(targetTable.getBaseName());
3908:            }
3909:
3910:            private String quoteSqlIdentifier(String orgValue) {
3911:                int i = 0, start = 0;
3912:                String retValue = "";
3913:                while ((i = orgValue.indexOf("\"", start) + 1) > 0) {
3914:                    retValue += orgValue.substring(start, i) + "\"";
3915:                    start = i;
3916:                }
3917:                retValue += orgValue.substring(start, orgValue.length());
3918:                return "\"" + retValue + "\"";
3919:            }
3920:
3921:            /**
3922:             * JDBC 2.0
3923:             * 
3924:             * Refresh the value of the current row with its current value in the
3925:             * database. Cannot be called when on the insert row.
3926:             * 
3927:             * The refreshRow() method provides a way for an application to explicitly
3928:             * tell the JDBC driver to refetch a row(s) from the database. An
3929:             * application may want to call refreshRow() when caching or prefetching is
3930:             * being done by the JDBC driver to fetch the latest value of a row from the
3931:             * database. The JDBC driver may actually refresh multiple rows at once if
3932:             * the fetch size is greater than one.
3933:             * 
3934:             * All values are refetched subject to the transaction isolation level and
3935:             * cursor sensitivity. If refreshRow() is called after calling updateXXX(),
3936:             * but before calling updateRow() then the updates made to the row are lost.
3937:             * Calling refreshRow() frequently will likely slow performance.
3938:             * 
3939:             * @exception SQLException
3940:             *                if a database-access error occurs, or if called when on
3941:             *                the insert row.
3942:             */
3943:            public void refreshRow() throws SQLException {
3944:                throw Util.notImplemented();
3945:            }
3946:
3947:            /**
3948:             * JDBC 2.0
3949:             *
3950:             * The cancelRowUpdates() method may be called after calling an
3951:             * updateXXX() method(s) and before calling updateRow() to rollback 
3952:             * the updates made to a row.  If no updates have been made or 
3953:             * updateRow() has already been called, then this method has no 
3954:             * effect.
3955:             *
3956:             * @exception SQLException if a database-access error occurs, or if
3957:             * called when on the insert row.
3958:             *
3959:             */
3960:            public void cancelRowUpdates() throws SQLException {
3961:                checksBeforeUpdateOrDelete("cancelRowUpdates", -1);
3962:
3963:                checkNotOnInsertRow();
3964:
3965:                initializeUpdateRowModifiers();
3966:            }
3967:
3968:            /**
3969:             * JDBC 2.0
3970:             * 
3971:             * Move to the insert row. The current cursor position is remembered while
3972:             * the cursor is positioned on the insert row.
3973:             * 
3974:             * The insert row is a special row associated with an updatable result set.
3975:             * It is essentially a buffer where a new row may be constructed by calling
3976:             * the updateXXX() methods prior to inserting the row into the result set.
3977:             * 
3978:             * Only the updateXXX(), getXXX(), and insertRow() methods may be called
3979:             * when the cursor is on the insert row. All of the columns in a result set
3980:             * must be given a value each time this method is called before calling
3981:             * insertRow(). UpdateXXX()must be called before getXXX() on a column.
3982:             * 
3983:             * @exception SQLException
3984:             *                if a database-access error occurs, or the result set is
3985:             *                not updatable
3986:             */
3987:            public void moveToInsertRow() throws SQLException {
3988:                checkExecIfClosed("moveToInsertRow");
3989:
3990:                // if not updatable resultset, then throw exception
3991:                checkUpdatableCursor("moveToInsertRow");
3992:
3993:                synchronized (getConnectionSynchronization()) {
3994:                    try {
3995:                        // initialize state corresponding to insertRow/updateRow impl.
3996:                        initializeUpdateRowModifiers();
3997:                        isOnInsertRow = true;
3998:
3999:                        for (int i = 1; i <= columnGotUpdated.length; i++) {
4000:                            updateRow
4001:                                    .setColumn(i, resultDescription
4002:                                            .getColumnDescriptor(i).getType()
4003:                                            .getNull());
4004:                        }
4005:                    } catch (Throwable ex) {
4006:                        handleException(ex);
4007:                    }
4008:                }
4009:            }
4010:
4011:            /**
4012:             * JDBC 2.0
4013:             * 
4014:             * Move the cursor to the remembered cursor position, usually the current
4015:             * row. Has no effect unless the cursor is on the insert row.
4016:             * 
4017:             * @exception SQLException
4018:             *                if a database-access error occurs, or the result set is
4019:             *                not updatable
4020:             */
4021:            public void moveToCurrentRow() throws SQLException {
4022:                checkExecIfClosed("moveToCurrentRow");
4023:
4024:                // if not updatable resultset, then throw exception
4025:                checkUpdatableCursor("moveToCurrentRow");
4026:
4027:                synchronized (getConnectionSynchronization()) {
4028:                    try {
4029:
4030:                        if (isOnInsertRow) {
4031:                            // initialize state corresponding to insertRow/updateRow impl.
4032:                            initializeUpdateRowModifiers();
4033:
4034:                            isOnInsertRow = false;
4035:                        }
4036:                    } catch (Throwable ex) {
4037:                        handleException(ex);
4038:                    }
4039:                }
4040:            }
4041:
4042:            /**
4043:             * JDBC 2.0
4044:             * 
4045:             * Get a BLOB column.
4046:             * 
4047:             * @param columnIndex the first column is 1, the second is 2, ...
4048:             * @return an object representing a BLOB
4049:             */
4050:            public Blob getBlob(int columnIndex) throws SQLException {
4051:
4052:                closeCurrentStream(); // closing currentStream does not depend on the
4053:                // underlying connection. Do this outside of
4054:                // the connection synchronization.
4055:
4056:                checkIfClosed("getBlob"); // checking result set closure does not depend
4057:                // on the underlying connection. Do this
4058:                // outside of the connection synchronization.
4059:
4060:                synchronized (getConnectionSynchronization()) {
4061:                    int colType = getColumnType(columnIndex);
4062:
4063:                    // DB2, only allow getBlob on a BLOB column.
4064:                    if (colType != Types.BLOB)
4065:                        throw dataTypeConversion("java.sql.Blob", columnIndex);
4066:
4067:                    boolean pushStack = false;
4068:                    try {
4069:                        DataValueDescriptor dvd = getColumn(columnIndex);
4070:
4071:                        if (wasNull = dvd.isNull())
4072:                            return null;
4073:
4074:                        // should set up a context stack if we have a long column,
4075:                        // since a blob may keep a pointer to a long column in the
4076:                        // database
4077:                        if (dvd.getStream() != null)
4078:                            pushStack = true;
4079:
4080:                        if (pushStack)
4081:                            setupContextStack();
4082:
4083:                        return new EmbedBlob(dvd, getEmbedConnection());
4084:                    } catch (Throwable t) {
4085:                        throw handleException(t);
4086:                    } finally {
4087:                        if (pushStack)
4088:                            restoreContextStack();
4089:                    }
4090:                }
4091:            }
4092:
4093:            /**
4094:             * JDBC 2.0
4095:             * 
4096:             * Get a CLOB column.
4097:             * 
4098:             * @param columnIndex the first column is 1, the second is 2, ...
4099:             * @return an object representing a CLOB
4100:             */
4101:            public final Clob getClob(int columnIndex) throws SQLException {
4102:
4103:                closeCurrentStream(); // closing currentStream does not depend on the
4104:                // underlying connection. Do this outside of
4105:                // the connection synchronization.
4106:
4107:                checkIfClosed("getClob"); // checking result set closure does not depend
4108:                // on the underlying connection. Do this
4109:                // outside of the connection synchronization.
4110:
4111:                synchronized (getConnectionSynchronization()) {
4112:                    int colType = getColumnType(columnIndex);
4113:
4114:                    // DB2:, only allow getClob on a CLOB column.
4115:                    if (colType != Types.CLOB)
4116:                        throw dataTypeConversion("java.sql.Clob", columnIndex);
4117:
4118:                    boolean pushStack = false;
4119:                    try {
4120:
4121:                        DataValueDescriptor dvd = getColumn(columnIndex);
4122:
4123:                        if (wasNull = dvd.isNull())
4124:                            return null;
4125:
4126:                        // should set up a context stack if we have a long column,
4127:                        // since a blob may keep a pointer to a long column in the
4128:                        // database
4129:                        if (dvd.getStream() != null)
4130:                            pushStack = true;
4131:
4132:                        if (pushStack)
4133:                            setupContextStack();
4134:
4135:                        return new EmbedClob(dvd, getEmbedConnection());
4136:                    } catch (Throwable t) {
4137:                        throw handleException(t);
4138:                    } finally {
4139:                        if (pushStack)
4140:                            restoreContextStack();
4141:                    }
4142:                }
4143:            }
4144:
4145:            /**
4146:             * JDBC 2.0
4147:             * 
4148:             * Get a BLOB column.
4149:             * 
4150:             * @param columnName the column name
4151:             * @return an object representing a BLOB
4152:             */
4153:            public final Blob getBlob(String columnName) throws SQLException {
4154:                checkIfClosed("getBlob");
4155:                return (getBlob(findColumnName(columnName)));
4156:            }
4157:
4158:            /**
4159:             * JDBC 2.0
4160:             * 
4161:             * Get a CLOB column.
4162:             * 
4163:             * @param columnName the column name
4164:             * @return an object representing a CLOB
4165:             * @exception SQLException
4166:             *                Feature not implemented for now.
4167:             */
4168:            public final Clob getClob(String columnName) throws SQLException {
4169:                checkIfClosed("getClob");
4170:                return (getClob(findColumnName(columnName)));
4171:            }
4172:
4173:            /**
4174:             * JDBC 3.0
4175:             * 
4176:             * Updates the designated column with a java.sql.Blob value. The updater
4177:             * methods are used to update column values in the current row or the insert
4178:             * row. The updater methods do not update the underlying database; instead
4179:             * the updateRow or insertRow methods are called to update the database.
4180:             * 
4181:             * @param columnIndex -
4182:             *            the first column is 1, the second is 2
4183:             * @param x -
4184:             *            the new column value
4185:             * @exception SQLException
4186:             *                Feature not implemented for now.
4187:             */
4188:            public void updateBlob(int columnIndex, Blob x) throws SQLException {
4189:                checksBeforeUpdateXXX("updateBlob", columnIndex);
4190:                int colType = getColumnType(columnIndex);
4191:                if (colType != Types.BLOB)
4192:                    throw dataTypeConversion(columnIndex, "java.sql.Blob");
4193:
4194:                if (x == null)
4195:                    updateNull(columnIndex);
4196:                else {
4197:                    long length = x.length();
4198:                    updateBinaryStreamInternal(columnIndex,
4199:                            x.getBinaryStream(), false, length, "updateBlob");
4200:                }
4201:            }
4202:
4203:            /**
4204:             * JDBC 3.0
4205:             * 
4206:             * Updates the designated column with a java.sql.Blob value. The updater
4207:             * methods are used to update column values in the current row or the insert
4208:             * row. The updater methods do not update the underlying database; instead
4209:             * the updateRow or insertRow methods are called to update the database.
4210:             * 
4211:             * @param columnName -
4212:             *            the SQL name of the column
4213:             * @param x -
4214:             *            the new column value
4215:             * @exception SQLException
4216:             *                Feature not implemented for now.
4217:             */
4218:            public void updateBlob(String columnName, Blob x)
4219:                    throws SQLException {
4220:                checkIfClosed("updateBlob");
4221:                updateBlob(findColumnName(columnName), x);
4222:            }
4223:
4224:            /**
4225:             * JDBC 3.0
4226:             * 
4227:             * Updates the designated column with a java.sql.Clob value. The updater
4228:             * methods are used to update column values in the current row or the insert
4229:             * row. The updater methods do not update the underlying database; instead
4230:             * the updateRow or insertRow methods are called to update the database.
4231:             * 
4232:             * @param columnIndex -
4233:             *            the first column is 1, the second is 2
4234:             * @param x -
4235:             *            the new column value
4236:             * @exception SQLException
4237:             *                Feature not implemented for now.
4238:             */
4239:            public void updateClob(int columnIndex, Clob x) throws SQLException {
4240:                checksBeforeUpdateXXX("updateClob", columnIndex);
4241:                int colType = getColumnType(columnIndex);
4242:                if (colType != Types.CLOB)
4243:                    throw dataTypeConversion(columnIndex, "java.sql.Clob");
4244:
4245:                if (x == null) {
4246:                    updateNull(columnIndex);
4247:                } else {
4248:
4249:                    long length = x.length();
4250:
4251:                    updateCharacterStreamInternal(columnIndex, x
4252:                            .getCharacterStream(), false, length, "updateClob");
4253:                }
4254:            }
4255:
4256:            /**
4257:             * JDBC 3.0
4258:             * 
4259:             * Updates the designated column with a java.sql.Clob value. The updater
4260:             * methods are used to update column values in the current row or the insert
4261:             * row. The updater methods do not update the underlying database; instead
4262:             * the updateRow or insertRow methods are called to update the database.
4263:             * 
4264:             * @param columnName -
4265:             *            the SQL name of the column
4266:             * @param x -
4267:             *            the new column value
4268:             * @exception SQLException
4269:             *                Feature not implemented for now.
4270:             */
4271:            public void updateClob(String columnName, Clob x)
4272:                    throws SQLException {
4273:                checkIfClosed("updateClob");
4274:                updateClob(findColumnName(columnName), x);
4275:            }
4276:
4277:            /*
4278:             * * End of JDBC public methods.
4279:             */
4280:
4281:            /**
4282:             * Map a Resultset column name to a ResultSet column index.
4283:             * 
4284:             * @param columnName
4285:             *            the name of the column
4286:             * @return the column index
4287:             * @exception SQLException
4288:             *                thrown on failure.
4289:             */
4290:            protected int findColumnName(String columnName) throws SQLException {
4291:                // n.b. if we went through the JDBC interface,
4292:                // there is a caching implementation in the JDBC doc
4293:                // (appendix C). But we go through our own info, for now.
4294:
4295:                if (columnName == null)
4296:                    throw newSQLException(SQLState.NULL_COLUMN_NAME);
4297:
4298:                final Map workMap;
4299:
4300:                synchronized (this ) {
4301:                    if (columnNameMap == null) {
4302:                        // updateXXX and getXXX methods are case insensitive and the 
4303:                        // first column should be returned. The loop goes backward to 
4304:                        // create a map which preserves this property.
4305:                        columnNameMap = new HashMap();
4306:                        for (int i = resultDescription.getColumnCount(); i >= 1; i--) {
4307:
4308:                            final String key = StringUtil
4309:                                    .SQLToUpperCase(resultDescription
4310:                                            .getColumnDescriptor(i).getName());
4311:
4312:                            final Integer value = ReuseFactory.getInteger(i);
4313:
4314:                            columnNameMap.put(key, value);
4315:                        }
4316:                    }
4317:                    workMap = columnNameMap;
4318:                }
4319:
4320:                Integer val = (Integer) workMap.get(columnName);
4321:                if (val == null) {
4322:                    val = (Integer) workMap.get(StringUtil
4323:                            .SQLToUpperCase(columnName));
4324:                }
4325:                if (val == null) {
4326:                    throw newSQLException(SQLState.COLUMN_NOT_FOUND, columnName);
4327:                } else {
4328:                    return val.intValue();
4329:                }
4330:            }
4331:
4332:            //
4333:            // methods to be overridden in subimplementations
4334:            // that want to stay within their subimplementation.
4335:            //
4336:            protected EmbedResultSetMetaData newEmbedResultSetMetaData(
4337:                    ResultDescription resultDesc) {
4338:                return factory.newEmbedResultSetMetaData(resultDesc
4339:                        .getColumnInfo());
4340:            }
4341:
4342:            /**
4343:             * Documented behaviour for streams is that they are implicitly closed on
4344:             * the next get*() method call.
4345:             */
4346:            private final void closeCurrentStream() {
4347:
4348:                if (currentStream != null) {
4349:                    try {
4350:                        // 99% of the time, the stream is already closed.
4351:                        synchronized (this ) {
4352:                            if (currentStream != null) {
4353:                                if (currentStream instanceof  java.io.Reader)
4354:                                    ((java.io.Reader) currentStream).close();
4355:                                else
4356:                                    ((java.io.InputStream) currentStream)
4357:                                            .close();
4358:                            }
4359:                        }
4360:                    } catch (IOException ioe) {
4361:                        // just ignore, caller has already read the data they require
4362:                    } finally {
4363:                        currentStream = null;
4364:                    }
4365:                }
4366:            }
4367:
4368:            /**
4369:             * Throw an exception if this ResultSet is closed.
4370:             *
4371:             * @param operation		The operation the caller is trying to perform
4372:             *
4373:             * @exception SQLException		Thrown if this ResultSet is closed.
4374:             */
4375:            final void checkIfClosed(String operation) throws SQLException {
4376:                if (isClosed) {
4377:                    throw newSQLException(SQLState.LANG_RESULT_SET_NOT_OPEN,
4378:                            operation);
4379:                }
4380:            }
4381:
4382:            /**
4383:             * Throw an exception if this ResultSet is closed or its
4384:             * Connection has been closed. If the ResultSet has not
4385:             * been explictly closed but the Connection is closed,
4386:             * then this ResultSet will be marked as closed.
4387:             */
4388:            final void checkExecIfClosed(String operation) throws SQLException {
4389:
4390:                checkIfClosed(operation);
4391:
4392:                java.sql.Connection appConn = getEmbedConnection()
4393:                        .getApplicationConnection();
4394:
4395:                // Currently disconnected, i.e. a detached gobal transaction
4396:                if (appConn == null)
4397:                    throw Util.noCurrentConnection();
4398:
4399:                if (appConn.isClosed()) {
4400:                    closeCurrentStream();
4401:                    isClosed = true;
4402:                    throw Util.noCurrentConnection();
4403:                }
4404:            }
4405:
4406:            /**
4407:             * Try to see if we can fish the SQL Statement out of the local statement.
4408:             * @return null if we cannot figure out what SQL Statement is currently
4409:             *  executing
4410:             */
4411:            protected String getSQLText() {
4412:                if (stmt == null)
4413:                    return null;
4414:
4415:                return stmt.getSQLText();
4416:            }
4417:
4418:            /**
4419:             * Try to see if we can fish the pvs out of the local statement.
4420:             * @return null if we cannot figure out what parameter value set is currently
4421:             *  using
4422:             */
4423:            protected ParameterValueSet getParameterValueSet() {
4424:                if (stmt == null)
4425:                    return null;
4426:
4427:                return stmt.getParameterValueSet();
4428:            }
4429:
4430:            private static boolean isMaxFieldSizeType(int colType) {
4431:                return (colType == Types.BINARY || colType == Types.VARBINARY
4432:                        || colType == Types.LONGVARBINARY
4433:                        || colType == Types.CHAR || colType == Types.VARCHAR || colType == Types.LONGVARCHAR);
4434:            }
4435:
4436:            /*
4437:             * close result set if we have a transaction level error 
4438:             */
4439:            final SQLException closeOnTransactionError(Throwable thrownException)
4440:                    throws SQLException {
4441:                SQLException sqle = handleException(thrownException);
4442:                if (thrownException instanceof  StandardException) {
4443:                    StandardException se = (StandardException) thrownException;
4444:                    int severity = se.getSeverity();
4445:                    if (severity == ExceptionSeverity.TRANSACTION_SEVERITY) {
4446:                        try {
4447:                            close();
4448:                        } catch (Throwable t) {
4449:                            SQLException top = handleException(t);
4450:                            top.setNextException(sqle);
4451:                            sqle = top;
4452:                        }
4453:                    }
4454:                }
4455:
4456:                return sqle;
4457:            }
4458:
4459:            /**
4460:            	Get the column value for a getXXX() call.
4461:            	This method:
4462:            	<UL>
4463:            	<LI> Closes the current stream (as per JDBC)
4464:            	<LI> Throws a SQLException if the result set is closed
4465:            	<LI> Throws a SQLException if the ResultSet is not on a row
4466:            	<LI> Throws a SQLException if the columnIndex is out of range
4467:            	<LI> Returns the DataValueDescriptor for the column.
4468:            	</UL>
4469:             */
4470:            protected final DataValueDescriptor getColumn(int columnIndex)
4471:                    throws SQLException, StandardException {
4472:
4473:                closeCurrentStream();
4474:
4475:                if (columnIndex < 1 || columnIndex > currentRow.nColumns()) {
4476:                    throw newSQLException(SQLState.COLUMN_NOT_FOUND,
4477:                            new Integer(columnIndex));
4478:                }
4479:                if (isOnInsertRow || currentRowHasBeenUpdated
4480:                        && columnGotUpdated[columnIndex - 1]) {
4481:                    return updateRow.getColumn(columnIndex);
4482:                } else {
4483:                    checkOnRow(); // make sure there's a row
4484:                    return currentRow.getColumn(columnIndex);
4485:                }
4486:            }
4487:
4488:            /**
4489:            	An exception on many method calls to JDBC objects does not change the state
4490:            	of the transaction or statement, or even the underlying object. This method
4491:            	simply wraps the excecption in a SQLException. Examples are:
4492:            	<UL>
4493:            	<LI> getXXX() calls on ResultSet - ResultSet is not closed.
4494:            	<LI> setXXX() calls on PreparedStatement - ResultSet is not closed.
4495:            	</UL>
4496:            	In addition these exceptions must not call higher level objects to
4497:            	be closed (e.g. when executing a server side Java procedure). See bug 4397
4498:
4499:             */
4500:            static final SQLException noStateChangeException(
4501:                    Throwable thrownException) {
4502:
4503:                // Any exception on a setXXX/getXXX method does not close
4504:                // the ResultSet or the Statement. So we only need
4505:                // to convert the exception to a SQLException.
4506:
4507:                return TransactionResourceImpl.wrapInSQLException(
4508:                        (SQLException) null, thrownException);
4509:
4510:            }
4511:
4512:            /**
4513:            	A dynamic result set was created in a procedure by a nested connection.
4514:            	Once the procedure returns, there is a good chance that connection is closed,
4515:            	so we re-attach the result set to the connection of the statement the called
4516:            	the procedure, which will be still open.
4517:             */
4518:            void setDynamicResultSet(EmbedStatement owningStmt) {
4519:
4520:                this .owningStmt = owningStmt;
4521:                this .localConn = owningStmt.getEmbedConnection();
4522:            }
4523:
4524:            /*
4525:             ** Comparable (for ordering dynamic result sets from procedures) 
4526:             */
4527:
4528:            public final int compareTo(Object other) {
4529:
4530:                EmbedResultSet olrs = (EmbedResultSet) other;
4531:
4532:                return order - olrs.order;
4533:
4534:            }
4535:
4536:            /**
4537:             * Checks if the result set has a scrollable cursor.
4538:             *
4539:             * @param methodName name of the method which requests the check
4540:             * @exception SQLException if the result set is closed or its type
4541:             * is <code>TYPE_FORWARD_ONLY</code>
4542:             */
4543:            private void checkScrollCursor(String methodName)
4544:                    throws SQLException {
4545:                checkIfClosed(methodName);
4546:                if (stmt.getResultSetType() == JDBC20Translation.TYPE_FORWARD_ONLY)
4547:                    throw Util
4548:                            .newEmbedSQLException(
4549:                                    SQLState.NOT_ON_FORWARD_ONLY_CURSOR,
4550:                                    new Object[] { methodName },
4551:                                    StandardException
4552:                                            .getSeverityFromIdentifier(SQLState.NOT_ON_FORWARD_ONLY_CURSOR));
4553:            }
4554:
4555:            private void checkUpdatableCursor(String operation)
4556:                    throws SQLException {
4557:                if (getConcurrency() != JDBC20Translation.CONCUR_UPDATABLE) {
4558:                    throw Util.generateCsSQLException(
4559:                            SQLState.UPDATABLE_RESULTSET_API_DISALLOWED,
4560:                            operation);
4561:                }
4562:            }
4563:
4564:            private boolean checkRowPosition(int position, String positionText)
4565:                    throws SQLException {
4566:                // beforeFirst is only allowed on scroll cursors
4567:                checkScrollCursor(positionText);
4568:
4569:                synchronized (getConnectionSynchronization()) {
4570:                    setupContextStack();
4571:                    try {
4572:                        try {
4573:
4574:                            /*
4575:                             * Push and pop a StatementContext around a next call so
4576:                             * that the ResultSet will get correctly closed down on an
4577:                             * error. (Cache the LanguageConnectionContext)
4578:                             */
4579:                            LanguageConnectionContext lcc = getEmbedConnection()
4580:                                    .getLanguageConnection();
4581:                            // No timeout for this operation (use 0)
4582:                            StatementContext statementContext = lcc
4583:                                    .pushStatementContext(
4584:                                            isAtomic,
4585:                                            concurrencyOfThisResultSet == JDBC20Translation.CONCUR_READ_ONLY,
4586:                                            getSQLText(),
4587:                                            getParameterValueSet(), false, 0L);
4588:
4589:                            boolean result = theResults
4590:                                    .checkRowPosition(position);
4591:
4592:                            lcc.popStatementContext(statementContext, null);
4593:
4594:                            return result;
4595:
4596:                        } catch (Throwable t) {
4597:                            /*
4598:                             * Need to close the result set here because the error might
4599:                             * cause us to lose the current connection if this is an XA
4600:                             * connection and we won't be able to do the close later
4601:                             */
4602:                            throw closeOnTransactionError(t);
4603:                        }
4604:
4605:                    } finally {
4606:                        restoreContextStack();
4607:                    }
4608:                }
4609:            }
4610:
4611:            /**
4612:             * * Is this result set from a select for update statement?
4613:             */
4614:            public final boolean isForUpdate() {
4615:                if (theResults instanceof  NoPutResultSet)
4616:                    return ((NoPutResultSet) theResults).isForUpdate();
4617:                return false;
4618:            }
4619:
4620:            final String getColumnSQLType(int column) {
4621:                return resultDescription.getColumnDescriptor(column).getType()
4622:                        .getTypeId().getSQLTypeName();
4623:            }
4624:
4625:            /**
4626:             * Return the user-defined maximum size of the column.
4627:             *
4628:             * Note that this may be different from the maximum column size Derby is
4629:             * able, or allowed, to handle (called 'maximum maximum length').
4630:             *
4631:             * @param columnIndex the 1-based index of the column
4632:             * @return the maximum length of the column
4633:             */
4634:            private final int getMaxColumnWidth(int columnIndex) {
4635:                return resultDescription.getColumnDescriptor(columnIndex)
4636:                        .getType().getMaximumWidth();
4637:            }
4638:
4639:            private final SQLException dataTypeConversion(String targetType,
4640:                    int column) {
4641:                return newSQLException(SQLState.LANG_DATA_TYPE_GET_MISMATCH,
4642:                        targetType, getColumnSQLType(column));
4643:            }
4644:
4645:            private final SQLException dataTypeConversion(int column,
4646:                    String targetType) {
4647:                return newSQLException(SQLState.LANG_DATA_TYPE_GET_MISMATCH,
4648:                        getColumnSQLType(column), targetType);
4649:            }
4650:
4651:            /**
4652:             * Mark a column as already having a stream accessed from it.
4653:             * If the stream was already accessed, then throw an exception.
4654:             * @param columnIndex
4655:             * @throws SQLException
4656:             */
4657:            final void useStream(int columnIndex) throws SQLException {
4658:
4659:                if (streamUsedFlags == null)
4660:                    streamUsedFlags = new boolean[getMetaData()
4661:                            .getColumnCount()];
4662:
4663:                else if (streamUsedFlags[columnIndex - 1])
4664:                    throw newSQLException(SQLState.LANG_STREAM_RETRIEVED_ALREADY);
4665:
4666:                streamUsedFlags[columnIndex - 1] = true;
4667:            }
4668:
4669:            /**
4670:             * JDBC 4.0
4671:             *
4672:             * <p>
4673:             * Checks whether this <code>ResultSet</code> object has been
4674:             * closed, either automatically or because <code>close()</code>
4675:             * has been called.
4676:             *
4677:             * @return <code>true</code> if the <code>ResultSet</code> is
4678:             * closed, <code>false</code> otherwise
4679:             * @exception SQLException if a database error occurs
4680:             */
4681:            public final boolean isClosed() throws SQLException {
4682:                if (isClosed)
4683:                    return true;
4684:                try {
4685:                    // isClosed is not updated when EmbedConnection.close() is
4686:                    // called, so we need to check the status of the
4687:                    // connection
4688:                    checkExecIfClosed("");
4689:                    return false;
4690:                } catch (SQLException sqle) {
4691:                    return isClosed;
4692:                }
4693:            }
4694:
4695:            /**
4696:             * Adds a warning to the end of the warning chain.
4697:             *
4698:             * @param w The warning to add to the warning chain.
4699:             */
4700:            private void addWarning(SQLWarning w) {
4701:                if (topWarning == null) {
4702:                    topWarning = w;
4703:                } else {
4704:                    topWarning.setNextWarning(w);
4705:                }
4706:            }
4707:
4708:            /**
4709:             *
4710:             * JDBC 2.0
4711:             *
4712:             * Update a column with an ascii stream value.
4713:             *
4714:             * The updateXXX() methods are used to update column values in the current
4715:             * row, or the insert row. The updateXXX() methods do not update the
4716:             * underlying database, instead the updateRow() or insertRow() methods are
4717:             * called to update the database.
4718:             *
4719:             * @param columnIndex
4720:             *            the first column is 1, the second is 2, ...
4721:             * @param x
4722:             *            the new column value
4723:             * @param length
4724:             *            the length of the stream
4725:             * @exception SQLException
4726:             *                if a database-access error occurs
4727:             */
4728:            public void updateAsciiStream(int columnIndex,
4729:                    java.io.InputStream x, int length) throws SQLException {
4730:                checkIfClosed("updateAsciiStream");
4731:                updateAsciiStream(columnIndex, x, (long) length);
4732:            }
4733:
4734:            /**
4735:             *
4736:             * JDBC 2.0
4737:             *
4738:             * Update a column with a binary stream value.
4739:             *
4740:             * The updateXXX() methods are used to update column values in the current
4741:             * row, or the insert row. The updateXXX() methods do not update the
4742:             * underlying database, instead the updateRow() or insertRow() methods are
4743:             * called to update the database.
4744:             *
4745:             * @param columnIndex
4746:             *            the first column is 1, the second is 2, ...
4747:             * @param x
4748:             *            the new column value
4749:             * @param length
4750:             *            the length of the stream
4751:             * @exception SQLException
4752:             *                if a database-access error occurs
4753:             */
4754:            public void updateBinaryStream(int columnIndex,
4755:                    java.io.InputStream x, int length) throws SQLException {
4756:                checkIfClosed("updateBinaryStream");
4757:                updateBinaryStream(columnIndex, x, (long) length);
4758:            }
4759:
4760:            /**
4761:             *
4762:             * JDBC 2.0
4763:             *
4764:             * Update a column with a character stream value.
4765:             *
4766:             * The updateXXX() methods are used to update column values in the current
4767:             * row, or the insert row. The updateXXX() methods do not update the
4768:             * underlying database, instead the updateRow() or insertRow() methods are
4769:             * called to update the database.
4770:             *
4771:             * @param columnIndex
4772:             *            the first column is 1, the second is 2, ...
4773:             * @param x
4774:             *            the new column value
4775:             * @param length
4776:             *            the length of the stream
4777:             * @exception SQLException
4778:             *                if a database-access error occurs
4779:             */
4780:            public void updateCharacterStream(int columnIndex,
4781:                    java.io.Reader x, int length) throws SQLException {
4782:                checkIfClosed("updateCharacterStream");
4783:                updateCharacterStream(columnIndex, x, (long) length);
4784:            }
4785:
4786:            /**
4787:             *
4788:             * JDBC 4.0
4789:             *
4790:             * Update a column with an ascii stream value.
4791:             *
4792:             * The updateXXX() methods are used to update column values in the current
4793:             * row, or the insert row. The updateXXX() methods do not update the
4794:             * underlying database, instead the updateRow() or insertRow() methods are
4795:             * called to update the database.
4796:             *
4797:             * @param columnName
4798:             *            the name of the column
4799:             * @param x
4800:             *            the new column value
4801:             * @param length
4802:             *            of the stream
4803:             * @exception SQLException
4804:             *                if a database-access error occurs
4805:             */
4806:            public void updateAsciiStream(String columnName,
4807:                    java.io.InputStream x, long length) throws SQLException {
4808:                checkIfClosed("updateAsciiStream");
4809:                updateAsciiStream(findColumnName(columnName), x, length);
4810:            }
4811:
4812:            /**
4813:             * Updates the designated column with a character stream value.
4814:             * The data will be read from the stream as needed until end-of-stream is
4815:             * reached.
4816:             *
4817:             * The updater methods are used to update column values in the current row
4818:             * or the insert row. The updater methods do not update the underlying
4819:             * database; instead the <code>updateRow</code> or </code>insertRow</code>
4820:             * methods are called to update the database.
4821:             *
4822:             * @param columnName the label for the column specified with the SQL AS
4823:             *      clause. If the SQL AS clause was not specified, then the label is
4824:             *      the name of the column
4825:             * @param x the new column value
4826:             * @throws SQLException if the columnIndex is not valid; if a database
4827:             *      access error occurs; the result set concurrency is
4828:             *      <code>CONCUR_READ_ONLY</code> or this method is called on a closed
4829:             *      result set
4830:             */
4831:            public void updateAsciiStream(String columnName, InputStream x)
4832:                    throws SQLException {
4833:                checkIfClosed("updateAsciiStream");
4834:                updateAsciiStream(findColumnName(columnName), x);
4835:            }
4836:
4837:            /**
4838:             *
4839:             * JDBC 4.0
4840:             *
4841:             * Update a column with a binary stream value.
4842:             *
4843:             * The updateXXX() methods are used to update column values in the current
4844:             * row, or the insert row. The updateXXX() methods do not update the
4845:             * underlying database, instead the updateRow() or insertRow() methods are
4846:             * called to update the database.
4847:             *
4848:             * @param columnName
4849:             *            the name of the column
4850:             * @param x
4851:             *            the new column value
4852:             * @param length
4853:             *            of the stream
4854:             * @exception SQLException
4855:             *                if a database-access error occurs
4856:             */
4857:
4858:            public void updateBinaryStream(String columnName,
4859:                    java.io.InputStream x, long length) throws SQLException {
4860:                checkIfClosed("updateBinaryStream");
4861:                updateBinaryStream(findColumnName(columnName), x, length);
4862:            }
4863:
4864:            /**
4865:             * Updates the designated column with a binary stream value.
4866:             * The data will be read from the stream as needed until end-of-stream is
4867:             * reached.
4868:             *
4869:             * The updater methods are used to update column values in the current row
4870:             * or the insert row. The updater methods do not update the underlying
4871:             * database; instead the <code>updateRow</code> or <code>insertRow</code>
4872:             * methods are called to update the database.
4873:             *
4874:             * @param columnName the label for the column specified with the SQL AS
4875:             *      clause. If the SQL AS clause was not specified, then the label is
4876:             *      the name of the column
4877:             * @param x the new column value
4878:             * @throws SQLException if the columnLabel is not valid; if a database
4879:             *      access error occurs; the result set concurrency is
4880:             *      <code>CONCUR_READ_ONLY</code> or this method is called on a closed
4881:             *      result set
4882:             */
4883:            public void updateBinaryStream(String columnName, InputStream x)
4884:                    throws SQLException {
4885:                checkIfClosed("updateBinaryStream");
4886:                updateBinaryStream(findColumnName(columnName), x);
4887:            }
4888:
4889:            /**
4890:             * JDBC 4.0
4891:             *
4892:             * Update a column with a character stream value.
4893:             *
4894:             * The updateXXX() methods are used to update column values in the current
4895:             * row, or the insert row. The updateXXX() methods do not update the
4896:             * underlying database, instead the updateRow() or insertRow() methods are
4897:             * called to update the database.
4898:             *
4899:             * @param columnName
4900:             *            the name of the column
4901:             * @param reader
4902:             *            the new column value
4903:             * @param length
4904:             *            length of the stream
4905:             * @exception SQLException
4906:             *                if a database-access error occurs
4907:             */
4908:            public void updateCharacterStream(String columnName,
4909:                    java.io.Reader reader, long length) throws SQLException {
4910:                checkIfClosed("updateCharacterStream");
4911:                updateCharacterStream(findColumnName(columnName), reader,
4912:                        length);
4913:            }
4914:
4915:            /**
4916:             * Updates the designated column with a character stream value.
4917:             * The data will be read from the stream as needed until end-of-stream is
4918:             * reached.
4919:             *
4920:             * The updater methods are used to update column values in the current row
4921:             * or the insert row. The updater methods do not update the underlying
4922:             * database; instead the <code>updateRow</code> or </code>insertRow</code>
4923:             * methods are called to update the database.
4924:             *
4925:             * @param columnName the label for the column specified with the SQL AS
4926:             *      clause. If the SQL AS clause was not specified, then the label is
4927:             *      the name of the column
4928:             * @param reader the new column value
4929:             * @throws SQLException if the columnIndex is not valid; if a database
4930:             *      access error occurs; the result set concurrency is
4931:             *      <code>CONCUR_READ_ONLY</code> or this method is called on a closed
4932:             *      result set
4933:             */
4934:            public void updateCharacterStream(String columnName, Reader reader)
4935:                    throws SQLException {
4936:                checkIfClosed("updateCharacterStream");
4937:                updateCharacterStream(findColumnName(columnName), reader);
4938:            }
4939:
4940:            /**
4941:             *
4942:             * JDBC 4.0
4943:             *
4944:             * Updates the designated column with a java.sql.Blob value. The updater
4945:             * methods are used to update column values in the current row or the insert
4946:             * row. The updater methods do not update the underlying database; instead
4947:             * the updateRow or insertRow methods are called to update the database.
4948:             *
4949:             * @param columnIndex -
4950:             *            the first column is 1, the second is 2
4951:             * @param x -
4952:             *            the new column value
4953:             * @param length -
4954:             *            the length of the Blob datatype
4955:             * @exception SQLException
4956:             *
4957:             */
4958:            public void updateBlob(int columnIndex, InputStream x, long length)
4959:                    throws SQLException {
4960:                checksBeforeUpdateXXX("updateBlob", columnIndex);
4961:                int colType = getColumnType(columnIndex);
4962:                if (colType != Types.BLOB)
4963:                    throw dataTypeConversion(columnIndex, "java.sql.Blob");
4964:
4965:                if (x == null)
4966:                    updateNull(columnIndex);
4967:                else {
4968:                    updateBinaryStreamInternal(columnIndex, x, false, length,
4969:                            "updateBlob");
4970:                }
4971:            }
4972:
4973:            /**
4974:             * Updates the designated column using the given input stream.
4975:             * The data will be read from the stream as needed until end-of-stream is reached.
4976:             *
4977:             * The updater methods are used to update column values in the current row
4978:             * or the insert row. The updater methods do not update the underlying
4979:             * database; instead the updateRow or insertRow methods are called to
4980:             * update the database.
4981:             *
4982:             * @param columnIndex the first column is 1, the second is 2, ...
4983:             * @param x an object that contains the data to set the
4984:             *     parameter value to.
4985:             * @throws SQLException if the columnIndex is not valid; if a database
4986:             *     access error occurs; the result set concurrency is
4987:             *     <code>CONCUR_READ_ONLY</code> or this method is called on a closed
4988:             *     result set
4989:             */
4990:            public void updateBlob(int columnIndex, InputStream x)
4991:                    throws SQLException {
4992:                checksBeforeUpdateXXX("updateBlob", columnIndex);
4993:                int colType = getColumnType(columnIndex);
4994:                if (colType != Types.BLOB) {
4995:                    throw dataTypeConversion(columnIndex, "java.sql.Blob");
4996:                }
4997:                updateBinaryStreamInternal(columnIndex, x, true, -1,
4998:                        "updateBlob");
4999:            }
5000:
5001:            /**
5002:             *
5003:             * JDBC 4.0
5004:             *
5005:             * Updates the designated column with a java.sql.Blob value. The updater
5006:             * methods are used to update column values in the current row or the insert
5007:             * row. The updater methods do not update the underlying database; instead
5008:             * the updateRow or insertRow methods are called to update the database.
5009:             *
5010:             * @param columnName -
5011:             *            the name of the column to be updated
5012:             * @param x -
5013:             *            the new column value
5014:             * @param length -
5015:             *            the length of the Blob datatype
5016:             * @exception SQLException
5017:             *
5018:             */
5019:
5020:            public void updateBlob(String columnName, InputStream x, long length)
5021:                    throws SQLException {
5022:                checkIfClosed("updateBlob");
5023:                updateBlob(findColumnName(columnName), x, length);
5024:            }
5025:
5026:            /**
5027:             * Updates the designated column using the given input stream.
5028:             * The data will be read from the stream as needed until end-of-stream is reached.
5029:             *
5030:             * The updater methods are used to update column values in the current row
5031:             * or the insert row. The updater methods do not update the underlying
5032:             * database; instead the updateRow or insertRow methods are called to
5033:             * update the database.
5034:             *
5035:             * @param columnName the label for the column specified with the SQL AS
5036:             *     clause. If the SQL AS clause was not specified, then the label is
5037:             *     the name of the column
5038:             * @param x an object that contains the data to set the
5039:             *     parameter value to.
5040:             * @throws SQLException if the columnIndex is not valid; if a database
5041:             *     access error occurs; the result set concurrency is
5042:             *     <code>CONCUR_READ_ONLY</code> or this method is called on a closed
5043:             *     result set
5044:             */
5045:            public void updateBlob(String columnName, InputStream x)
5046:                    throws SQLException {
5047:                checkIfClosed("updateBlob");
5048:                updateBlob(findColumnName(columnName), x);
5049:            }
5050:
5051:            /**
5052:             *
5053:             * JDBC 4.0
5054:             *
5055:             * Updates the designated column with a java.sql.Clob value. The updater
5056:             * methods are used to update column values in the current row or the insert
5057:             * row. The updater methods do not update the underlying database; instead
5058:             * the updateRow or insertRow methods are called to update the database.
5059:             *
5060:             * @param columnIndex -
5061:             *            the first column is 1, the second is 2
5062:             * @param x -
5063:             *            the new column value
5064:             * @exception SQLException
5065:             *                Feature not implemented for now.
5066:             */
5067:            public void updateClob(int columnIndex, Reader x, long length)
5068:                    throws SQLException {
5069:                checksBeforeUpdateXXX("updateClob", columnIndex);
5070:                int colType = getColumnType(columnIndex);
5071:                if (colType != Types.CLOB)
5072:                    throw dataTypeConversion(columnIndex, "java.sql.Clob");
5073:
5074:                if (x == null) {
5075:                    updateNull(columnIndex);
5076:                } else {
5077:                    updateCharacterStreamInternal(columnIndex, x, false,
5078:                            length, "updateClob");
5079:                }
5080:            }
5081:
5082:            /**
5083:             * Updates the designated column using the given <code>Reader</code>
5084:             * object.
5085:             *
5086:             * The data will be read from the stream as needed until end-of-stream is
5087:             * reached. The JDBC driver will do any necessary conversion from
5088:             * <code>UNICODE</code> to the database char format.
5089:             *
5090:             * The updater methods are used to update column values in the current row
5091:             * or the insert row. The updater methods do not update the underlying
5092:             * database; instead the <code>updateRow</code> or <code>insertRow</code>
5093:             * methods are called to update the database.
5094:             *
5095:             * @param columnIndex the first column is 1, the second is 2, ...
5096:             * @param x an object that contains the data to set the parameter
5097:             *     value to
5098:             * @throws SQLException if the columnIndex is not valid; if a database
5099:             *     access error occurs; the result set concurrency is
5100:             *     <code>CONCUR_READ_ONLY</code> or this method is called on a closed
5101:             *     result set
5102:             */
5103:            public void updateClob(int columnIndex, Reader x)
5104:                    throws SQLException {
5105:                checksBeforeUpdateXXX("updateClob", columnIndex);
5106:                int colType = getColumnType(columnIndex);
5107:                if (colType != Types.CLOB) {
5108:                    throw dataTypeConversion(columnIndex, "java.sql.Clob");
5109:                }
5110:                updateCharacterStreamInternal(columnIndex, x, true, -1,
5111:                        "updateClob");
5112:            }
5113:
5114:            /**
5115:             *
5116:             * JDBC 4.0
5117:             *
5118:             * Updates the designated column with a java.sql.Clob value. The updater
5119:             * methods are used to update column values in the current row or the insert
5120:             * row. The updater methods do not update the underlying database; instead
5121:             * the updateRow or insertRow methods are called to update the database.
5122:             *
5123:             * @param columnName -
5124:             *            the name of the Clob column
5125:             * @param x -
5126:             *            the new column value
5127:             * @exception SQLException
5128:             *                Feature not implemented for now.
5129:             */
5130:
5131:            public void updateClob(String columnName, Reader x, long length)
5132:                    throws SQLException {
5133:                checkIfClosed("updateClob");
5134:                updateClob(findColumnName(columnName), x, length);
5135:            }
5136:
5137:            /**
5138:             * Updates the designated column using the given <code>Reader</code>
5139:             * object.
5140:             *
5141:             * The data will be read from the stream as needed until end-of-stream is
5142:             * reached. The JDBC driver will do any necessary conversion from
5143:             * <code>UNICODE</code> to the database char format.
5144:             *
5145:             * The updater methods are used to update column values in the current row
5146:             * or the insert row. The updater methods do not update the underlying
5147:             * database; instead the <code>updateRow</code> or <code>insertRow</code>
5148:             * methods are called to update the database.
5149:             *
5150:             * @param columnName the label for the column specified with the SQL AS
5151:             *     clause. If the SQL AS clause was not specified, then the label is
5152:             *     the name of the column
5153:             * @param x an object that contains the data to set the parameter
5154:             *     value to
5155:             * @throws SQLException if the columnIndex is not valid; if a database
5156:             *     access error occurs; the result set concurrency is
5157:             *     <code>CONCUR_READ_ONLY</code> or this method is called on a closed
5158:             *     result set
5159:             */
5160:            public void updateClob(String columnName, Reader x)
5161:                    throws SQLException {
5162:                checkIfClosed("updateClob");
5163:                updateClob(findColumnName(columnName), x);
5164:            }
5165:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.