Source Code Cross Referenced for EmbedStatement.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.EmbedStatement
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.reference.JDBC20Translation;
0025:        import org.apache.derby.iapi.reference.JDBC30Translation;
0026:        import org.apache.derby.iapi.reference.SQLState;
0027:
0028:        import org.apache.derby.iapi.services.sanity.SanityManager;
0029:
0030:        import org.apache.derby.iapi.sql.Activation;
0031:        import org.apache.derby.iapi.sql.PreparedStatement;
0032:        import org.apache.derby.iapi.sql.ResultSet;
0033:        import org.apache.derby.iapi.sql.ParameterValueSet;
0034:        import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;
0035:        import org.apache.derby.iapi.error.StandardException;
0036:        import org.apache.derby.iapi.jdbc.EngineStatement;
0037:
0038:        import java.sql.SQLException;
0039:        import java.sql.SQLWarning;
0040:        import java.util.Vector;
0041:
0042:        /*
0043:         We would import these, but have name-overlap
0044:         import java.sql.Statement;
0045:         import java.sql.ResultSet;
0046:         */
0047:
0048:        /**
0049:         *
0050:         * EmbedStatement is a local JDBC statement.
0051:         *
0052:         <P><B>Supports</B>
0053:         <UL>
0054:         <LI> JSR169 - no subsetting for java.sql.Statement
0055:         <LI> JDBC 2.0
0056:         <LI> JDBC 3.0 - no new dependencies on new JDBC 3.0 or JDK 1.4 classes,
0057:         new methods can safely be added into implementation.
0058:         </UL>
0059:
0060:         * @author ames
0061:         */
0062:        public class EmbedStatement extends ConnectionChild implements 
0063:                EngineStatement {
0064:
0065:            private final java.sql.Connection applicationConnection;
0066:
0067:            /**
0068:             * Statement reference the application is using to execute
0069:             * this Statement. Normally set to this, but if this was
0070:             * created by a Connection from an XAConnection then this
0071:             * will be a reference to the BrokeredStatement.
0072:             *
0073:             * Making it protected to allow access from EmbedPreparedStatement40
0074:             * to be used for StatementEvents
0075:             *
0076:             */
0077:            protected EngineStatement applicationStatement;
0078:
0079:            int updateCount = -1;
0080:            java.sql.ResultSet results;
0081:            //for jdbc3.0 feature, where you can get a resultset of rows inserted
0082:            //for auto generated columns after an insert
0083:            private java.sql.ResultSet autoGeneratedKeysResultSet;
0084:            private String cursorName;
0085:
0086:            private final boolean forMetaData;
0087:            final int resultSetType;
0088:            private final int resultSetConcurrency;
0089:            private final int resultSetHoldability;
0090:            final LanguageConnectionContext lcc;
0091:
0092:            private SQLWarning warnings;
0093:            String SQLText;
0094:
0095:            private int fetchSize = 1;
0096:            private int fetchDirection = JDBC20Translation.FETCH_FORWARD;
0097:            int MaxFieldSize;
0098:            private int timeoutSeconds;
0099:
0100:            //the state of this statement, set to false when close() is called
0101:            private boolean active = true;
0102:
0103:            //in case of batch update, save the individual statements in the batch in this vector
0104:            //this is only used by JDBC 2.0
0105:            Vector batchStatements;
0106:
0107:            // The maximum # of rows to return per result set.
0108:            // (0 means no limit.)
0109:            int maxRows;
0110:
0111:            private ParameterValueSet pvs;
0112:
0113:            // An EmbedStatement is NOT poolable by default. The constructor for
0114:            // PreparedStatement overrides this.
0115:            protected boolean isPoolable = false;
0116:
0117:            //
0118:            // constructor
0119:            //
0120:            public EmbedStatement(EmbedConnection connection,
0121:                    boolean forMetaData, int resultSetType,
0122:                    int resultSetConcurrency, int resultSetHoldability) {
0123:                super (connection);
0124:                this .forMetaData = forMetaData;
0125:                this .resultSetType = resultSetType;
0126:                this .resultSetConcurrency = resultSetConcurrency;
0127:                this .resultSetHoldability = resultSetHoldability;
0128:
0129:                lcc = getEmbedConnection().getLanguageConnection();
0130:                applicationConnection = getEmbedConnection()
0131:                        .getApplicationConnection();
0132:                applicationStatement = this ;
0133:
0134:                // By default, no statements time out.
0135:                // Timeout is set explicitly with setQueryTimeout().
0136:                timeoutSeconds = 0;
0137:            }
0138:
0139:            //
0140:            // java.sql.Statement interface
0141:            // the comments are those from the JDBC interface,
0142:            // so we know what we're supposed to to.
0143:
0144:            /**
0145:             * Execute a SQL statement that returns a single ResultSet.
0146:             *
0147:             * @param sql					typically this is a static SQL SELECT statement
0148:             * @return a ResultSet that contains the data produced by the
0149:             * query; never null
0150:             * @exception SQLException thrown on failure.
0151:             */
0152:            public java.sql.ResultSet executeQuery(String sql)
0153:                    throws SQLException {
0154:                execute(sql, true, false, JDBC30Translation.NO_GENERATED_KEYS,
0155:                        null, null);
0156:
0157:                if (SanityManager.DEBUG) {
0158:                    if (results == null)
0159:                        SanityManager
0160:                                .THROWASSERT("no results returned on executeQuery()");
0161:                }
0162:
0163:                return results;
0164:            }
0165:
0166:            /**
0167:             * Execute a SQL INSERT, UPDATE or DELETE statement. In addition,
0168:             * SQL statements that return nothing such as SQL DDL statements
0169:             * can be executed.
0170:             *
0171:             * @param sql a SQL INSERT, UPDATE or DELETE statement or a SQL
0172:             * statement that returns nothing
0173:             * @return either the row count for INSERT, UPDATE or DELETE; or 0
0174:             * for SQL statements that return nothing
0175:             * @exception SQLException thrown on failure.
0176:             */
0177:            public int executeUpdate(String sql) throws SQLException {
0178:                execute(sql, false, true, JDBC30Translation.NO_GENERATED_KEYS,
0179:                        null, null);
0180:                return updateCount;
0181:            }
0182:
0183:            /**
0184:             * JDBC 3.0
0185:             *
0186:             * Execute the given SQL statement and signals the driver with the given flag
0187:             * about whether the auto-generated keys produced by this Statement object
0188:             * should be made available for retrieval.
0189:             *
0190:             * @param sql a SQL INSERT, UPDATE or DELETE statement or a SQL
0191:             * statement that returns nothing
0192:             * @param autoGeneratedKeys - a flag indicating whether auto-generated keys
0193:             * should be made available for retrieval; one of the following constants:
0194:             * Statement.RETURN_GENERATED_KEYS Statement.NO_GENERATED_KEYS
0195:             * @return either the row count for INSERT, UPDATE or DELETE; or 0
0196:             * for SQL statements that return nothing
0197:             * @exception SQLException if a database access error occurs
0198:             */
0199:            public int executeUpdate(String sql, int autoGeneratedKeys)
0200:                    throws SQLException {
0201:                execute(sql, false, true, autoGeneratedKeys, null, null);
0202:                return updateCount;
0203:            }
0204:
0205:            /**
0206:             * JDBC 3.0
0207:             *
0208:             * Executes the given SQL statement and signals the driver that the
0209:             * auto-generated keys indicated in the given array should be made
0210:             * available for retrieval. The driver will ignore the array if the SQL
0211:             * statement is not an INSERT statement
0212:             *
0213:             * @param sql a SQL INSERT, UPDATE or DELETE statement or a SQL
0214:             * statement that returns nothing
0215:             * @param columnIndexes - an array of column indexes indicating the
0216:             * columns that should be returned from the inserted row
0217:             * @return either the row count for INSERT, UPDATE or DELETE; or 0
0218:             * for SQL statements that return nothing
0219:             * @exception SQLException if a database access error occurs
0220:             */
0221:            public int executeUpdate(String sql, int[] columnIndexes)
0222:                    throws SQLException {
0223:                throw Util.notImplemented("executeUpdate(String, int[])");
0224:            }
0225:
0226:            /**
0227:             * JDBC 3.0
0228:             *
0229:             * Executes the given SQL statement and signals the driver that the
0230:             * auto-generated keys indicated in the given array should be made
0231:             * available for retrieval. The driver will ignore the array if the SQL
0232:             * statement is not an INSERT statement
0233:             *
0234:             * @param sql a SQL INSERT, UPDATE or DELETE statement or a SQL
0235:             * statement that returns nothing
0236:             * @param columnNames - an array of the names of the columns
0237:             * that should be returned from the inserted row
0238:             * @return either the row count for INSERT, UPDATE or DELETE; or 0
0239:             * for SQL statements that return nothing
0240:             * @exception SQLException if a database access error occurs
0241:             */
0242:            public int executeUpdate(String sql, String[] columnNames)
0243:                    throws SQLException {
0244:                throw Util.notImplemented("executeUpdate(String, String[])");
0245:            }
0246:
0247:            final void checkIfInMiddleOfBatch() throws SQLException {
0248:                /* If batchStatements is not null then we are in the middle
0249:                 * of a batch. That's an invalid state. We need to finish the
0250:                 * batch either by clearing the batch or executing the batch.
0251:                 * executeUpdate is not allowed inside the batch.
0252:                 */
0253:                if (batchStatements != null)
0254:                    throw newSQLException(SQLState.MIDDLE_OF_BATCH);
0255:            }
0256:
0257:            /**
0258:             * Tell whether this statment has been closed or not.
0259:             *
0260:             * @return <code>true</code> is closed, <code>false</code> otherwise.
0261:             * @exception SQLException if a database access error occurs.
0262:             */
0263:            public boolean isClosed() throws SQLException {
0264:                // If active, verify state by consulting parent connection.
0265:                if (active) {
0266:                    try {
0267:                        checkExecStatus();
0268:                    } catch (SQLException sqle) {
0269:                    }
0270:                }
0271:                return !active;
0272:            }
0273:
0274:            /**
0275:             * In many cases, it is desirable to immediately release a
0276:             * Statements's database and JDBC resources instead of waiting for
0277:             * this to happen when it is automatically closed; the close
0278:             * method provides this immediate release.
0279:             *
0280:             * <P><B>Note:</B> A Statement is automatically closed when it is
0281:             * garbage collected. When a Statement is closed its current
0282:             * ResultSet, if one exists, is also closed.
0283:             * @exception SQLException thrown on failure.
0284:             */
0285:            public final void close() throws SQLException {
0286:
0287:                /* The close() method is the only method
0288:                 * that is allowed to be called on a closed
0289:                 * Statement, as per Jon Ellis.
0290:                 */
0291:                if (!active) {
0292:                    return;
0293:                }
0294:
0295:                synchronized (getConnectionSynchronization()) {
0296:
0297:                    closeActions();
0298:
0299:                    //we first set the status
0300:                    active = false;
0301:
0302:                    //first, clear the resutl set
0303:                    clearResultSets();
0304:
0305:                    //next, release other resource
0306:                    cursorName = null;
0307:                    warnings = null;
0308:                    SQLText = null;
0309:                    batchStatements = null;
0310:                }
0311:            }
0312:
0313:            // allow sub-classes to execute additional close
0314:            // logic while holding the synchronization.
0315:            void closeActions() throws SQLException {
0316:            }
0317:
0318:            //----------------------------------------------------------------------
0319:
0320:            /**
0321:             * The maxFieldSize limit (in bytes) is the maximum amount of data
0322:             * returned for any column value; it only applies to BINARY,
0323:             * VARBINARY, LONGVARBINARY, CHAR, VARCHAR, and LONGVARCHAR
0324:             * columns.  If the limit is exceeded, the excess data is silently
0325:             * discarded.
0326:             *
0327:             * @return the current max column size limit; zero means unlimited
0328:             * @exception SQLException thrown on failure.
0329:             */
0330:            public int getMaxFieldSize() throws SQLException {
0331:                checkStatus();
0332:
0333:                return MaxFieldSize;
0334:            }
0335:
0336:            /**
0337:             * The maxFieldSize limit (in bytes) is set to limit the size of
0338:             * data that can be returned for any column value; it only applies
0339:             * to BINARY, VARBINARY, LONGVARBINARY, CHAR, VARCHAR, and
0340:             * LONGVARCHAR fields.  If the limit is exceeded, the excess data
0341:             * is silently discarded.
0342:             *
0343:             * @param max the new max column size limit; zero means unlimited
0344:             * @exception SQLException thrown on failure.
0345:             */
0346:            public void setMaxFieldSize(int max) throws SQLException {
0347:                checkStatus();
0348:
0349:                if (max < 0) {
0350:                    throw newSQLException(SQLState.INVALID_MAXFIELD_SIZE,
0351:                            new Integer(max));
0352:                }
0353:                this .MaxFieldSize = max;
0354:            }
0355:
0356:            /**
0357:             * The maxRows limit is the maximum number of rows that a
0358:             * ResultSet can contain.  If the limit is exceeded, the excess
0359:             * rows are silently dropped.
0360:             *
0361:             * @return the current max row limit; zero means unlimited
0362:             * @exception SQLException thrown on failure.
0363:             */
0364:            public int getMaxRows() throws SQLException {
0365:                checkStatus();
0366:                return maxRows;
0367:            }
0368:
0369:            /**
0370:             * The maxRows limit is set to limit the number of rows that any
0371:             * ResultSet can contain.  If the limit is exceeded, the excess
0372:             * rows are silently dropped.
0373:             *
0374:             * @param max the new max rows limit; zero means unlimited
0375:             * @exception SQLException thrown on failure.
0376:             */
0377:            public void setMaxRows(int max) throws SQLException {
0378:                checkStatus();
0379:                if (max < 0) {
0380:                    throw newSQLException(SQLState.INVALID_MAX_ROWS_VALUE,
0381:                            new Integer(max));
0382:                }
0383:                this .maxRows = max;
0384:            }
0385:
0386:            /**
0387:             * If escape scanning is on (the default) the driver will do
0388:             * escape substitution before sending the SQL to the database.
0389:             *
0390:             * @param enable true to enable; false to disable
0391:             * @exception SQLException thrown on failure.
0392:             */
0393:            public void setEscapeProcessing(boolean enable) throws SQLException {
0394:                checkStatus();
0395:                // Nothing to do in our server , just ignore it.
0396:
0397:            }
0398:
0399:            /**
0400:             * The queryTimeout limit is the number of seconds the driver will
0401:             * wait for a Statement to execute. If the limit is exceeded a
0402:             * SQLException is thrown.
0403:             *
0404:             * @return the current query timeout limit in seconds; zero means unlimited
0405:             * @exception SQLException thrown on failure.
0406:             */
0407:            public final int getQueryTimeout() throws SQLException {
0408:                checkStatus();
0409:                return timeoutSeconds;
0410:            }
0411:
0412:            /**
0413:             * The queryTimeout limit is the number of seconds the driver will
0414:             * wait for a Statement to execute. If the limit is exceeded a
0415:             * SQLException is thrown.
0416:             *
0417:             * @param seconds the new query timeout limit in seconds; zero means unlimited
0418:             * @exception SQLException thrown on failure.
0419:             */
0420:            public final void setQueryTimeout(int seconds) throws SQLException {
0421:                checkStatus();
0422:                if (seconds < 0) {
0423:                    throw newSQLException(SQLState.INVALID_QUERYTIMEOUT_VALUE,
0424:                            new Integer(seconds));
0425:                }
0426:                timeoutSeconds = seconds;
0427:            }
0428:
0429:            /**
0430:             * Cancel can be used by one thread to cancel a statement that
0431:             * is being executed by another thread.
0432:             * @exception SQLException thrown on failure.
0433:             */
0434:            public void cancel() throws SQLException {
0435:                throw Util.notImplemented("cancel");
0436:            }
0437:
0438:            /**
0439:             * The first warning reported by calls on this Statement is
0440:             * returned.  A Statment's execute methods clear its SQLWarning
0441:             * chain. Subsequent Statement warnings will be chained to this
0442:             * SQLWarning.
0443:             *
0444:             * <p>The warning chain is automatically cleared each time
0445:             * a statement is (re)executed.
0446:             *
0447:             * <P><B>Note:</B> If you are processing a ResultSet then any
0448:             * warnings associated with ResultSet reads will be chained on the
0449:             * ResultSet object.
0450:             *
0451:             * @return the first SQLWarning or null
0452:             * @exception SQLException thrown on failure.
0453:             */
0454:            public SQLWarning getWarnings() throws SQLException {
0455:                checkStatus();
0456:                return warnings;
0457:            }
0458:
0459:            /**
0460:             * After this call getWarnings returns null until a new warning is
0461:             * reported for this Statement.
0462:             * @exception SQLException thrown on failure.
0463:             */
0464:            public void clearWarnings() throws SQLException {
0465:                checkStatus();
0466:                warnings = null;
0467:            }
0468:
0469:            /**
0470:             * setCursorName defines the SQL cursor name that will be used by
0471:             * subsequent Statement execute methods. This name can then be
0472:             * used in SQL positioned update/delete statements to identify the
0473:             * current row in the ResultSet generated by this statement.  If
0474:             * the database doesn't support positioned update/delete, this
0475:             * method is a noop.
0476:             *
0477:             * <P><B>Note:</B> By definition, positioned update/delete
0478:             * execution must be done by a different Statement than the one
0479:             * which generated the ResultSet being used for positioning. Also,
0480:             * cursor names must be unique within a Connection.
0481:             *
0482:             * @param name the new cursor name.
0483:             */
0484:            public void setCursorName(String name) throws SQLException {
0485:                checkStatus();
0486:                cursorName = name;
0487:            }
0488:
0489:            //----------------------- Multiple Results --------------------------
0490:
0491:            /**
0492:             * Execute a SQL statement that may return multiple results.
0493:             * Under some (uncommon) situations a single SQL statement may return
0494:             * multiple result sets and/or update counts.  Normally you can ignore
0495:             * this, unless you're executing a stored procedure that you know may
0496:             * return multiple results, or unless you're dynamically executing an
0497:             * unknown SQL string.  The "execute", "getMoreResults", "getResultSet"
0498:             * and "getUpdateCount" methods let you navigate through multiple results.
0499:             *
0500:             * The "execute" method executes a SQL statement and indicates the
0501:             * form of the first result.  You can then use getResultSet or
0502:             * getUpdateCount to retrieve the result, and getMoreResults to
0503:             * move to any subsequent result(s).
0504:             *
0505:             * @param sql					any SQL statement
0506:             *
0507:             * @return true if the first result is a ResultSet; false if it is an integer
0508:             * @see #getResultSet
0509:             * @see #getUpdateCount
0510:             * @see #getMoreResults
0511:             * @exception SQLException thrown on failure
0512:             */
0513:            public boolean execute(String sql) throws SQLException {
0514:                return execute(sql, false, false,
0515:                        JDBC30Translation.NO_GENERATED_KEYS, null, null);
0516:            }
0517:
0518:            /**
0519:             * Execute a SQL statement that may return multiple results.
0520:             * Under some (uncommon) situations a single SQL statement may return
0521:             * multiple result sets and/or update counts.  Normally you can ignore
0522:             * this, unless you're executing a stored procedure that you know may
0523:             * return multiple results, or unless you're dynamically executing an
0524:             * unknown SQL string.  The "execute", "getMoreResults", "getResultSet"
0525:             * and "getUpdateCount" methods let you navigate through multiple results.
0526:             *
0527:             * The "execute" method executes a SQL statement and indicates the
0528:             * form of the first result.  You can then use getResultSet or
0529:             * getUpdateCount to retrieve the result, and getMoreResults to
0530:             * move to any subsequent result(s).
0531:             *
0532:             * @param sql					any SQL statement
0533:             * @param executeQuery			caller is executeQuery()
0534:             * @param executeUpdate			caller is executeUpdate()
0535:             * @param autoGeneratedKeys
0536:             * @param columnIndexes
0537:             * @param columnNames
0538:             *
0539:             * @return true if the first result is a ResultSet; false if it is an integer
0540:             * @see #getResultSet
0541:             * @see #getUpdateCount
0542:             * @see #getMoreResults
0543:             * @exception SQLException thrown on failure
0544:             */
0545:            private boolean execute(String sql, boolean executeQuery,
0546:                    boolean executeUpdate, int autoGeneratedKeys,
0547:                    int[] columnIndexes, String[] columnNames)
0548:                    throws SQLException {
0549:                synchronized (getConnectionSynchronization()) {
0550:
0551:                    checkExecStatus();
0552:                    if (sql == null) {
0553:                        throw newSQLException(SQLState.NULL_SQL_TEXT);
0554:                    }
0555:                    checkIfInMiddleOfBatch();
0556:                    clearResultSets(); // release the last statement executed, if any.
0557:
0558:                    setupContextStack(); // make sure there's context
0559:
0560:                    // try to remember the SQL statement in case anybody asks for it
0561:                    SQLText = sql;
0562:
0563:                    try {
0564:                        Activation activation;
0565:                        try {
0566:                            PreparedStatement preparedStatement = lcc
0567:                                    .prepareInternalStatement(
0568:                                            lcc.getDefaultSchema(),
0569:                                            sql,
0570:                                            resultSetConcurrency == JDBC20Translation.CONCUR_READ_ONLY,
0571:                                            false);
0572:                            activation = preparedStatement
0573:                                    .getActivation(
0574:                                            lcc,
0575:                                            resultSetType == JDBC20Translation.TYPE_SCROLL_INSENSITIVE);
0576:                            checkRequiresCallableStatement(activation);
0577:                        } catch (Throwable t) {
0578:                            throw handleException(t);
0579:                        }
0580:
0581:                        // this is for a Statement execution
0582:                        activation.setSingleExecution();
0583:
0584:                        //bug 4838 - save the auto-generated key information in activation. keeping this
0585:                        //information in lcc will not work work it can be tampered by a nested trasaction
0586:                        if (autoGeneratedKeys == JDBC30Translation.RETURN_GENERATED_KEYS)
0587:                            activation.setAutoGeneratedKeysResultsetInfo(
0588:                                    columnIndexes, columnNames);
0589:                        return executeStatement(activation, executeQuery,
0590:                                executeUpdate);
0591:                    } finally {
0592:                        restoreContextStack();
0593:                    }
0594:                }
0595:            }
0596:
0597:            /**
0598:             * JDBC 3.0
0599:             *
0600:             * Executes the given SQL statement, which may return multiple
0601:             * results, and signals the driver that any auto-generated keys
0602:             * should be made available for retrieval. The driver will ignore
0603:             * this signal if the SQL statement is not an INSERT statement.
0604:             *
0605:             * @param sql any SQL statement
0606:             * @param autoGeneratedKeys - a constant indicating whether
0607:             * auto-generated keys should be made available for retrieval using
0608:             * the method getGeneratedKeys; one of the following constants:
0609:             * Statement.RETURN_GENERATED_KEYS or Statement.NO_GENERATED_KEYS
0610:             * @return rue if the first result is a ResultSet object; false if
0611:             * it is an update count or there are no results
0612:             * @exception SQLException if a database access error occurs
0613:             */
0614:            public boolean execute(String sql, int autoGeneratedKeys)
0615:                    throws SQLException {
0616:                return execute(sql, false, false, autoGeneratedKeys, null, null);
0617:            }
0618:
0619:            /**
0620:             * JDBC 3.0
0621:             *
0622:             * Executes the given SQL statement, which may return multiple
0623:             * results, and signals the driver that the auto-generated keys
0624:             * indicated in the given array should be made available for retrieval.
0625:             * This array contains the indexes of the columns in the target table
0626:             * that contain the auto-generated keys that should be made available.
0627:             * The driver will ignore the array if the given SQL statement is not an
0628:             * INSERT statement.
0629:             *
0630:             * @param sql any SQL statement
0631:             * @param columnIndexes - an array of the indexes of the columns in the
0632:             * inserted row that should be made available for retrieval by a call to
0633:             * the method getGeneratedKeys
0634:             * @return rue if the first result is a ResultSet object; false if
0635:             * it is an update count or there are no results
0636:             * @exception SQLException if a database access error occurs
0637:             */
0638:            public boolean execute(String sql, int[] columnIndexes)
0639:                    throws SQLException {
0640:                throw Util.notImplemented("execute(String, int[])");
0641:            }
0642:
0643:            /**
0644:             * JDBC 3.0
0645:             *
0646:             * Executes the given SQL statement, which may return multiple
0647:             * results, and signals the driver that the auto-generated keys
0648:             * indicated in the given array should be made available for retrieval.
0649:             * This array contains the names of the columns in the target table
0650:             * that contain the auto-generated keys that should be made available.
0651:             * The driver will ignore the array if the given SQL statement is not an
0652:             * INSERT statement.
0653:             *
0654:             * @param sql any SQL statement
0655:             * @param columnNames - an array of the names of the columns in the
0656:             * inserted row that should be made available for retrieval by a call to
0657:             * the method getGeneratedKeys
0658:             * @return rue if the first result is a ResultSet object; false if
0659:             * it is an update count or there are no results
0660:             * @exception SQLException if a database access error occurs
0661:             */
0662:            public boolean execute(String sql, String[] columnNames)
0663:                    throws SQLException {
0664:                throw Util.notImplemented("execute(String, String[])");
0665:            }
0666:
0667:            /**
0668:             *  getResultSet returns the current result as a ResultSet.  It
0669:             *  should only be called once per result.
0670:             *
0671:             * @return the current result as a ResultSet; null if the result
0672:             * is an update count or there are no more results or the statement
0673:             * was closed.
0674:             * @see #execute
0675:             */
0676:            public final java.sql.ResultSet getResultSet() throws SQLException {
0677:                checkStatus();
0678:
0679:                return results;
0680:            }
0681:
0682:            /**
0683:             *  getUpdateCount returns the current result as an update count;
0684:             *  if the result is a ResultSet or there are no more results -1
0685:             *  is returned.  It should only be called once per result.
0686:             *
0687:             * <P>The only way to tell for sure that the result is an update
0688:             *  count is to first test to see if it is a ResultSet. If it is
0689:             *  not a ResultSet it is either an update count or there are no
0690:             *  more results.
0691:             *
0692:             * @return the current result as an update count; -1 if it is a
0693:             * ResultSet or there are no more results
0694:             * @see #execute
0695:             */
0696:            public final int getUpdateCount() throws SQLException {
0697:                checkStatus();
0698:                return updateCount;
0699:            }
0700:
0701:            /**
0702:             * getMoreResults moves to a Statement's next result.  It returns true if
0703:             * this result is a ResultSet.  getMoreResults also implicitly
0704:             * closes any current ResultSet obtained with getResultSet.
0705:             *
0706:             * There are no more results when (!getMoreResults() &&
0707:             * (getUpdateCount() == -1)
0708:             *
0709:             * @return true if the next result is a ResultSet; false if it is
0710:             * an update count or there are no more results
0711:             * @see #execute
0712:             * @exception SQLException thrown on failure.
0713:             */
0714:            public final boolean getMoreResults() throws SQLException {
0715:                return getMoreResults(JDBC30Translation.CLOSE_ALL_RESULTS);
0716:            }
0717:
0718:            /////////////////////////////////////////////////////////////////////////
0719:            //
0720:            //	JDBC 2.0 methods that are implemented here because EmbedPreparedStatement
0721:            //  and EmbedCallableStatement in Local20 need access to them, and those
0722:            //	classes extend their peer classes in Local, instead of EmbedStatement
0723:            //	in Local20
0724:            //
0725:            //  We do the same of JDBC 3.0 methods.
0726:            /////////////////////////////////////////////////////////////////////////
0727:
0728:            /**
0729:             * JDBC 2.0
0730:             *
0731:             * Determine the result set type.
0732:             *
0733:             * @exception SQLException Feature not implemented for now.
0734:             */
0735:            public final int getResultSetType() throws SQLException {
0736:                checkStatus();
0737:                return resultSetType;
0738:            }
0739:
0740:            /**
0741:             * JDBC 2.0
0742:             *
0743:             * Give a hint as to the direction in which the rows in a result set
0744:             * will be processed. The hint applies only to result sets created
0745:             * using this Statement object.  The default value is 
0746:             * ResultSet.FETCH_FORWARD.
0747:             *
0748:             * @param direction the initial direction for processing rows
0749:             * @exception SQLException if a database-access error occurs or direction
0750:             * is not one of ResultSet.FETCH_FORWARD, ResultSet.FETCH_REVERSE, or
0751:             * ResultSet.FETCH_UNKNOWN
0752:             */
0753:            public void setFetchDirection(int direction) throws SQLException {
0754:
0755:                checkStatus();
0756:                /* fetch direction is meaningless to us. we just save
0757:                 * it off if it is valid  and return the current value if asked.
0758:                 */
0759:                if (direction == JDBC20Translation.FETCH_FORWARD
0760:                        || direction == JDBC20Translation.FETCH_REVERSE
0761:                        || direction == JDBC20Translation.FETCH_UNKNOWN) {
0762:                    fetchDirection = direction;
0763:                } else
0764:                    throw newSQLException(SQLState.INVALID_FETCH_DIRECTION,
0765:                            new Integer(direction));
0766:            }
0767:
0768:            /**
0769:             * JDBC 2.0
0770:             *
0771:             * Determine the fetch direction.
0772:             *
0773:             * @return the default fetch direction
0774:             * @exception SQLException if a database-access error occurs
0775:             */
0776:            public int getFetchDirection() throws SQLException {
0777:                checkStatus();
0778:                return fetchDirection;
0779:            }
0780:
0781:            /**
0782:             * JDBC 2.0
0783:             *
0784:             * Give the JDBC driver a hint as to the number of rows that should
0785:             * be fetched from the database when more rows are needed.  The number 
0786:             * of rows specified only affects result sets created using this 
0787:             * statement. If the value specified is zero, then the hint is ignored.
0788:             * The default value is zero.
0789:             *
0790:             * @param rows the number of rows to fetch
0791:             * @exception SQLException if a database-access error occurs, or the
0792:             * condition 0 <= rows <= this.getMaxRows() is not satisfied.
0793:             */
0794:            public void setFetchSize(int rows) throws SQLException {
0795:                checkStatus();
0796:                if (rows < 0
0797:                        || (this .getMaxRows() != 0 && rows > this .getMaxRows())) {
0798:                    throw newSQLException(SQLState.INVALID_ST_FETCH_SIZE,
0799:                            new Integer(rows));
0800:                } else if (rows > 0) // ignore the call if the value is zero
0801:                    fetchSize = rows;
0802:            }
0803:
0804:            /**
0805:             * JDBC 2.0
0806:             *
0807:             * Determine the default fetch size.
0808:             * @exception SQLException if a database-access error occurs
0809:             *
0810:             */
0811:            public int getFetchSize() throws SQLException {
0812:                checkStatus();
0813:                return fetchSize;
0814:            }
0815:
0816:            /**
0817:             * JDBC 2.0
0818:             *
0819:             * Determine the result set concurrency.
0820:             *
0821:             * @exception SQLException Feature not implemented for now.
0822:             */
0823:            public int getResultSetConcurrency() throws SQLException {
0824:                checkStatus();
0825:                return resultSetConcurrency;
0826:            }
0827:
0828:            /**
0829:             * JDBC 3.0
0830:             *
0831:             * Retrieves the result set holdability for ResultSet objects
0832:             * generated by this Statement object.
0833:             *
0834:             * @return either ResultSet.HOLD_CURSORS_OVER_COMMIT or
0835:             * ResultSet.CLOSE_CURSORS_AT_COMMIT
0836:             * @exception SQLException Feature not implemented for now.
0837:             */
0838:            public final int getResultSetHoldability() throws SQLException {
0839:                checkStatus();
0840:                return resultSetHoldability;
0841:            }
0842:
0843:            /**
0844:             * JDBC 2.0
0845:             *
0846:             * Adds a SQL command to the current batch of commmands for the statement.
0847:             * This method is optional.
0848:             *
0849:             * @param sql typically this is a static SQL INSERT or UPDATE statement
0850:             * @exception SQLException if a database-access error occurs, or the
0851:             * driver does not support batch statements
0852:             */
0853:            public void addBatch(String sql) throws SQLException {
0854:                checkStatus();
0855:                synchronized (getConnectionSynchronization()) {
0856:                    if (batchStatements == null)
0857:                        batchStatements = new Vector();
0858:                    batchStatements.addElement(sql);
0859:                }
0860:            }
0861:
0862:            /**
0863:             * JDBC 2.0
0864:             *
0865:             * Make the set of commands in the current batch empty.
0866:             * This method is optional.
0867:             *
0868:             * @exception SQLException if a database-access error occurs, or the
0869:             * driver does not support batch statements
0870:             */
0871:            public final void clearBatch() throws SQLException {
0872:                checkStatus();
0873:                synchronized (getConnectionSynchronization()) {
0874:                    batchStatements = null;
0875:                }
0876:            }
0877:
0878:            /**
0879:             * JDBC 2.0
0880:             * 
0881:             * Submit a batch of commands to the database for execution.
0882:             * This method is optional.
0883:             *
0884:             * Moving jdbc2.0 batch related code in this class because
0885:             * callableStatement in jdbc 20 needs this code too and it doesn't derive
0886:             * from prepared statement in jdbc 20 in our implementation. 
0887:             * BatchUpdateException is the only new class from jdbc 20 which is being
0888:             * referenced here and in order to avoid any jdk11x problems, using
0889:             * reflection code to make an instance of that class. 
0890:             *
0891:             * @return an array of update counts containing one element for each
0892:             * command in the batch.  The array is ordered according
0893:             * to the order in which commands were inserted into the batch
0894:             * @exception SQLException if a database-access error occurs, or the
0895:             * driver does not support batch statements
0896:             */
0897:            public int[] executeBatch() throws SQLException {
0898:                checkExecStatus();
0899:                synchronized (getConnectionSynchronization()) {
0900:                    setupContextStack();
0901:                    int i = 0;
0902:                    // As per the jdbc 2.0 specs, close the statement object's current resultset
0903:                    // if one is open.
0904:                    // Are there results?
0905:                    // outside of the lower try/finally since results will
0906:                    // setup and restore themselves.
0907:                    clearResultSets();
0908:
0909:                    Vector stmts = batchStatements;
0910:                    batchStatements = null;
0911:                    int size;
0912:                    if (stmts == null)
0913:                        size = 0;
0914:                    else
0915:                        size = stmts.size();
0916:
0917:                    int[] returnUpdateCountForBatch = new int[size];
0918:
0919:                    SQLException sqle;
0920:                    try {
0921:                        for (; i < size; i++) {
0922:                            if (executeBatchElement(stmts.elementAt(i)))
0923:                                throw newSQLException(SQLState.RESULTSET_RETURN_NOT_ALLOWED);
0924:                            returnUpdateCountForBatch[i] = getUpdateCount();
0925:                        }
0926:                        return returnUpdateCountForBatch;
0927:                    } catch (StandardException se) {
0928:
0929:                        sqle = handleException(se);
0930:                    } catch (SQLException sqle2) {
0931:                        sqle = sqle2;
0932:                    } finally {
0933:                        restoreContextStack();
0934:                    }
0935:
0936:                    int successfulUpdateCount[] = new int[i];
0937:                    for (int j = 0; j < i; j++) {
0938:                        successfulUpdateCount[j] = returnUpdateCountForBatch[j];
0939:                    }
0940:
0941:                    SQLException batch = new java.sql.BatchUpdateException(sqle
0942:                            .getMessage(), sqle.getSQLState(), sqle
0943:                            .getErrorCode(), successfulUpdateCount);
0944:
0945:                    batch.setNextException(sqle);
0946:                    throw batch;
0947:                }
0948:            }
0949:
0950:            /**
0951:            	Execute a single element of the batch. Overridden by EmbedPreparedStatement
0952:             */
0953:            boolean executeBatchElement(Object batchElement)
0954:                    throws SQLException, StandardException {
0955:                return execute((String) batchElement, false, true,
0956:                        JDBC30Translation.NO_GENERATED_KEYS, null, null);
0957:            }
0958:
0959:            /**
0960:             * JDBC 2.0
0961:             *
0962:             * Return the Connection that produced the Statement.
0963:             *
0964:             * @exception SQLException Exception if it cannot find the connection
0965:             * associated to this statement.
0966:             */
0967:            public final java.sql.Connection getConnection()
0968:                    throws SQLException {
0969:                checkStatus();
0970:
0971:                java.sql.Connection appConn = getEmbedConnection()
0972:                        .getApplicationConnection();
0973:                if ((appConn != applicationConnection) || (appConn == null)) {
0974:
0975:                    throw Util.noCurrentConnection();
0976:                }
0977:                return appConn;
0978:            }
0979:
0980:            /**
0981:             * JDBC 3.0
0982:             *
0983:             * Moves to this Statement obect's next result, deals with any current ResultSet
0984:             * object(s) according to the instructions specified by the given flag, and
0985:             * returns true if the next result is a ResultSet object
0986:             *
0987:             * @param current - one of the following Statement constants indicating what
0988:             * should happen to current ResultSet objects obtained using the method
0989:             * getResultSetCLOSE_CURRENT_RESULT, KEEP_CURRENT_RESULT, or CLOSE_ALL_RESULTS
0990:             * @return true if the next result is a ResultSet; false if it is
0991:             * an update count or there are no more results
0992:             * @see #execute
0993:             * @exception SQLException thrown on failure.
0994:             */
0995:            public final boolean getMoreResults(int current)
0996:                    throws SQLException {
0997:                checkExecStatus();
0998:
0999:                synchronized (getConnectionSynchronization()) {
1000:                    if (dynamicResults == null) {
1001:                        // we only have the one resultset, so this is
1002:                        // simply a close for us.
1003:                        clearResultSets();
1004:                        return false;
1005:                    }
1006:
1007:                    int startingClose;
1008:                    switch (current) {
1009:                    default:
1010:                    case JDBC30Translation.CLOSE_ALL_RESULTS:
1011:                        startingClose = 0;
1012:                        break;
1013:                    case JDBC30Translation.CLOSE_CURRENT_RESULT:
1014:                        // just close the current result set.
1015:                        startingClose = currentDynamicResultSet;
1016:                        break;
1017:                    case JDBC30Translation.KEEP_CURRENT_RESULT:
1018:                        // make the close loop a no-op.
1019:                        startingClose = dynamicResults.length;
1020:                        break;
1021:                    }
1022:
1023:                    // Close loop.
1024:                    SQLException se = null;
1025:                    for (int i = startingClose; i <= currentDynamicResultSet
1026:                            && i < dynamicResults.length; i++) {
1027:                        EmbedResultSet lrs = dynamicResults[i];
1028:                        if (lrs == null)
1029:                            continue;
1030:
1031:                        try {
1032:                            lrs.close();
1033:                        } catch (SQLException sqle) {
1034:                            if (se == null)
1035:                                se = sqle;
1036:                            else
1037:                                se.setNextException(sqle);
1038:                        } finally {
1039:                            dynamicResults[i] = null;
1040:                        }
1041:                    }
1042:
1043:                    if (se != null) {
1044:                        // leave positioned on the current result set (?)
1045:                        throw se;
1046:                    }
1047:
1048:                    updateCount = -1;
1049:
1050:                    while (++currentDynamicResultSet < dynamicResults.length) {
1051:
1052:                        EmbedResultSet lrs = dynamicResults[currentDynamicResultSet];
1053:                        if (lrs != null) {
1054:                            if (lrs.isClosed) {
1055:                                dynamicResults[currentDynamicResultSet] = null;
1056:                                continue;
1057:                            }
1058:
1059:                            results = lrs;
1060:
1061:                            return true;
1062:                        }
1063:                    }
1064:
1065:                    results = null;
1066:                    return false;
1067:                }
1068:            }
1069:
1070:            /**
1071:             * JDBC 3.0
1072:             *
1073:             * Retrieves any auto-generated keys created as a result of executing this
1074:             * Statement object. If this Statement is a non-insert statement,
1075:             * a null ResultSet object is returned.
1076:             *
1077:             * @return a ResultSet object containing the auto-generated key(s) generated by
1078:             * the execution of this Statement object
1079:             * @exception SQLException if a database access error occurs
1080:             */
1081:            public final java.sql.ResultSet getGeneratedKeys()
1082:                    throws SQLException {
1083:                checkStatus();
1084:                if (autoGeneratedKeysResultSet == null)
1085:                    return null;
1086:                else {
1087:                    execute("VALUES IDENTITY_VAL_LOCAL()", true, false,
1088:                            JDBC30Translation.NO_GENERATED_KEYS, null, null);
1089:                    return results;
1090:                }
1091:            }
1092:
1093:            /////////////////////////////////////////////////////////////////////////
1094:            //
1095:            //	Implementation specific methods	
1096:            //
1097:            /////////////////////////////////////////////////////////////////////////
1098:
1099:            /**
1100:            	Execute the current statement.
1101:                @exception SQLException thrown on failure.
1102:             */
1103:            boolean executeStatement(Activation a, boolean executeQuery,
1104:                    boolean executeUpdate) throws SQLException {
1105:
1106:                // we don't differentiate the update from the resultset case.
1107:                // so, there could be a result set.
1108:
1109:                // note: the statement interface will paste together
1110:                // an activation and make sure the prepared statement
1111:                // is still valid, so it is preferrable, for now,
1112:                // to creating our own activation and stuffing it in
1113:                // the prepared statement.
1114:
1115:                synchronized (getConnectionSynchronization()) {
1116:                    setupContextStack(); // make sure there's context
1117:                    boolean retval;
1118:
1119:                    pvs = a.getParameterValueSet();
1120:
1121:                    try {
1122:                        // The following is from the javadoc for java.sql.Statement
1123:                        // Only one ResultSet per Statement can be open at any point in time.
1124:                        // Therefore, if the reading of one ResultSet is interleaved with the
1125:                        // reading of another, each must have been generated by different Statements.
1126:                        // All statement execute methods implicitly close a
1127:                        // statment's current ResultSet if an open one exists. 
1128:                        if (results != null) {
1129:                            results.close();
1130:                            results = null;
1131:                        }
1132:
1133:                        clearWarnings();
1134:
1135:                        if (!forMetaData) {
1136:                            commitIfNeeded(); // commit the last statement if needed
1137:                            needCommit();
1138:                        } else {
1139:
1140:                            if (lcc.getActivationCount() > 1) {
1141:                                // we do not want to commit here as there seems to be other
1142:                                // statements/resultSets currently opened for this connection.
1143:                            } else {
1144:                                commitIfNeeded(); // we can legitimately commit
1145:                                needCommit();
1146:                            }
1147:                        }
1148:
1149:                        // if this was a prepared statement, this just
1150:                        // gets it for us, it won't recompile unless it is invalid.
1151:                        PreparedStatement ps = a.getPreparedStatement();
1152:                        ps.rePrepare(lcc);
1153:                        addWarning(ps.getCompileTimeWarnings());
1154:
1155:                        /*
1156:                         ** WARNING WARNING
1157:                         **
1158:                         ** Any state set in the activation before execution *must* be copied
1159:                         ** to the new activation in GenericActivationHolder.execute() when
1160:                         ** the statement has been recompiled. State such as
1161:                         ** singleExecution, cursorName, holdability, maxRows.
1162:                         */
1163:
1164:                        if (cursorName != null) {
1165:                            a.setCursorName(cursorName);
1166:                        }
1167:
1168:                        boolean executeHoldable = getExecuteHoldable();
1169:
1170:                        a.setResultSetHoldability(executeHoldable);
1171:
1172:                        //reset the activation to clear warnings
1173:                        //and clear existing result sets in case this has been cached
1174:                        a.reset();
1175:                        a.setMaxRows(maxRows);
1176:                        long timeoutMillis = (long) timeoutSeconds * 1000L;
1177:                        ResultSet resultsToWrap = ps.execute(a, false,
1178:                                timeoutMillis);
1179:                        addWarning(a.getWarnings());
1180:
1181:                        if (resultsToWrap.returnsRows()) {
1182:
1183:                            // The statement returns rows, so calling it with
1184:                            // executeUpdate() is not allowed.
1185:                            if (executeUpdate) {
1186:                                throw StandardException
1187:                                        .newException(SQLState.LANG_INVALID_CALL_TO_EXECUTE_UPDATE);
1188:                            }
1189:
1190:                            EmbedResultSet lresults = factory
1191:                                    .newEmbedResultSet(getEmbedConnection(),
1192:                                            resultsToWrap, forMetaData, this ,
1193:                                            ps.isAtomic());
1194:                            results = lresults;
1195:
1196:                            // Set up the finalization of the ResultSet to
1197:                            // mark the activation as unused. It will be
1198:                            // closed sometime later by the connection
1199:                            // outside of finalization.
1200:                            if (a.isSingleExecution())
1201:                                lresults.singleUseActivation = a;
1202:
1203:                            updateCount = -1;
1204:                            retval = true;
1205:                        } else {
1206:
1207:                            // Only applipable for an insert statement, which does not return rows.
1208:                            //the auto-generated keys resultset will be null if used for non-insert statement
1209:                            if (a.getAutoGeneratedKeysResultsetMode()
1210:                                    && (resultsToWrap
1211:                                            .getAutoGeneratedKeysResultset() != null)) {
1212:                                resultsToWrap.getAutoGeneratedKeysResultset()
1213:                                        .open();
1214:                                autoGeneratedKeysResultSet = factory
1215:                                        .newEmbedResultSet(
1216:                                                getEmbedConnection(),
1217:                                                resultsToWrap
1218:                                                        .getAutoGeneratedKeysResultset(),
1219:                                                false, this , ps.isAtomic());
1220:                            }
1221:
1222:                            updateCount = resultsToWrap.modifiedRowCount();
1223:
1224:                            resultsToWrap.finish(); // Don't need the result set any more
1225:                            results = null; // note that we have none.
1226:
1227:                            int dynamicResultCount = 0;
1228:                            if (a.getDynamicResults() != null) {
1229:                                dynamicResultCount = processDynamicResults(a
1230:                                        .getDynamicResults(), a
1231:                                        .getMaxDynamicResults());
1232:                            }
1233:
1234:                            // executeQuery() is not allowed if the statement
1235:                            // doesn't return exactly one ResultSet.
1236:                            if (executeQuery && dynamicResultCount != 1) {
1237:                                throw StandardException
1238:                                        .newException(SQLState.LANG_INVALID_CALL_TO_EXECUTE_QUERY);
1239:                            }
1240:
1241:                            // executeUpdate() is not allowed if the statement
1242:                            // returns ResultSets.
1243:                            if (executeUpdate && dynamicResultCount > 0) {
1244:                                throw StandardException
1245:                                        .newException(SQLState.LANG_INVALID_CALL_TO_EXECUTE_UPDATE);
1246:                            }
1247:
1248:                            if (dynamicResultCount == 0) {
1249:                                if (a.isSingleExecution()) {
1250:                                    a.close();
1251:                                }
1252:
1253:                                if (!forMetaData)
1254:                                    commitIfNeeded();
1255:                                else {
1256:
1257:                                    if (lcc.getActivationCount() > 1) {
1258:                                        // we do not want to commit here as there seems to be other
1259:                                        // statements/resultSets currently opened for this connection.
1260:                                    } else {
1261:                                        commitIfNeeded(); // we can legitimately commit
1262:                                    }
1263:                                }
1264:                            }
1265:
1266:                            retval = (dynamicResultCount > 0);
1267:                        }
1268:                    } catch (Throwable t) {
1269:                        if (a.isSingleExecution()) {
1270:                            try {
1271:                                a.close();
1272:                            } catch (Throwable tt) {
1273:                                ;
1274:                            }
1275:                        }
1276:                        throw handleException(t);
1277:                    } finally {
1278:                        restoreContextStack();
1279:                    }
1280:                    return retval;
1281:                }
1282:            }
1283:
1284:            /**
1285:             * Add a SQLWarning to this Statement object.
1286:             * If the Statement already has a SQLWarning then it
1287:             * is added to the end of the chain.
1288:             * 
1289:             * @see #getWarnings()
1290:             */
1291:            final void addWarning(SQLWarning sw) {
1292:                if (sw != null) {
1293:                    if (warnings == null)
1294:                        warnings = sw;
1295:                    else
1296:                        warnings.setNextException(sw);
1297:                }
1298:            }
1299:
1300:            /* package */
1301:            public String getSQLText() {
1302:                // no need to synchronize - accessing a reference is atomic
1303:                // synchronized (getConnectionSynchronization()) 
1304:                return SQLText;
1305:            }
1306:
1307:            public ParameterValueSet getParameterValueSet() {
1308:                return pvs;
1309:            }
1310:
1311:            /**
1312:             * Throw an exception if this Statement has been closed explictly
1313:             * or it has noticed it has been closed implicitly.
1314:             * JDBC specifications require nearly all methods throw a SQLException
1315:             * if the Statement has been closed, thus most methods call this
1316:             * method or checkExecStatus first.
1317:             * 
1318:             * @exception SQLException Thrown if the statement is marked as closed.
1319:             * 
1320:             * @see #checkExecStatus()
1321:             */
1322:            final void checkStatus() throws SQLException {
1323:                if (!active) {
1324:                    // 
1325:                    // Check the status of the connection first
1326:                    //
1327:                    java.sql.Connection appConn = getEmbedConnection()
1328:                            .getApplicationConnection();
1329:                    if (appConn == null || appConn.isClosed()) {
1330:                        throw Util.noCurrentConnection();
1331:                    }
1332:
1333:                    throw newSQLException(SQLState.ALREADY_CLOSED, "Statement");
1334:                }
1335:            }
1336:
1337:            /**
1338:            	A heavier weight version of checkStatus() that ensures the application's Connection
1339:            	object is still open. This is to stop errors or unexpected behaviour when a [Prepared]Statement
1340:            	object is used after the application has been closed. In particular to ensure that
1341:            	a Statement obtained from a PooledConnection cannot be used after the application has closed
1342:            	its connection (as the underlying Connection is still active).
1343:            	To avoid this heavier weight check on every method of [Prepared]Statement it is only used
1344:            	on those methods that would end up using the database's connection to read or modify data.
1345:            	E.g. execute*(), but not setXXX, etc.
1346:                <BR>
1347:                If this Statement's Connection is closed an exception will
1348:                be thrown and the active field will be set to false,
1349:                completely marking the Statement as closed.
1350:                <BR>
1351:                If the Statement is not currently connected to an active
1352:                transaction, i.e. a suspended global transaction, then
1353:                this method will throw a SQLException but the Statement
1354:                will remain open. The Statement is open but unable to
1355:                process any new requests until its global transaction
1356:                is resumed.
1357:                <BR>
1358:                Upon return from the method, with or without a SQLException
1359:                the field active will correctly represent the open state of
1360:                the Statement.
1361:                
1362:                @exception SQLException Thrown if the statement is marked as closed
1363:                or the Statement's transaction is suspended.
1364:                
1365:                @see #checkStatus()
1366:             */
1367:            final void checkExecStatus() throws SQLException {
1368:                // getConnection() checks if the Statement is closed
1369:                if (!getConnection().isClosed())
1370:                    return;
1371:
1372:                // Now this connection is closed for all
1373:                // future use.
1374:                active = false;
1375:
1376:                throw Util.noCurrentConnection();
1377:            }
1378:
1379:            /**
1380:            	Close and clear all result sets associated with this statement
1381:            	from the last execution.
1382:             */
1383:            void clearResultSets() throws SQLException {
1384:
1385:                SQLException sqle = null;
1386:
1387:                try {
1388:                    // Are there results?
1389:                    // outside of the lower try/finally since results will
1390:                    // setup and restore themselves.
1391:                    if (results != null) {
1392:                        results.close();
1393:                        results = null;
1394:                    }
1395:                } catch (SQLException s1) {
1396:                    sqle = s1;
1397:                }
1398:
1399:                try {
1400:                    if (autoGeneratedKeysResultSet != null) {
1401:                        autoGeneratedKeysResultSet.close();
1402:                        autoGeneratedKeysResultSet = null;
1403:                    }
1404:                } catch (SQLException sauto) {
1405:                    if (sqle == null)
1406:                        sqle = sauto;
1407:                    else
1408:                        sqle.setNextException(sauto);
1409:                }
1410:
1411:                // close all the dynamic result sets.
1412:                if (dynamicResults != null) {
1413:                    for (int i = 0; i < dynamicResults.length; i++) {
1414:                        EmbedResultSet lrs = dynamicResults[i];
1415:                        if (lrs == null)
1416:                            continue;
1417:
1418:                        try {
1419:                            lrs.close();
1420:                        } catch (SQLException sdynamic) {
1421:                            if (sqle == null)
1422:                                sqle = sdynamic;
1423:                            else
1424:                                sqle.setNextException(sdynamic);
1425:                        }
1426:                    }
1427:                    dynamicResults = null;
1428:                }
1429:
1430:                /*
1431:                	  We don't reset statement to null because PreparedStatement
1432:                	  relies on it being there for subsequent (post-close) execution
1433:                	  requests.  There is no close method on database statement objects.
1434:                 */
1435:
1436:                updateCount = -1; // reset field
1437:
1438:                if (sqle != null)
1439:                    throw sqle;
1440:            }
1441:
1442:            /**
1443:            	Check to see if a statement requires to be executed via a callable statement.
1444:             */
1445:            void checkRequiresCallableStatement(Activation activation)
1446:                    throws SQLException {
1447:
1448:                ParameterValueSet pvs = activation.getParameterValueSet();
1449:
1450:                if (pvs == null)
1451:                    return;
1452:
1453:                if (pvs.checkNoDeclaredOutputParameters()) {
1454:                    try {
1455:                        activation.close();
1456:                    } catch (StandardException se) {
1457:                    }
1458:                    throw newSQLException(SQLState.REQUIRES_CALLABLE_STATEMENT,
1459:                            SQLText);
1460:                }
1461:            }
1462:
1463:            /**
1464:            	Transfer my batch of Statements to a newly created Statement.
1465:             */
1466:            public void transferBatch(EmbedStatement other) throws SQLException {
1467:
1468:                synchronized (getConnectionSynchronization()) {
1469:                    other.batchStatements = batchStatements;
1470:                    batchStatements = null;
1471:                }
1472:            }
1473:
1474:            /**
1475:             * Set the application statement for this Statement.
1476:             */
1477:            public final void setApplicationStatement(EngineStatement s) {
1478:                this .applicationStatement = s;
1479:            }
1480:
1481:            private EmbedResultSet[] dynamicResults;
1482:            private int currentDynamicResultSet;
1483:
1484:            /**
1485:             * Go through a holder of dynamic result sets, remove those that
1486:             * should not be returned, and sort the result sets according to
1487:             * their creation.
1488:             *
1489:             * @param holder a holder of dynamic result sets
1490:             * @param maxDynamicResultSets the maximum number of result sets
1491:             * to be returned
1492:             * @return the actual number of result sets
1493:             * @exception SQLException if an error occurs
1494:             */
1495:            private int processDynamicResults(java.sql.ResultSet[][] holder,
1496:                    int maxDynamicResultSets) throws SQLException {
1497:
1498:                EmbedResultSet[] sorted = new EmbedResultSet[holder.length];
1499:
1500:                int actualCount = 0;
1501:                for (int i = 0; i < holder.length; i++) {
1502:
1503:                    java.sql.ResultSet[] param = holder[i];
1504:
1505:                    if (param[0] == null)
1506:                        continue;
1507:
1508:                    java.sql.ResultSet rs = param[0];
1509:                    param[0] = null;
1510:
1511:                    // ignore non-cloudscape result sets or results sets from another connection
1512:                    if (!(rs instanceof  EmbedResultSet))
1513:                        continue;
1514:
1515:                    EmbedResultSet lrs = (EmbedResultSet) rs;
1516:
1517:                    if (lrs.getEmbedConnection().rootConnection != getEmbedConnection().rootConnection)
1518:                        continue;
1519:
1520:                    // ignore closed result sets.
1521:                    if (lrs.isClosed)
1522:                        continue;
1523:
1524:                    lrs.setDynamicResultSet(this );
1525:                    sorted[actualCount++] = lrs;
1526:                }
1527:
1528:                if (actualCount != 0) {
1529:
1530:                    // results are defined to be ordered according to their creation
1531:                    if (actualCount != 1) {
1532:                        java.util.Arrays.sort(sorted, 0, actualCount);
1533:                    }
1534:
1535:                    dynamicResults = sorted;
1536:
1537:                    if (actualCount > maxDynamicResultSets) {
1538:                        addWarning(StandardException
1539:                                .newWarning(SQLState.LANG_TOO_MANY_DYNAMIC_RESULTS_RETURNED));
1540:
1541:                        for (int i = maxDynamicResultSets; i < actualCount; i++) {
1542:                            sorted[i].close();
1543:                            sorted[i] = null;
1544:                        }
1545:
1546:                        actualCount = maxDynamicResultSets;
1547:                    }
1548:
1549:                    updateCount = -1;
1550:                    results = sorted[0];
1551:                    currentDynamicResultSet = 0;
1552:
1553:                    // 0100C is not returned for procedures written in Java, from the SQL2003 spec.
1554:                    // getWarnings(StandardException.newWarning(SQLState.LANG_DYNAMIC_RESULTS_RETURNED));
1555:                }
1556:
1557:                return actualCount;
1558:            }
1559:
1560:            /**
1561:            	Callback on the statement when one of its result sets is closed.
1562:            	This allows the statement to control when it completes and hence
1563:            	when it commits in auto commit mode.
1564:
1565:                Must have connection synchronization and setupContextStack(), this
1566:                is required for the call to commitIfNeeded().
1567:             */
1568:            void resultSetClosing(EmbedResultSet closingLRS)
1569:                    throws SQLException {
1570:
1571:                // If the Connection is not in auto commit then this statement completion
1572:                // cannot cause a commit.
1573:                if (!getEmbedConnection().autoCommit)
1574:                    return;
1575:
1576:                // If we have dynamic results, see if there is another result set open.
1577:                // If so, then no commit. The last result set to close will close the statement.
1578:                if (dynamicResults != null) {
1579:                    for (int i = 0; i < dynamicResults.length; i++) {
1580:                        EmbedResultSet lrs = dynamicResults[i];
1581:                        if (lrs == null)
1582:                            continue;
1583:                        if (lrs.isClosed)
1584:                            continue;
1585:                        if (lrs == closingLRS)
1586:                            continue;
1587:
1588:                        // at least one still open so no commit now.
1589:                        return;
1590:                    }
1591:                }
1592:
1593:                // new Throwable("COMMIT ON " + SQLText).printStackTrace(System.out);
1594:
1595:                // beetle 5383.  Force a commit in autocommit always.  Before this
1596:                // change if client in autocommit opened a result set, did a commit,
1597:                // then next then close a commit would not be forced on the close.
1598:                commitIfAutoCommit();
1599:            }
1600:
1601:            /**
1602:             * Get the execute time holdability for the Statement.
1603:             * When in a global transaction holdabilty defaults to false.
1604:             * @throws SQLException Error from getResultSetHoldability.
1605:             */
1606:            private boolean getExecuteHoldable() throws SQLException {
1607:                if (resultSetHoldability == JDBC30Translation.CLOSE_CURSORS_AT_COMMIT)
1608:                    return false;
1609:
1610:                // Simple non-XA case
1611:                if (applicationStatement == this )
1612:                    return true;
1613:
1614:                return applicationStatement.getResultSetHoldability() == JDBC30Translation.HOLD_CURSORS_OVER_COMMIT;
1615:            }
1616:
1617:            /**
1618:             * Returns the value of the EmbedStatement's poolable hint,
1619:             * indicating whether pooling is requested.
1620:             *
1621:             * @return The value of the poolable hint.
1622:             * @throws SQLException if the Statement has been closed.
1623:             */
1624:
1625:            public boolean isPoolable() throws SQLException {
1626:                // Assert the statement is still active (not closed)
1627:                checkStatus();
1628:
1629:                return isPoolable;
1630:            }
1631:
1632:            /**
1633:             * Requests that an EmbedStatement be pooled or not.
1634:             *
1635:             * @param poolable requests that the EmbedStatement be pooled if true
1636:             * and not be pooled if false.
1637:             * @throws SQLException if the EmbedStatement has been closed.
1638:             */
1639:
1640:            public void setPoolable(boolean poolable) throws SQLException {
1641:                // Assert the statement is still active (not closed)
1642:                checkStatus();
1643:
1644:                isPoolable = poolable;
1645:            }
1646:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.