Source Code Cross Referenced for DbStatement.java in  » Web-Framework » rife-1.6.1 » com » uwyn » rife » database » 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 » Web Framework » rife 1.6.1 » com.uwyn.rife.database 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * Copyright 2001-2007 Geert Bevin <gbevin[remove] at uwyn dot com>
0003:         * Distributed under the terms of either:
0004:         * - the common development and distribution license (CDDL), v1.0; or
0005:         * - the GNU Lesser General Public License, v2.1 or later
0006:         * $Id: DbStatement.java 3648 2007-01-29 12:16:16Z gbevin $
0007:         */
0008:        package com.uwyn.rife.database;
0009:
0010:        import com.uwyn.rife.config.RifeConfig;
0011:        import com.uwyn.rife.database.DbResultSet;
0012:        import com.uwyn.rife.database.exceptions.BatchExecutionErrorException;
0013:        import com.uwyn.rife.database.exceptions.DatabaseException;
0014:        import com.uwyn.rife.database.exceptions.ExecutionErrorException;
0015:        import com.uwyn.rife.database.exceptions.MissingResultsException;
0016:        import com.uwyn.rife.database.exceptions.StatementCloseErrorException;
0017:        import com.uwyn.rife.database.queries.Query;
0018:        import com.uwyn.rife.database.queries.ReadQuery;
0019:        import com.uwyn.rife.tools.ExceptionUtils;
0020:        import com.uwyn.rife.tools.JavaSpecificationUtils;
0021:        import java.lang.reflect.Constructor;
0022:        import java.sql.ResultSet;
0023:        import java.sql.SQLException;
0024:        import java.sql.SQLWarning;
0025:        import java.sql.Statement;
0026:        import java.util.logging.Level;
0027:        import java.util.logging.Logger;
0028:
0029:        /**
0030:         * Provides a wrapper around the regular JDBC <code>Statement</code> class. It
0031:         * can only be instantiated by calling the <code>createStatement</code> method on
0032:         * an existing <code>DbConnection</code> instance.
0033:         * <p>This class hooks into the database connection pool and cleans up as much
0034:         * as possible in case of errors. The thrown <code>DatabaseException</code>
0035:         * exceptions should thus only be used for error reporting and not for
0036:         * releasing resources used by the framework.
0037:         * <p>The <code>execute</code> and <code>executeQuery</code> methods store
0038:         * their result set in the executing <code>DbStatement</code> instance. It's
0039:         * recommended to use the <code>DbQueryManager</code>'s <code>fetch</code>
0040:         * method to process the result set. If needed, one can also use the
0041:         * <code>getResultSet</code> method to manually process the results through
0042:         * plain JDBC. However, when exceptions are thrown during this procedure, it's
0043:         * also the responsability of the user to correctly clean up all resources.
0044:         * <p>Additional methods have been implemented to facilitate the retrieval of
0045:         * queries which return only a single field and to easily check if a query
0046:         * returned any result rows.
0047:         *
0048:         * @author Geert Bevin (gbevin[remove] at uwyn dot com)
0049:         * @version $Revision: 3648 $
0050:         * @see #executeQuery(String)
0051:         * @see #execute(String)
0052:         * @see #execute(String, int)
0053:         * @see #execute(String, int[])
0054:         * @see #execute(String, String[])
0055:         * @see #getResultSet()
0056:         * @see com.uwyn.rife.database.DbConnection#createStatement
0057:         * @see com.uwyn.rife.database.DbQueryManager#fetch(ResultSet, DbRowProcessor)
0058:         * @see java.sql.ResultSet
0059:         * @see java.sql.Statement
0060:         * @since 1.0
0061:         */
0062:        public class DbStatement implements  Cloneable {
0063:            private DbResultSet mResultSet = null;
0064:
0065:            final Statement mStatement;
0066:            final DbConnection mConnection;
0067:
0068:            /**
0069:             * Constructs a new <code>DbStatement</code> from an existing
0070:             * <code>DbConnection</code> and <code>Statement</code>. This constructor
0071:             * will never be called by a user of the api. The
0072:             * <code>createStatement</code> of an existing <code>DbConnection</code>
0073:             * instance should be used instead.
0074:             *
0075:             * @param connection a <code>DbConnection</code> instance
0076:             * @param statement a JDBC <code>Statement</code> instance
0077:             * @exception DatabaseException if a database access error occurs
0078:             * @since 1.0
0079:             */
0080:            DbStatement(DbConnection connection, Statement statement)
0081:                    throws DatabaseException {
0082:                assert connection != null;
0083:                assert statement != null;
0084:
0085:                mConnection = connection;
0086:                mStatement = statement;
0087:            }
0088:
0089:            /**
0090:             * Adds the given SQL command to the current list of commmands for this
0091:             * <code>Statement</code> object. The commands in this list can be
0092:             * executed as a batch by calling the method <code>executeBatch</code>.
0093:             * <p>If an exception is thrown, this <code>DbStatement</code> is
0094:             * automatically closed and an ongoing transaction will be automatically
0095:             * rolled back if it belongs to the executing thread.
0096:             *
0097:             * @param sql typically this is a static SQL <code>INSERT</code> or
0098:             * <code>UPDATE</code> statement
0099:             * @exception DatabaseException if a database access error occurs, or the
0100:             * driver does not support batch updates
0101:             * @see #executeBatch
0102:             * @since 1.0
0103:             */
0104:            public void addBatch(String sql) throws DatabaseException {
0105:                try {
0106:                    mStatement.addBatch(sql);
0107:                    traceBatch(sql);
0108:                } catch (SQLException e) {
0109:                    handleException();
0110:                    throw new DatabaseException(e);
0111:                }
0112:            }
0113:
0114:            /**
0115:             * Cancels this <code>DbStatement</code> object if both the DBMS and
0116:             * driver support aborting a SQL statement. This method can be used by one
0117:             * thread to cancel a statement that is being executed by another thread.
0118:             * <p>If an exception is thrown, this <code>DbStatement</code> is
0119:             * automatically closed and an ongoing transaction will be automatically
0120:             * rolled back if it belongs to the executing thread.
0121:             *
0122:             * @exception DatabaseException if a database access error occurs
0123:             * @since 1.0
0124:             */
0125:            public void cancel() throws DatabaseException {
0126:                try {
0127:                    mStatement.cancel();
0128:                } catch (SQLException e) {
0129:                    handleException();
0130:                    throw new DatabaseException(e);
0131:                }
0132:            }
0133:
0134:            /**
0135:             * Empties this <code>Statement</code> object's current list of SQL
0136:             * commands.
0137:             * <p>If an exception is thrown, this <code>DbStatement</code> is
0138:             * automatically closed and an ongoing transaction will be automatically
0139:             * rolled back if it belongs to the executing thread.
0140:             *
0141:             * @exception DatabaseException if a database access error occurs or the
0142:             * driver does not support batch updates
0143:             * @see #addBatch
0144:             * @since 1.0
0145:             */
0146:            public void clearBatch() throws DatabaseException {
0147:                try {
0148:                    mStatement.clearBatch();
0149:                } catch (SQLException e) {
0150:                    handleException();
0151:                    throw new DatabaseException(e);
0152:                }
0153:            }
0154:
0155:            /**
0156:             * Clears all the warnings reported on this <code>DbStatement</code>
0157:             * object. After a call to this method, the method
0158:             * <code>getWarnings</code> will return <code>null</code> until a new
0159:             * warning is reported for this <code>DbStatement</code> object.
0160:             * <p>If an exception is thrown, this <code>DbStatement</code> is
0161:             * automatically closed and an ongoing transaction will be automatically
0162:             * rolled back if it belongs to the executing thread.
0163:             *
0164:             * @exception DatabaseException if a database access error occurs
0165:             * @since 1.0
0166:             */
0167:            public void clearWarnings() throws DatabaseException {
0168:                try {
0169:                    mStatement.clearWarnings();
0170:                } catch (SQLException e) {
0171:                    handleException();
0172:                    throw new DatabaseException(e);
0173:                }
0174:            }
0175:
0176:            /**
0177:             * Releases this <code>DbStatement</code> object's database and JDBC
0178:             * resources immediately instead of waiting for this to happen when it is
0179:             * automatically closed. It is generally good practice to release
0180:             * resources as soon as you are finished with them to avoid tying up
0181:             * database resources.
0182:             * <p>Calling the method <code>close</code> on a <code>DbStatement</code>
0183:             * object that is already closed has no effect.
0184:             * <p><b>Note:</b> A <code>DbStatement</code> object is automatically
0185:             * closed when it is garbage collected. When a <code>DbStatement</code>
0186:             * object is closed, its current <code>ResultSet</code> object, if one
0187:             * exists, is also closed.
0188:             *
0189:             * @exception DatabaseException if a database access error occurs
0190:             * @since 1.0
0191:             */
0192:            public void close() throws DatabaseException {
0193:                try {
0194:                    mConnection.releaseStatement(this );
0195:
0196:                    // cleanup this statement
0197:                    cleanResultSet();
0198:
0199:                    mStatement.close();
0200:                } catch (SQLException e) {
0201:                    throw new StatementCloseErrorException(mConnection
0202:                            .getDatasource(), e);
0203:                }
0204:            }
0205:
0206:            protected long startTrace() {
0207:                if (RifeConfig.Database.getSqlDebugTrace()) {
0208:                    Logger logger = Logger.getLogger("com.uwyn.rife.database");
0209:                    if (logger.isLoggable(Level.INFO)) {
0210:                        return System.currentTimeMillis();
0211:                    }
0212:                }
0213:
0214:                return 0;
0215:            }
0216:
0217:            protected void outputTrace(long start, String sql) {
0218:                if (start != 0) {
0219:                    StringBuilder output = new StringBuilder();
0220:
0221:                    output.append(System.currentTimeMillis() - start);
0222:                    output.append("ms : ");
0223:                    output.append(sql);
0224:
0225:                    Logger.getLogger("com.uwyn.rife.database").info(
0226:                            output.toString());
0227:                }
0228:            }
0229:
0230:            protected void traceBatch(String sql) {
0231:                if (RifeConfig.Database.getSqlDebugTrace()) {
0232:                    Logger logger = Logger.getLogger("com.uwyn.rife.database");
0233:                    if (logger.isLoggable(Level.INFO)) {
0234:                        logger.info("batched : " + sql);
0235:                    }
0236:                }
0237:            }
0238:
0239:            /**
0240:             * Executes the given SQL statement, which may return multiple results. In
0241:             * some (uncommon) situations, a single SQL statement may return multiple
0242:             * result sets and/or update counts. Normally you can ignore this unless
0243:             * you are (1) executing a stored procedure that you know may return
0244:             * multiple results or (2) you are dynamically executing an unknown SQL
0245:             * string.
0246:             * <p>The <code>execute</code> method executes a SQL statement and
0247:             * indicates the form of the first result. You must then use the methods
0248:             * <code>getResultSet</code> or <code>getUpdateCount</code> to retrieve
0249:             * the result, and <code>getMoreResults</code> to move to any subsequent
0250:             * result(s).
0251:             * <p>If an exception is thrown, this <code>DbStatement</code> is
0252:             * automatically closed and an ongoing transaction will be automatically
0253:             * rolled back if it belongs to the executing thread.
0254:             *
0255:             * @param sql any SQL statement
0256:             * @return <code>true</code> if the first result is a
0257:             * <code>ResultSet</code> object; or
0258:             * <p><code>false</code> if it is an update count or there are no results
0259:             * @exception DatabaseException if a database access error occurs
0260:             * @see #getResultSet
0261:             * @see #getUpdateCount
0262:             * @see #getMoreResults
0263:             * @since 1.0
0264:             */
0265:            public boolean execute(String sql) throws DatabaseException {
0266:                try {
0267:                    waitForConnection();
0268:
0269:                    cleanResultSet();
0270:
0271:                    long start = startTrace();
0272:                    boolean result = mStatement.execute(sql);
0273:                    outputTrace(start, sql);
0274:
0275:                    setResultset(mStatement.getResultSet());
0276:
0277:                    return result;
0278:                } catch (SQLException e) {
0279:                    handleException();
0280:                    throw new ExecutionErrorException(sql, mConnection
0281:                            .getDatasource(), e);
0282:                }
0283:            }
0284:
0285:            /**
0286:             * Executes the given SQL statement, which may return multiple results,
0287:             * and signals the driver that any auto-generated keys should be made
0288:             * available for retrieval. The driver will ignore this signal if the SQL
0289:             * statement is not an <code>INSERT</code> statement.
0290:             * <p>In some (uncommon) situations, a single SQL statement may return
0291:             * multiple result sets and/or update counts. Normally you can ignore this
0292:             * unless you are (1) executing a stored procedure that you know may
0293:             * return multiple results or (2) you are dynamically executing an unknown
0294:             * SQL string.
0295:             * <p>The <code>execute</code> method executes a SQL statement and
0296:             * indicates the form of the first result. You must then use the methods
0297:             * <code>getResultSet</code> or <code>getUpdateCount</code> to retrieve
0298:             * the result, and <code>getMoreResults</code> to move to any subsequent
0299:             * result(s).
0300:             * <p>If an exception is thrown, this <code>DbStatement</code> is
0301:             * automatically closed and an ongoing transaction will be automatically
0302:             * rolled back if it belongs to the executing thread.
0303:             *
0304:             * @param sql any SQL statement
0305:             * @param autoGeneratedKeys a constant indicating whether auto-generated
0306:             * keys should be made available for retrieval using the method
0307:             * <code>getGeneratedKeys</code>; one of the following constants:
0308:             * <code>Statement.RETURN_GENERATED_KEYS</code> or
0309:             * <code>Statement.NO_GENERATED_KEYS</code>
0310:             * @return <code>true</code> if the first result is a
0311:             * <code>ResultSet</code> object; or
0312:             * <p><code>false</code> if it is an update count or there are no results
0313:             * @exception DatabaseException if a database access error occurs
0314:             * @see Statement
0315:             * @see #getResultSet
0316:             * @see #getUpdateCount
0317:             * @see #getMoreResults
0318:             * @see #getGeneratedKeys
0319:             * @since 1.0
0320:             */
0321:            public boolean execute(String sql, int autoGeneratedKeys)
0322:                    throws DatabaseException {
0323:                try {
0324:                    waitForConnection();
0325:
0326:                    cleanResultSet();
0327:
0328:                    long start = startTrace();
0329:                    boolean result = mStatement.execute(sql, autoGeneratedKeys);
0330:                    outputTrace(start, sql);
0331:
0332:                    setResultset(mStatement.getResultSet());
0333:
0334:                    return result;
0335:                } catch (SQLException e) {
0336:                    handleException();
0337:                    throw new ExecutionErrorException(sql, mConnection
0338:                            .getDatasource(), e);
0339:                }
0340:            }
0341:
0342:            /**
0343:             * Executes the given SQL statement, which may return multiple results,
0344:             * and signals the driver that the auto-generated keys indicated in the
0345:             * given array should be made available for retrieval. This array contains
0346:             * the indexes of the columns in the target table that contain the
0347:             * auto-generated keys that should be made available. The driver will
0348:             * ignore the array if the given SQL statement is not an
0349:             * <code>INSERT</code> statement.
0350:             * <p>Under some (uncommon) situations, a single SQL statement may return
0351:             * multiple result sets and/or update counts. Normally you can ignore this
0352:             * unless you are (1) executing a stored procedure that you know may
0353:             * return multiple results or (2) you are dynamically executing an unknown
0354:             * SQL string.
0355:             * <p>The <code>execute</code> method executes a SQL statement and
0356:             * indicates the form of the first result. You must then use the methods
0357:             * <code>getResultSet</code> or <code>getUpdateCount</code> to retrieve
0358:             * the result, and <code>getMoreResults</code> to move to any subsequent
0359:             * result(s).
0360:             * <p>If an exception is thrown, this <code>DbStatement</code> is
0361:             * automatically closed and an ongoing transaction will be automatically
0362:             * rolled back if it belongs to the executing thread.
0363:             *
0364:             * @param sql any SQL statement
0365:             * @param columnIndexes an array of the indexes of the columns in the
0366:             * inserted row that should be made available for retrieval by a call to
0367:             * the method <code>getGeneratedKeys</code>
0368:             * @return <code>true</code> if the first result is a
0369:             * <code>ResultSet</code> object; or
0370:             * <p><code>false</code> if it is an update count or there are no results
0371:             * @exception DatabaseException if a database access error occurs
0372:             * @see #getResultSet
0373:             * @see #getUpdateCount
0374:             * @see #getMoreResults
0375:             * @since 1.0
0376:             */
0377:            public boolean execute(String sql, int[] columnIndexes)
0378:                    throws DatabaseException {
0379:                try {
0380:                    waitForConnection();
0381:
0382:                    cleanResultSet();
0383:
0384:                    long start = startTrace();
0385:                    boolean result = mStatement.execute(sql, columnIndexes);
0386:                    outputTrace(start, sql);
0387:
0388:                    setResultset(mStatement.getResultSet());
0389:
0390:                    return result;
0391:                } catch (SQLException e) {
0392:                    handleException();
0393:                    throw new ExecutionErrorException(sql, mConnection
0394:                            .getDatasource(), e);
0395:                }
0396:            }
0397:
0398:            /**
0399:             * Executes the given SQL statement, which may return multiple results,
0400:             * and signals the driver that the auto-generated keys indicated in the
0401:             * given array should be made available for retrieval. This array contains
0402:             * the names of the columns in the target table that contain the
0403:             * auto-generated keys that should be made available. The driver will
0404:             * ignore the array if the given SQL statement is not an
0405:             * <code>INSERT</code> statement.
0406:             * <p>In some (uncommon) situations, a single SQL statement may return
0407:             * multiple result sets and/or update counts. Normally you can ignore this
0408:             * unless you are (1) executing a stored procedure that you know may
0409:             * return multiple results or (2) you are dynamically executing an unknown
0410:             * SQL string.
0411:             * <p>The <code>execute</code> method executes a SQL statement and
0412:             * indicates the form of the first result. You must then use the methods
0413:             * <code>getResultSet</code> or <code>getUpdateCount</code> to retrieve
0414:             * the result, and <code>getMoreResults</code> to move to any subsequent
0415:             * result(s).
0416:             * <p>If an exception is thrown, this <code>DbStatement</code> is
0417:             * automatically closed and an ongoing transaction will be automatically
0418:             * rolled back if it belongs to the executing thread.
0419:             *
0420:             * @param sql any SQL statement
0421:             * @param columnNames an array of the names of the columns in the inserted
0422:             * row that should be made available for retrieval by a call to the method
0423:             * <code>getGeneratedKeys</code>
0424:             * @return <code>true</code> if the next result is a
0425:             * <code>ResultSet</code> object; or
0426:             * <p><code>false</code> if it is an update count or there are no more
0427:             * results
0428:             * @exception DatabaseException if a database access error occurs
0429:             * @see #getResultSet
0430:             * @see #getUpdateCount
0431:             * @see #getMoreResults
0432:             * @see #getGeneratedKeys
0433:             * @since 1.0
0434:             */
0435:            public boolean execute(String sql, String[] columnNames)
0436:                    throws DatabaseException {
0437:                try {
0438:                    waitForConnection();
0439:
0440:                    cleanResultSet();
0441:
0442:                    long start = startTrace();
0443:                    boolean result = mStatement.execute(sql, columnNames);
0444:                    outputTrace(start, sql);
0445:
0446:                    setResultset(mStatement.getResultSet());
0447:
0448:                    return result;
0449:                } catch (SQLException e) {
0450:                    handleException();
0451:                    throw new ExecutionErrorException(sql, mConnection
0452:                            .getDatasource(), e);
0453:                }
0454:            }
0455:
0456:            /**
0457:             * Submits a batch of commands to the database for execution and if all
0458:             * commands execute successfully, returns an array of update counts. The
0459:             * <code>int</code> elements of the array that is returned are ordered to
0460:             * correspond to the commands in the batch, which are ordered according to
0461:             * the order in which they were added to the batch. The elements in the
0462:             * array returned by the method <code>executeBatch</code> may be one of
0463:             * the following:
0464:             * <ol>
0465:             * <li>A number greater than or equal to zero -- indicates that the
0466:             * command was processed successfully and is an update count giving the
0467:             * number of rows in the database that were affected by the command's
0468:             * execution
0469:             * <li>A value of <code>SUCCESS_NO_INFO</code> -- indicates that the
0470:             * command was processed successfully but that the number of rows affected
0471:             * is unknown
0472:             * <p>If one of the commands in a batch update fails to execute properly,
0473:             * this method throws a <code>BatchUpdateException</code>, and a JDBC
0474:             * driver may or may not continue to process the remaining commands in the
0475:             * batch. However, the driver's behavior must be consistent with a
0476:             * particular DBMS, either always continuing to process commands or never
0477:             * continuing to process commands. If the driver continues processing
0478:             * after a failure, the array returned by the method
0479:             * <code>BatchUpdateException.getUpdateCounts</code> will contain as many
0480:             * elements as there are commands in the batch, and at least one of the
0481:             * elements will be the following:
0482:             * <p>
0483:             * <li>A value of <code>EXECUTE_FAILED</code> -- indicates that the
0484:             * command failed to execute successfully and occurs only if a driver
0485:             * continues to process commands after a command fails
0486:             * </ol>
0487:             * <p>A driver is not required to implement this method.
0488:             * <p>If an exception is thrown, this <code>DbStatement</code> is
0489:             * automatically closed and an ongoing transaction will be automatically
0490:             * rolled back if it belongs to the executing thread.
0491:             *
0492:             * @return an array of update counts containing one element for each
0493:             * command in the batch. The elements of the array are ordered according
0494:             * to the order in which commands were added to the batch.
0495:             * @exception DatabaseException if a database access error occurs or the
0496:             * driver does not support batch statements. The cause is a {@link
0497:             * java.sql.BatchUpdateException} (a subclass of <code>SQLException</code>)
0498:             * if one of the commands sent to the database fails to execute properly
0499:             * or attempts to return a result set.
0500:             * @since 1.0
0501:             */
0502:            public int[] executeBatch() throws DatabaseException {
0503:                try {
0504:                    waitForConnection();
0505:
0506:                    return mStatement.executeBatch();
0507:                } catch (SQLException e) {
0508:                    handleException();
0509:                    throw new BatchExecutionErrorException(mConnection
0510:                            .getDatasource(), e);
0511:                }
0512:            }
0513:
0514:            /**
0515:             * Executes the given SQL statement. The returned <code>ResultSet</code>
0516:             * object is stored and can be retrieved with the
0517:             * <code>getResultSet</code> method.
0518:             * <p>If an exception is thrown, this <code>DbStatement</code> is
0519:             * automatically closed and an ongoing transaction will be automatically
0520:             * rolled back if it belongs to the executing thread.
0521:             *
0522:             * @param sql a SQL statement to be sent to the database, typically a
0523:             * static SQL <code>SELECT</code> statement
0524:             * @exception DatabaseException if a database access error occurs or the
0525:             * given SQL statement produces anything other than a single
0526:             * <code>ResultSet</code> object
0527:             * @see #getResultSet
0528:             * @since 1.0
0529:             */
0530:            public void executeQuery(String sql) throws DatabaseException {
0531:                try {
0532:                    waitForConnection();
0533:
0534:                    cleanResultSet();
0535:
0536:                    long start = startTrace();
0537:                    mStatement.execute(sql);
0538:                    outputTrace(start, sql);
0539:
0540:                    setResultset(mStatement.getResultSet());
0541:
0542:                    return;
0543:                } catch (SQLException e) {
0544:                    handleException();
0545:                    throw new ExecutionErrorException(sql, mConnection
0546:                            .getDatasource(), e);
0547:                }
0548:            }
0549:
0550:            /**
0551:             * Executes the given <code>Query</code> builder's SQL statement. The
0552:             * returned <code>ResultSet</code> object is stored and can be retrieved
0553:             * with the <code>getResultSet</code> method.
0554:             * <p>If an exception is thrown, this <code>DbStatement</code> is
0555:             * automatically closed and an ongoing transaction will be automatically
0556:             * rolled back if it belongs to the executing thread.
0557:             *
0558:             * @param query a <code>Query</code> builder instance which provides a SQL
0559:             * statement that queries the database
0560:             * @exception DatabaseException if a database access error occurs or the
0561:             * given SQL statement produces anything other than a single
0562:             * <code>ResultSet</code> object
0563:             * @see #getResultSet
0564:             * @since 1.0
0565:             */
0566:            public void executeQuery(ReadQuery query) throws DatabaseException {
0567:                if (null == query)
0568:                    throw new IllegalArgumentException("query can't be null.");
0569:
0570:                executeQuery(query.getSql());
0571:            }
0572:
0573:            /**
0574:             * Executes the given SQL statement, which may be an <code>INSERT</code>,
0575:             * <code>UPDATE</code>, or <code>DELETE</code> statement or an SQL
0576:             * statement that returns nothing, such as an SQL DDL statement.
0577:             * <p>If an exception is thrown, this <code>DbStatement</code> is
0578:             * automatically closed and an ongoing transaction will be automatically
0579:             * rolled back if it belongs to the executing thread.
0580:             *
0581:             * @param sql an SQL <code>INSERT</code>, <code>UPDATE</code> or
0582:             * <code>DELETE</code> statement or a SQL statement that returns nothing
0583:             * @return the row count for <code>INSERT</code>, <code>UPDATE</code> or
0584:             * <code>DELETE</code> statements; or
0585:             * <p><code>0</code> for SQL statements that return nothing
0586:             * @exception DatabaseException if a database access error occurs or the
0587:             * given SQL statement produces a <code>ResultSet</code> object
0588:             * @since 1.0
0589:             */
0590:            public int executeUpdate(String sql) throws DatabaseException {
0591:                try {
0592:                    waitForConnection();
0593:
0594:                    long start = startTrace();
0595:                    int result = mStatement.executeUpdate(sql);
0596:                    outputTrace(start, sql);
0597:
0598:                    return result;
0599:                } catch (SQLException e) {
0600:                    handleException();
0601:                    throw new ExecutionErrorException(sql, mConnection
0602:                            .getDatasource(), e);
0603:                }
0604:            }
0605:
0606:            /**
0607:             * Executes the given <code>Query</code> builder's SQL statement, which
0608:             * may be an <code>INSERT</code>, <code>UPDATE</code>, or
0609:             * <code>DELETE</code> statement or a SQL statement that returns nothing,
0610:             * such as an SQL DDL statement.
0611:             * <p>If an exception is thrown, this <code>DbStatement</code> is
0612:             * automatically closed and an ongoing transaction will be automatically
0613:             * rolled back if it belongs to the executing thread.
0614:             *
0615:             * @param query a <code>Query</code> builder instance which provides a SQL
0616:             * statement that modifies the database
0617:             * @return the row count for <code>INSERT</code>, <code>UPDATE</code> or
0618:             * <code>DELETE</code> statements; or
0619:             * <p><code>0</code> for SQL statements that return nothing
0620:             * @exception DatabaseException if a database access error occurs or the
0621:             * given SQL statement produces a <code>ResultSet</code> object
0622:             * @since 1.0
0623:             */
0624:            public int executeUpdate(Query query) throws DatabaseException {
0625:                if (null == query)
0626:                    throw new IllegalArgumentException("query can't be null.");
0627:
0628:                return executeUpdate(query.getSql());
0629:            }
0630:
0631:            /**
0632:             * Retrieves the direction for fetching rows from database tables that is
0633:             * the default for result sets generated from this
0634:             * <code>DbStatement</code> object. If this <code>DbStatement</code>
0635:             * object has not set a fetch direction by calling the method
0636:             * <code>setFetchDirection</code>, the return value is
0637:             * implementation-specific.
0638:             * <p>If an exception is thrown, this <code>DbStatement</code> is
0639:             * automatically closed and an ongoing transaction will be automatically
0640:             * rolled back if it belongs to the executing thread.
0641:             *
0642:             * @return the default fetch direction for result sets generated from this
0643:             * <code>DbStatement</code> object
0644:             * @exception DatabaseException if a database access error occurs
0645:             * @see #setFetchDirection
0646:             * @since 1.0
0647:             */
0648:            public int getFetchDirection() throws DatabaseException {
0649:                try {
0650:                    return mStatement.getFetchDirection();
0651:                } catch (SQLException e) {
0652:                    handleException();
0653:                    throw new DatabaseException(e);
0654:                }
0655:            }
0656:
0657:            /**
0658:             * Retrieves the number of result set rows that is the default fetch size
0659:             * for <code>ResultSet</code> objects generated from this
0660:             * <code>DbStatement</code> object. If this <code>DbStatement</code>
0661:             * object has not set a fetch size by calling the method
0662:             * <code>setFetchSize</code>, the return value is implementation-specific.
0663:             * <p>If an exception is thrown, this <code>DbStatement</code> is
0664:             * automatically closed and an ongoing transaction will be automatically
0665:             * rolled back if it belongs to the executing thread.
0666:             *
0667:             * @return the default fetch size for result sets generated from this
0668:             * <code>DbStatement</code> object
0669:             * @exception DatabaseException if a database access error occurs
0670:             * @see #setFetchSize
0671:             * @since 1.0
0672:             */
0673:            public int getFetchSize() throws DatabaseException {
0674:                try {
0675:                    return mStatement.getFetchSize();
0676:                } catch (SQLException e) {
0677:                    handleException();
0678:                    throw new DatabaseException(e);
0679:                }
0680:            }
0681:
0682:            /**
0683:             * Retrieves any auto-generated keys created as a result of executing this
0684:             * <code>DbStatement</code> object. If this DbStatement object did not
0685:             * generate any keys, an empty <code>DbResultSet</code> object is
0686:             * returned.
0687:             * <p>If an exception is thrown, this <code>DbStatement</code> is
0688:             * automatically closed and an ongoing transaction will be automatically
0689:             * rolled back if it belongs to the executing thread.
0690:             *
0691:             * @return a <code>DbResultSet</code> object containing the auto-generated
0692:             * key(s) generated by the execution of this <code>DbStatement</code>
0693:             * object
0694:             * @exception DatabaseException if a database access error occurs
0695:             * @since 1.0
0696:             */
0697:            public DbResultSet getGeneratedKeys() throws DatabaseException {
0698:                try {
0699:                    return wrapWithDbResultSet(mStatement.getGeneratedKeys());
0700:                } catch (SQLException e) {
0701:                    handleException();
0702:                    throw new DatabaseException(e);
0703:                }
0704:            }
0705:
0706:            /**
0707:             * Retrieves the first auto-generated key created as a result of executing
0708:             * this <code>DbStatement</code> object as an integer. If this
0709:             * <code>DbStatement</code> object did not generate any keys, a exception
0710:             * is thrown.
0711:             * <p>If an exception is thrown, this <code>DbStatement</code> is
0712:             * automatically closed and an ongoing transaction will be automatically
0713:             * rolled back if it belongs to the executing thread.
0714:             *
0715:             * @return the first auto-generated key as an integer
0716:             * @exception DatabaseException if a database access error occurs
0717:             * @since 1.0
0718:             */
0719:            public int getFirstGeneratedIntKey() throws DatabaseException {
0720:                try {
0721:                    DbResultSet resultset = getGeneratedKeys();
0722:                    resultset.next();
0723:                    return resultset.getInt(1);
0724:                } catch (SQLException e) {
0725:                    handleException();
0726:                    throw new DatabaseException(e);
0727:                }
0728:            }
0729:
0730:            /**
0731:             * Retrieves the maximum number of bytes that can be returned for
0732:             * character and binary column values in a <code>ResultSet</code> object
0733:             * produced by this <code>Statement</code> object. This limit applies only
0734:             * to <code>BINARY</code>, <code>VARBINARY</code>,
0735:             * <code>LONGVARBINARY</code>, <code>CHAR</code>, <code>VARCHAR</code>,
0736:             * and <code>LONGVARCHAR</code> columns. If the limit is exceeded, the
0737:             * excess data is silently discarded.
0738:             * <p>If an exception is thrown, this <code>DbStatement</code> is
0739:             * automatically closed and an ongoing transaction will be automatically
0740:             * rolled back if it belongs to the executing thread.
0741:             *
0742:             * @return the current column size limit for columns storing character and
0743:             * binary values; or
0744:             * <p><code>0</code> if there's no limit
0745:             * @exception DatabaseException if a database access error occurs
0746:             * @see #setMaxFieldSize
0747:             * @since 1.0
0748:             */
0749:            public int getMaxFieldSize() throws DatabaseException {
0750:                try {
0751:                    return mStatement.getMaxFieldSize();
0752:                } catch (SQLException e) {
0753:                    handleException();
0754:                    throw new DatabaseException(e);
0755:                }
0756:            }
0757:
0758:            /**
0759:             * Retrieves the maximum number of rows that a <code>ResultSet</code>
0760:             * object produced by this <code>DbStatement</code> object can contain. If
0761:             * this limit is exceeded, the excess rows are silently dropped.
0762:             * <p>If an exception is thrown, this <code>DbStatement</code> is
0763:             * automatically closed and an ongoing transaction will be automatically
0764:             * rolled back if it belongs to the executing thread.
0765:             *
0766:             * @return the current maximum number of rows for a <code>ResultSet</code>
0767:             * object produced by this <code>Statement</code> object; or
0768:             * <p><code>0</code> if there's no limit
0769:             * @exception DatabaseException if a database access error occurs
0770:             * @see #setMaxRows
0771:             * @since 1.0
0772:             */
0773:            public int getMaxRows() throws DatabaseException {
0774:                try {
0775:                    return mStatement.getMaxRows();
0776:                } catch (SQLException e) {
0777:                    handleException();
0778:                    throw new DatabaseException(e);
0779:                }
0780:            }
0781:
0782:            /**
0783:             * Moves to this <code>DbStatement</code> object's next result, returns
0784:             * <code>true</code> if it is a <code>ResultSet</code> object, and
0785:             * implicitly closes any current <code>ResultSet</code> object(s) obtained
0786:             * with the method <code>getResultSet</code>.
0787:             * <p>There are no more results when the following is true:
0788:             * <pre>
0789:             * <code>(!getMoreResults() &amp;&amp; (getUpdateCount() == -1)</code>
0790:             * </pre>
0791:             * <p>If an exception is thrown, this <code>DbStatement</code> is
0792:             * automatically closed and an ongoing transaction will be automatically
0793:             * rolled back if it belongs to the executing thread.
0794:             *
0795:             * @return <code>true</code> if the next result is a
0796:             * <code>ResultSet</code> object; or
0797:             * <p><code>false</code> if it is an update count or there are no more
0798:             * results
0799:             * @exception DatabaseException if a database access error occurs
0800:             * @see #execute
0801:             * @since 1.0
0802:             */
0803:            public boolean getMoreResults() throws DatabaseException {
0804:                try {
0805:                    cleanResultSet();
0806:
0807:                    boolean result = mStatement.getMoreResults();
0808:                    setResultset(mStatement.getResultSet());
0809:                    return result;
0810:                } catch (SQLException e) {
0811:                    handleException();
0812:                    throw new DatabaseException(e);
0813:                }
0814:            }
0815:
0816:            /**
0817:             * Moves to this <code>DbStatement</code> object's next result, deals with
0818:             * any current <code>ResultSet</code> object(s) according to the
0819:             * instructions specified by the given flag, and returns <code>true</code>
0820:             * if the next result is a <code>ResultSet</code> object.
0821:             * <p>There are no more results when the following is true:
0822:             * <pre>
0823:             *	  <code>(!getMoreResults() &amp;&amp; (getUpdateCount() == -1)</code>
0824:             * </pre>
0825:             * <p>If an exception is thrown, this <code>DbStatement</code> is
0826:             * automatically closed and an ongoing transaction will be automatically
0827:             * rolled back if it belongs to the executing thread.
0828:             *
0829:             * @param current one of the following <code>Statement</code> constants
0830:             * indicating what should happen to current <code>ResultSet</code> objects
0831:             * obtained using the method <code>getResultSet</code>:
0832:             * <code>CLOSE_CURRENT_RESULT</code>, <code>KEEP_CURRENT_RESULT</code>, or
0833:             * <code>CLOSE_ALL_RESULTS</code>
0834:             * @return <code>true</code> if the next result is a
0835:             * <code>ResultSet</code> object; or
0836:             * <p><code>false</code> if it is an update count or there are no more
0837:             * results
0838:             * @exception DatabaseException if a database access error occurs
0839:             * @see Statement
0840:             * @see #execute
0841:             * @since 1.0
0842:             */
0843:            public boolean getMoreResults(int current) throws DatabaseException {
0844:                try {
0845:                    cleanResultSet();
0846:
0847:                    boolean result = mStatement.getMoreResults(current);
0848:                    setResultset(mStatement.getResultSet());
0849:                    return result;
0850:                } catch (SQLException e) {
0851:                    handleException();
0852:                    throw new DatabaseException(e);
0853:                }
0854:            }
0855:
0856:            /**
0857:             * Retrieves the number of seconds the driver will wait for a
0858:             * <code>DbStatement</code> object to execute. If the limit is exceeded, a
0859:             * <code>DatabaseException</code> is thrown.
0860:             * <p>If an exception is thrown, this <code>DbStatement</code> is
0861:             * automatically closed and an ongoing transaction will be automatically
0862:             * rolled back if it belongs to the executing thread.
0863:             *
0864:             * @return the current query timeout limit in seconds; or
0865:             * <p><code>0</code> if there's no limit
0866:             * @exception DatabaseException if a database access error occurs
0867:             * @see #setQueryTimeout
0868:             * @since 1.0
0869:             */
0870:            public int getQueryTimeout() throws DatabaseException {
0871:                try {
0872:                    return mStatement.getQueryTimeout();
0873:                } catch (SQLException e) {
0874:                    handleException();
0875:                    throw new DatabaseException(e);
0876:                }
0877:            }
0878:
0879:            /**
0880:             * Reports whether the last column read had a value of SQL
0881:             * <code>NULL</code>. Note that you must first call one of the getter
0882:             * methods on a column to try to read its value and then call the method
0883:             * <code>wasNull</code> to see if the value read was SQL <code>NULL</code>.
0884:             * <p>If an exception is thrown, this <code>DbStatement</code> is
0885:             * automatically closed and an ongoing transaction will be automatically
0886:             * rolled back if it belongs to the executing thread.
0887:             *
0888:             * @return <code>true</code> if the last column value read was SQL
0889:             * <code>NULL</code>; or
0890:             * <p><code>false</code> otherwise
0891:             * @exception DatabaseException if a database access error occurs
0892:             * @since 1.0
0893:             */
0894:            public boolean wasNull() throws DatabaseException {
0895:                if (null == mResultSet) {
0896:                    throw new MissingResultsException(getConnection()
0897:                            .getDatasource());
0898:                }
0899:
0900:                try {
0901:                    return mResultSet.wasNull();
0902:                } catch (SQLException e) {
0903:                    handleException();
0904:                    throw new DatabaseException(e);
0905:                }
0906:            }
0907:
0908:            /**
0909:             * Retrieves the result set concurrency for <code>ResultSet</code> objects
0910:             * generated by this <code>DbStatement</code> object.
0911:             * <p>If an exception is thrown, this <code>DbStatement</code> is
0912:             * automatically closed and an ongoing transaction will be automatically
0913:             * rolled back if it belongs to the executing thread.
0914:             *
0915:             * @return either <code>ResultSet.CONCUR_READ_ONLY</code> or
0916:             * <code>ResultSet.CONCUR_UPDATABLE</code>
0917:             * @exception DatabaseException if a database access error occurs
0918:             * @see ResultSet
0919:             * @since 1.0
0920:             */
0921:            public int getResultSetConcurrency() throws DatabaseException {
0922:                try {
0923:                    return mStatement.getResultSetConcurrency();
0924:                } catch (SQLException e) {
0925:                    handleException();
0926:                    throw new DatabaseException(e);
0927:                }
0928:            }
0929:
0930:            /**
0931:             * Retrieves the result set holdability for <code>ResultSet</code> objects
0932:             * generated by this <code>DbStatement</code> object.
0933:             * <p>If an exception is thrown, this <code>DbStatement</code> is
0934:             * automatically closed and an ongoing transaction will be automatically
0935:             * rolled back if it belongs to the executing thread.
0936:             *
0937:             * @return either <code>ResultSet.HOLD_CURSORS_OVER_COMMIT</code> or
0938:             * <code>ResultSet.CLOSE_CURSORS_AT_COMMIT</code>
0939:             * @exception DatabaseException if a database access error occurs
0940:             * @see ResultSet
0941:             * @since 1.0
0942:             */
0943:            public int getResultSetHoldability() throws DatabaseException {
0944:                try {
0945:                    return mStatement.getResultSetHoldability();
0946:                } catch (SQLException e) {
0947:                    handleException();
0948:                    throw new DatabaseException(e);
0949:                }
0950:            }
0951:
0952:            /**
0953:             * Retrieves the result set type for <code>ResultSet</code> objects
0954:             * generated by this <code>DbStatement</code> object.
0955:             * <p>If an exception is thrown, this <code>DbStatement</code> is
0956:             * automatically closed and an ongoing transaction will be automatically
0957:             * rolled back if it belongs to the executing thread.
0958:             *
0959:             * @return one of <code>ResultSet.TYPE_FORWARD_ONLY</code>,
0960:             * <code>ResultSet.TYPE_SCROLL_INSENSITIVE</code>, or
0961:             * <code>ResultSet.TYPE_SCROLL_SENSITIVE</code>
0962:             * @exception DatabaseException if a database access error occurs
0963:             * @see ResultSet
0964:             * @since 1.0
0965:             */
0966:            public int getResultSetType() throws DatabaseException {
0967:                try {
0968:                    return mStatement.getResultSetType();
0969:                } catch (SQLException e) {
0970:                    handleException();
0971:                    throw new DatabaseException(e);
0972:                }
0973:            }
0974:
0975:            /**
0976:             * Retrieves the current result as an update count; if the result is a
0977:             * <code>ResultSet</code> object or there are no more results, -1 is
0978:             * returned. This method should be called only once per result.
0979:             * <p>If an exception is thrown, this <code>DbStatement</code> is
0980:             * automatically closed and an ongoing transaction will be automatically
0981:             * rolled back if it belongs to the executing thread.
0982:             *
0983:             * @return the current result as an update count; or
0984:             * <p><code>-1</code> if the current result is a <code>ResultSet</code>
0985:             * object or there are no more results
0986:             * @exception DatabaseException if a database access error occurs
0987:             * @see #execute
0988:             * @since 1.0
0989:             */
0990:            public int getUpdateCount() throws DatabaseException {
0991:                try {
0992:                    return mStatement.getUpdateCount();
0993:                } catch (SQLException e) {
0994:                    handleException();
0995:                    throw new DatabaseException(e);
0996:                }
0997:            }
0998:
0999:            /**
1000:             * Retrieves the first warning reported by calls on this
1001:             * <code>Statement</code> object. Subsequent <code>DbStatement</code>
1002:             * object warnings will be chained to this <code>SQLWarning</code> object.
1003:             * <p>The warning chain is automatically cleared each time a statement is
1004:             * (re)executed. This method may not be called on a closed
1005:             * <code>DbStatement</code> object; doing so will cause an
1006:             * <code>SQLException</code> to be thrown.
1007:             * <p>If an exception is thrown, this <code>DbStatement</code> is
1008:             * automatically closed and an ongoing transaction will be automatically
1009:             * rolled back if it belongs to the executing thread.
1010:             * <p><b>Note:</b> If you are processing a <code>ResultSet</code> object,
1011:             * any warnings associated with reads on that <code>ResultSet</code>
1012:             * object will be chained on it rather than on the
1013:             * <code>DbStatement</code> object that produced it.
1014:             *
1015:             * @return the first <code>SQLWarning</code> object; or
1016:             * <p><code>null</code> if there are no warnings
1017:             * @exception DatabaseException if a database access error occurs or this
1018:             * method is called on a closed statement
1019:             * @since 1.0
1020:             */
1021:            public SQLWarning getWarnings() throws DatabaseException {
1022:                try {
1023:                    return mStatement.getWarnings();
1024:                } catch (SQLException e) {
1025:                    handleException();
1026:                    throw new DatabaseException(e);
1027:                }
1028:            }
1029:
1030:            /**
1031:             * Retrieves the current result as a <code>ResultSet</code> object. This
1032:             * method returns the internally stored result and can be called as many
1033:             * times as wanted, contrary to the regular JDBC counterpart.
1034:             *
1035:             * @return the current result as a <code>ResultSet</code> object; or
1036:             * <p><code>NULL</code> if the result is an update count.
1037:             * @see #execute
1038:             * @since 1.0
1039:             */
1040:            public DbResultSet getResultSet() {
1041:                return mResultSet;
1042:            }
1043:
1044:            /**
1045:             * Gives the driver a hint as to the direction in which rows will be
1046:             * processed in <code>ResultSet</code> objects created using this
1047:             * <code>DbStatement</code> object. The default value is
1048:             * <code>ResultSet.FETCH_FORWARD</code>.
1049:             * <p>Note that this method sets the default fetch direction for result
1050:             * sets generated by this <code>DbStatement</code> object. Each result set
1051:             * has its own methods for getting and setting its own fetch direction.
1052:             * <p>If an exception is thrown, this <code>DbStatement</code> is
1053:             * automatically closed and an ongoing transaction will be automatically
1054:             * rolled back if it belongs to the executing thread.
1055:             *
1056:             * @param direction the initial direction for processing rows
1057:             * @exception DatabaseException if a database access error occurs or the
1058:             * given direction is not one of <code>ResultSet.FETCH_FORWARD</code>,
1059:             * <code>ResultSet.FETCH_REVERSE</code>, or
1060:             * <code>ResultSet.FETCH_UNKNOWN</code>
1061:             * @see #getFetchDirection
1062:             * @see ResultSet
1063:             * @since 1.0
1064:             */
1065:            public void setFetchDirection(int direction)
1066:                    throws DatabaseException {
1067:                try {
1068:                    mStatement.setFetchDirection(direction);
1069:                } catch (SQLException e) {
1070:                    handleException();
1071:                    throw new DatabaseException(e);
1072:                }
1073:            }
1074:
1075:            /**
1076:             * Gives the JDBC driver a hint as to the number of rows that should be
1077:             * fetched from the database when more rows are needed. The number of rows
1078:             * specified affects only result sets created using this statement. If the
1079:             * value specified is zero, then the hint is ignored. The default value is
1080:             * zero.
1081:             * <p>If an exception is thrown, this <code>DbStatement</code> is
1082:             * automatically closed and an ongoing transaction will be automatically
1083:             * rolled back if it belongs to the executing thread.
1084:             *
1085:             * @param rows the number of rows to fetch
1086:             * @exception DatabaseException if a database access error occurs, or the
1087:             * condition 0 &lt;= <code>rows</code> &lt;=
1088:             * <code>this.getMaxRows()</code> is not satisfied.
1089:             * @see #getFetchSize
1090:             * @see #getMaxRows
1091:             * @since 1.0
1092:             */
1093:            public void setFetchSize(int rows) throws DatabaseException {
1094:                try {
1095:                    mStatement.setFetchSize(rows);
1096:                } catch (SQLException e) {
1097:                    handleException();
1098:                    throw new DatabaseException(e);
1099:                }
1100:            }
1101:
1102:            /**
1103:             * Sets the limit for the maximum number of bytes in a
1104:             * <code>ResultSet</code> column storing character or binary values to the
1105:             * given number of bytes. This limit applies only to <code>BINARY</code>,
1106:             * <code>VARBINARY</code>, <code>LONGVARBINARY</code>, <code>CHAR</code>,
1107:             * <code>VARCHAR</code>, and <code>LONGVARCHAR</code> fields. If the limit
1108:             * is exceeded, the excess data is silently discarded. For maximum
1109:             * portability, use values greater than 256.
1110:             * <p>If an exception is thrown, this <code>DbStatement</code> is
1111:             * automatically closed and an ongoing transaction will be automatically
1112:             * rolled back if it belongs to the executing thread.
1113:             *
1114:             * @param max the new column size limit in bytes; zero means there is no
1115:             * limit
1116:             * @exception DatabaseException if a database access error occurs or the
1117:             * condition max &gt;= 0 is not satisfied
1118:             * @see #getMaxFieldSize
1119:             * @since 1.0
1120:             */
1121:            public void setMaxFieldSize(int max) throws DatabaseException {
1122:                try {
1123:                    mStatement.setMaxFieldSize(max);
1124:                } catch (SQLException e) {
1125:                    handleException();
1126:                    throw new DatabaseException(e);
1127:                }
1128:            }
1129:
1130:            /**
1131:             * Sets the limit for the maximum number of rows that any
1132:             * <code>ResultSet</code> object can contain to the given number. If the
1133:             * limit is exceeded, the excess rows are silently dropped.
1134:             * <p>If an exception is thrown, this <code>DbStatement</code> is
1135:             * automatically closed and an ongoing transaction will be automatically
1136:             * rolled back if it belongs to the executing thread.
1137:             *
1138:             * @param max the new max rows limit; zero means there is no limit
1139:             * @exception DatabaseException if a database access error occurs or the
1140:             * condition max &gt;= 0 is not satisfied
1141:             * @see #getMaxRows
1142:             * @since 1.0
1143:             */
1144:            public void setMaxRows(int max) throws DatabaseException {
1145:                try {
1146:                    mStatement.setMaxRows(max);
1147:                } catch (SQLException e) {
1148:                    handleException();
1149:                    throw new DatabaseException(e);
1150:                }
1151:            }
1152:
1153:            /**
1154:             * Sets the number of seconds the driver will wait for a
1155:             * <code>DbStatement</code> object to execute to the given number of
1156:             * seconds. If the limit is exceeded, an <code>DatabaseException</code> is
1157:             * thrown.
1158:             *
1159:             * @param max the new query timeout limit in seconds; zero means there is
1160:             * no limit
1161:             * @exception DatabaseException if a database access error occurs or the
1162:             * condition seconds &gt;= 0 is not satisfied
1163:             * @see #getQueryTimeout
1164:             * @since 1.0
1165:             */
1166:            public void setQueryTimeout(int max) throws DatabaseException {
1167:                try {
1168:                    mStatement.setQueryTimeout(max);
1169:                } catch (SQLException e) {
1170:                    handleException();
1171:                    throw new DatabaseException(e);
1172:                }
1173:            }
1174:
1175:            /**
1176:             * Returns the <code>DbConnection</code> object from which this
1177:             * <code>DbStatement</code> object has been instantiated.
1178:             *
1179:             * @return the instantiating <code>DbConnection</code> object.
1180:             * @since 1.0
1181:             */
1182:            public DbConnection getConnection() {
1183:                return mConnection;
1184:            }
1185:
1186:            /**
1187:             * Waits until the <code>DbConnection</code> method is available for use.
1188:             * This method is used by all the execution methods to effectively
1189:             * integrate with the connection pool.
1190:             *
1191:             * @exception DatabaseException when a database access error occurs or the
1192:             * connection isn't open or has timed-out
1193:             * @since 1.0
1194:             */
1195:            void waitForConnection() throws DatabaseException {
1196:                if (mConnection.isClosed()) {
1197:                    mConnection.handleException();
1198:                    throw new DatabaseException("The connection is not open.");
1199:                }
1200:
1201:                while (true) {
1202:                    if (!mConnection.isFree()) {
1203:                        try {
1204:                            synchronized (mConnection) {
1205:                                mConnection.wait();
1206:                            }
1207:                        } catch (InterruptedException e) {
1208:                            throw new DatabaseException(
1209:                                    "Timeout while waiting for the connection to become available.");
1210:                        }
1211:                    } else {
1212:                        break;
1213:                    }
1214:                }
1215:            }
1216:
1217:            /**
1218:             * Checks if there's a <code>ResultSet</code> object present.
1219:             *
1220:             * @return <code>true</code> if a <code>ResultSet</code> object is
1221:             * available; or
1222:             * <p><code>false</code> otherwise.
1223:             * @since 1.0
1224:             */
1225:            boolean hasResultset() {
1226:                return null != mResultSet;
1227:            }
1228:
1229:            /**
1230:             * Set the current <code>ResultSet</code> object and cleans up the
1231:             * previous <code>ResultSet</code> object automatically.
1232:             *
1233:             * @param resultSet the new current <code>ResultSet</code> object
1234:             * @exception DatabaseException if a database access error occurred.
1235:             * @since 1.0
1236:             */
1237:            protected void setResultset(ResultSet resultSet)
1238:                    throws DatabaseException {
1239:                if (null == resultSet) {
1240:                    mResultSet = null;
1241:                } else {
1242:                    mResultSet = wrapWithDbResultSet(resultSet);
1243:                }
1244:            }
1245:
1246:            private DbResultSet wrapWithDbResultSet(ResultSet resultSet)
1247:                    throws DatabaseException {
1248:                Class resulset_class = null;
1249:                try {
1250:                    if (JavaSpecificationUtils.isAtLeastJdk16()) {
1251:                        resulset_class = Class.forName(DbResultSet.class
1252:                                .getName()
1253:                                + "40");
1254:                    } else {
1255:                        resulset_class = Class.forName(DbResultSet.class
1256:                                .getName()
1257:                                + "30");
1258:                    }
1259:
1260:                    Constructor constructor = resulset_class
1261:                            .getDeclaredConstructor(new Class[] {
1262:                                    DbStatement.class, ResultSet.class });
1263:                    return (DbResultSet) constructor.newInstance(new Object[] {
1264:                            this , resultSet });
1265:                } catch (Exception e) {
1266:                    handleException();
1267:                    throw new DatabaseException(e);
1268:                }
1269:            }
1270:
1271:            /**
1272:             * Cleans up and closes the current <code>ResultSet</code> object.
1273:             *
1274:             * @exception DatabaseException if a database access error occurred.
1275:             * @since 1.0
1276:             */
1277:            void cleanResultSet() throws DatabaseException {
1278:                if (null != mResultSet) {
1279:                    try {
1280:                        mResultSet.close();
1281:                        mResultSet = null;
1282:                    } catch (SQLException e) {
1283:                        mResultSet = null;
1284:                        close();
1285:                        throw new DatabaseException(e);
1286:                    }
1287:                }
1288:            }
1289:
1290:            /**
1291:             * Performs the cleanup logic in case an exeception is thrown during
1292:             * execution. The statement will be closed and if a transaction is active,
1293:             * it will be automatically rolled back.
1294:             *
1295:             * @exception DatabaseException when an error occurs during the cleanup of
1296:             * the connection, or when an error occurs during the roll-back.
1297:             */
1298:            protected void handleException() throws DatabaseException {
1299:                synchronized (this ) {
1300:                    try {
1301:                        close();
1302:                    } catch (DatabaseException e) {
1303:                        // this is a defensive close, if it can't be closed again, it
1304:                        // probably already is
1305:                    }
1306:
1307:                    if (mConnection.isTransactionValidForThread()) {
1308:                        mConnection.rollback();
1309:                    } else {
1310:                        synchronized (mConnection) {
1311:                            mConnection.notifyAll();
1312:                        }
1313:                    }
1314:                }
1315:            }
1316:
1317:            /**
1318:             * Ensures that this <code>DbStatement</code> is correctly closed when
1319:             * it's garbage collected.
1320:             *
1321:             * @exception Throwable if an error occurred during the finalization
1322:             * @since 1.0
1323:             */
1324:            protected void finalize() throws Throwable {
1325:                close();
1326:                super .finalize();
1327:            }
1328:
1329:            /**
1330:             * Simply clones the instance with the default clone method. This creates
1331:             * a shallow copy of all fields and the clone will in fact just be another
1332:             * reference to the same underlying data. The independence of each cloned
1333:             * instance is consciously not respected since they rely on resources that
1334:             * can't be cloned.
1335:             *
1336:             * @since 1.0
1337:             */
1338:            public Object clone() {
1339:                try {
1340:                    return super .clone();
1341:                } catch (CloneNotSupportedException e) {
1342:                    // this should never happen
1343:                    Logger.getLogger("com.uwyn.rife.database").severe(
1344:                            ExceptionUtils.getExceptionStackTrace(e));
1345:                    return null;
1346:                }
1347:            }
1348:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.