0001: /*
0002: * <copyright>
0003: *
0004: * Copyright 1997-2004 BBNT Solutions, LLC
0005: * under sponsorship of the Defense Advanced Research Projects
0006: * Agency (DARPA).
0007: *
0008: * You can redistribute this software and/or modify it under the
0009: * terms of the Cougaar Open Source License as published on the
0010: * Cougaar Open Source Website (www.cougaar.org).
0011: *
0012: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
0013: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
0014: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
0015: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
0016: * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
0017: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
0018: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
0019: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
0020: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
0021: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
0022: * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0023: *
0024: * </copyright>
0025: */
0026:
0027: /*
0028: * Originally from delta/fgi package mil.darpa.log.alpine.delta.plugin;
0029: * Copyright 1997 BBN Systems and Technologies, A Division of BBN Corporation
0030: * 10 Moulton Street, Cambridge, MA 02138 (617) 873-3000
0031: */
0032:
0033: package org.cougaar.util;
0034:
0035: import java.io.InputStream;
0036: import java.io.Reader;
0037: import java.math.BigDecimal;
0038: import java.net.URL;
0039: import java.sql.Array;
0040: import java.sql.Blob;
0041: import java.sql.CallableStatement;
0042: import java.sql.Clob;
0043: import java.sql.Connection;
0044: import java.sql.DatabaseMetaData;
0045: import java.sql.Driver;
0046: import java.sql.DriverManager;
0047: import java.sql.ParameterMetaData;
0048: import java.sql.PreparedStatement;
0049: import java.sql.Ref;
0050: import java.sql.ResultSet;
0051: import java.sql.ResultSetMetaData;
0052: import java.sql.SQLException;
0053: import java.sql.SQLWarning;
0054: import java.sql.Savepoint;
0055: import java.sql.Statement;
0056: import java.sql.Time;
0057: import java.sql.Timestamp;
0058: import java.util.ArrayList;
0059: import java.util.Calendar;
0060: import java.util.HashMap;
0061: import java.util.Iterator;
0062: import java.util.Map;
0063: import java.util.Properties;
0064:
0065: import org.cougaar.bootstrap.SystemProperties;
0066: import org.cougaar.util.log.Logger;
0067: import org.cougaar.util.log.Logging;
0068:
0069: /**
0070: * A database connection manager that creates pools of db connections
0071: * that can be reused to improve performance. DBConnectionPool should
0072: * be used in exactly the same way as the DriverManager class. That
0073: * is, call DBConnectionPool.getConnection() to get a Connection, use
0074: * the connection and close it. The same issues that exist for
0075: * Connections obtained from the DriverManager exist for Connections
0076: * obtained from DBConnectionPool. In particular, ResultSets should be
0077: * closed when you are finished with them so that you do not exceed
0078: * the limit on open ResultSets and Statements should be closed when
0079: * you are finished with them so you do not exceed the limit on open
0080: * Statements. In the same way as for Connections obtained from the
0081: * DriverManager, ResultSets that are not closed will be closed when
0082: * you close the Statement and Statements that are not closed will be
0083: * closed when you close the Connection.
0084: *
0085: * @property org.cougaar.util.DBConnectionPool.maxConnections number
0086: * of simulataneous connections allowed per pool (10).
0087: * @property org.cougaar.util.DBConnectionPool.timeoutCheckInterval
0088: * milliseconds between checks to see if any old connections should be
0089: * collected (5000).
0090: * @property org.cougaar.util.DBConnectionPool.timeout milliseconds
0091: * that a connection must be idle in order to be collected by the
0092: * reaper (10000).
0093: * @note The property org.cougaar.util.DBConnectionPool.verbosity used
0094: * to be used to control logging behavior. Now it uses standard cougaar
0095: * logging with the name org.cuogaar.util.DBConnectionPool at the log levels
0096: * ERROR, WARN and DEBUG.
0097: **/
0098: public class DBConnectionPool {
0099: // keep a logger around for status.
0100: protected static final Logger logger = Logging
0101: .getLogger(DBConnectionPool.class);
0102:
0103: /**
0104: * A hash table relating the database URL and user to a connection
0105: * pool.
0106: */
0107: private static HashMap dbConnectionPools = new HashMap();
0108:
0109: /**
0110: * The separator inserted between the database URL and user to form
0111: * the key to the dbConnectionPools hash table.
0112: */
0113: private static final String SEP = "#";
0114:
0115: /** How often to run the timeout out checker, in milliseconds. */
0116: private static long TIMEOUT_CHECK_INTERVAL = 5 * 1000L;
0117:
0118: /**
0119: * How long to keep old connections before closing and releasing
0120: * them.
0121: *
0122: * The default value may be controlled with the
0123: * System Property org.cougaar.util.DBConnectionPool.maxConnections
0124: */
0125: private static long TIMEOUT = 10 * 1000L;
0126:
0127: /**
0128: * The number of cursors created after which we always release the
0129: * connection. This tries to avoid an accumulation of never released
0130: * cursors as the pooled connection is re-used. Default is 5.
0131: */
0132: private static int MAX_CONNECTIONS = 5;
0133:
0134: static {
0135: String prefix = "org.cougaar.util.DBConnectionPool.";
0136:
0137: TIMEOUT_CHECK_INTERVAL = SystemProperties.getLong(prefix
0138: + "timeoutCheckInterval", TIMEOUT_CHECK_INTERVAL);
0139: TIMEOUT = SystemProperties.getLong(prefix + "timeout", TIMEOUT);
0140: MAX_CONNECTIONS = SystemProperties.getInt(prefix
0141: + "maxConnections", MAX_CONNECTIONS);
0142: }
0143:
0144: /**
0145: * Record the key for this pool for debugging purposes.
0146: */
0147: private String key;
0148:
0149: /**
0150: * Construct a new pool. Record the key for debugging.
0151: */
0152: private DBConnectionPool(String key, int max_connections) {
0153: this .key = key;
0154: this .maxConnections = (max_connections > 0 ? max_connections
0155: : MAX_CONNECTIONS);
0156: }
0157:
0158: /**
0159: * Construct a new pool. Record the key for debugging.
0160: */
0161: private DBConnectionPool(String key) {
0162: this .key = key;
0163: this .maxConnections = MAX_CONNECTIONS;
0164: }
0165:
0166: int entryCounter = 0;
0167:
0168: /** how many clients are waiting for a connection in this pool? **/
0169: int waitingCounter = 0;
0170:
0171: /**
0172: * Inner class to record individual connections
0173: */
0174: class DBConnectionPoolEntry {
0175: int entryNumber = ++entryCounter;
0176: boolean defaultAutoCommit;
0177:
0178: /**
0179: * Construct an entry for a given connection that is not in use.
0180: */
0181: DBConnectionPoolEntry(Connection aConnection)
0182: throws SQLException {
0183: theConnection = aConnection;
0184: defaultAutoCommit = theConnection.getAutoCommit();
0185: }
0186:
0187: /**
0188: * Return the pool that this entry is in.
0189: */
0190: DBConnectionPool getDBConnectionPool() {
0191: return DBConnectionPool.this ;
0192: }
0193:
0194: /**
0195: * Create a PoolConnection to return to the user.
0196: */
0197: Connection getPoolConnection() throws SQLException {
0198: return new PoolConnection(theConnection);
0199: }
0200:
0201: /**
0202: * This assumes that the entry will no longer be used. There is no mechanism
0203: * to reopen theConnection.
0204: */
0205: private void destroy() {
0206: try {
0207: theConnection.close();
0208: } catch (SQLException sqle) {
0209: sqle.printStackTrace();
0210: }
0211: }
0212:
0213: /**
0214: * The connection of this entry.
0215: */
0216: Connection theConnection;
0217:
0218: /**
0219: * Indicates if this entry is in use.
0220: */
0221: boolean inUse = false;
0222:
0223: /**
0224: * Records when this connection was last used.
0225: */
0226: long lastUsed = System.currentTimeMillis();
0227:
0228: /**
0229: * This is a wrapper for a Connection object that delegates most
0230: * functions to the wrapped object, but interposes some processing
0231: * of its own to keep track of operations that have been done to
0232: * the connection. This record permits the connection to be
0233: * logically closed, but to remain actually open. In particular,
0234: * Statement objects created for the connection can be closed if
0235: * the program has not already done so. In this way, the
0236: * connection starts out in a clean state when reused.
0237: */
0238: class PoolConnection implements Connection {
0239: Connection c;
0240: boolean supportsTransactions;
0241: boolean closed = false;
0242: ArrayList statements = new ArrayList();
0243:
0244: PoolConnection(Connection realConnection)
0245: throws SQLException {
0246: c = realConnection;
0247: supportsTransactions = c.getMetaData()
0248: .supportsTransactions();
0249: if (supportsTransactions)
0250: realConnection.setAutoCommit(defaultAutoCommit);
0251: }
0252:
0253: private void destroyPool() {
0254: DBConnectionPoolEntry entry = DBConnectionPoolEntry.this ;
0255: // If this Connection is in the pool, then destroy the pool,
0256: // otherwise leave it alone.
0257: if (entry.getDBConnectionPool().containsConnection(
0258: entry))
0259: entry.getDBConnectionPool().destroyPool();
0260: }
0261:
0262: private void closeStatement(PoolStatement statement)
0263: throws SQLException {
0264: synchronized (statements) {
0265: statement.theStatement.close();
0266: statements.remove(statement);
0267: }
0268: }
0269:
0270: public Statement createStatement() throws SQLException {
0271: if (closed)
0272: throw new SQLException("Connection is closed");
0273: Statement statement = null;
0274: int rc = 0; // retry count
0275: while (true) {
0276: try {
0277: statement = new PoolStatement(c
0278: .createStatement());
0279: statements.add(statement);
0280: return statement;
0281: } catch (SQLException sqle) {
0282: if (rc < maxRetries && isRetryable(sqle)) {
0283: rc++;
0284: try {
0285: Thread.sleep(retryTimeout);
0286: } catch (InterruptedException ie) {
0287: }
0288: } else {
0289: destroyPool();
0290: throw sqle;
0291: }
0292: }
0293: }
0294: }
0295:
0296: public Statement createStatement(int a, int b)
0297: throws SQLException {
0298: if (closed)
0299: throw new SQLException("Connection is closed");
0300: Statement statement = null;
0301:
0302: int rc = 0; // retry count
0303: while (true) {
0304: try {
0305: statement = new PoolStatement(c
0306: .createStatement(a, b));
0307: statements.add(statement);
0308: return statement;
0309: } catch (SQLException sqle) {
0310: if (rc < maxRetries && isRetryable(sqle)) {
0311: rc++;
0312: try {
0313: Thread.sleep(retryTimeout);
0314: } catch (InterruptedException ie) {
0315: }
0316: } else {
0317: destroyPool();
0318: throw sqle;
0319: }
0320: }
0321: }
0322: }
0323:
0324: public PreparedStatement prepareStatement(String sql)
0325: throws SQLException {
0326: if (closed)
0327: throw new SQLException("Connection is closed");
0328: PreparedStatement statement = null;
0329: try {
0330: statement = (PreparedStatement) new PoolPreparedStatement(
0331: c.prepareStatement(sql));
0332: statements.add(statement);
0333: } catch (SQLException sqle) {
0334: destroyPool();
0335: throw sqle;
0336: }
0337: return statement;
0338: }
0339:
0340: public PreparedStatement prepareStatement(String sql,
0341: int a, int b) throws SQLException {
0342: if (closed)
0343: throw new SQLException("Connection is closed");
0344: PreparedStatement statement = null;
0345: try {
0346: statement = (PreparedStatement) new PoolPreparedStatement(
0347: c.prepareStatement(sql, a, b));
0348: statements.add(statement);
0349: } catch (SQLException sqle) {
0350: destroyPool();
0351: throw sqle;
0352: }
0353: return statement;
0354: }
0355:
0356: public CallableStatement prepareCall(String sql)
0357: throws SQLException {
0358: if (closed)
0359: throw new SQLException("Connection is closed");
0360: CallableStatement statement = null;
0361: try {
0362: statement = new PoolCallableStatement(c
0363: .prepareCall(sql));
0364: statements.add(statement);
0365: } catch (SQLException sqle) {
0366: destroyPool();
0367: throw sqle;
0368: }
0369: return statement;
0370: }
0371:
0372: public CallableStatement prepareCall(String sql, int a,
0373: int b) throws SQLException {
0374: if (closed)
0375: throw new SQLException("Connection is closed");
0376: CallableStatement statement = null;
0377: try {
0378: statement = new PoolCallableStatement(c
0379: .prepareCall(sql, a, b));
0380: statements.add(statement);
0381: } catch (SQLException sqle) {
0382: destroyPool();
0383: throw sqle;
0384: }
0385: return statement;
0386: }
0387:
0388: public String nativeSQL(String sql) throws SQLException {
0389: if (closed)
0390: throw new SQLException("Connection is closed");
0391: String str = null;
0392: try {
0393: str = c.nativeSQL(sql);
0394: } catch (SQLException sqle) {
0395: destroyPool();
0396: throw sqle;
0397: }
0398: return str;
0399: }
0400:
0401: public void setAutoCommit(boolean autoCommit)
0402: throws SQLException {
0403: if (closed)
0404: throw new SQLException("Connection is closed");
0405: try {
0406: c.setAutoCommit(autoCommit);
0407: } catch (SQLException sqle) {
0408: destroyPool();
0409: throw sqle;
0410: }
0411: }
0412:
0413: public boolean getAutoCommit() throws SQLException {
0414: if (closed)
0415: throw new SQLException("Connection is closed");
0416: boolean b;
0417: try {
0418: b = c.getAutoCommit();
0419: } catch (SQLException sqle) {
0420: destroyPool();
0421: throw sqle;
0422: }
0423: return b;
0424: }
0425:
0426: public void commit() throws SQLException {
0427: if (closed)
0428: throw new SQLException("Connection is closed");
0429: try {
0430: if (supportsTransactions)
0431: c.commit();
0432: } catch (SQLException sqle) {
0433: destroyPool();
0434: throw sqle;
0435: }
0436: }
0437:
0438: public void rollback() throws SQLException {
0439: if (closed)
0440: throw new SQLException("Connection is closed");
0441: try {
0442: c.rollback();
0443: } catch (SQLException sqle) {
0444: destroyPool();
0445: throw sqle;
0446: }
0447: }
0448:
0449: public void finalize() {
0450: if (closed)
0451: return; // Connection already closed (normal case)
0452: try { // Connection was never closed (abandoned)
0453: close(); // Simply close it now (it will get reused)
0454: } catch (SQLException e) {
0455: e.printStackTrace(); // Ignore exceptions
0456: }
0457: }
0458:
0459: public void close() throws SQLException {
0460: if (closed)
0461: return;
0462: closed = true;
0463: try {
0464: if (supportsTransactions && !c.getAutoCommit())
0465: c.commit();
0466: synchronized (statements) {
0467: while (statements.size() > 0) {
0468: PoolStatement statement = (PoolStatement) statements
0469: .get(0);
0470: closeStatement(statement);
0471: }
0472: }
0473: } catch (SQLException sqle) {
0474: // Since the entry that contains this Connection still exists, we
0475: // should explicitly kill this entry after the pool is destroyed
0476: destroyPool();
0477: DBConnectionPoolEntry entry = DBConnectionPoolEntry.this ;
0478: entry.destroy();
0479: throw sqle;
0480: }
0481: // If the pool contains the entry, return it, otherwise, the pool has
0482: // been destroyed so destroy the entry
0483: DBConnectionPoolEntry entry = DBConnectionPoolEntry.this ;
0484: if (entry.getDBConnectionPool().containsConnection(
0485: entry))
0486: entry.getDBConnectionPool().release(entry);
0487: else {
0488: entry.destroy();
0489: }
0490: }
0491:
0492: public boolean isClosed() throws SQLException {
0493: return closed;
0494: }
0495:
0496: public DatabaseMetaData getMetaData() throws SQLException {
0497: if (closed)
0498: throw new SQLException("Connection is closed");
0499: DatabaseMetaData data = null;
0500: try {
0501: data = c.getMetaData();
0502: } catch (SQLException sqle) {
0503: destroyPool();
0504: throw sqle;
0505: }
0506: return data;
0507: }
0508:
0509: public void setReadOnly(boolean readOnly)
0510: throws SQLException {
0511: if (closed)
0512: throw new SQLException("Connection is closed");
0513: try {
0514: c.setReadOnly(readOnly);
0515: } catch (SQLException sqle) {
0516: destroyPool();
0517: throw sqle;
0518: }
0519: }
0520:
0521: public boolean isReadOnly() throws SQLException {
0522: if (closed)
0523: throw new SQLException("Connection is closed");
0524: boolean b;
0525: try {
0526: b = c.isReadOnly();
0527: } catch (SQLException sqle) {
0528: destroyPool();
0529: throw sqle;
0530: }
0531: return b;
0532: }
0533:
0534: public void setCatalog(String catalog) throws SQLException {
0535: if (closed)
0536: throw new SQLException("Connection is closed");
0537: try {
0538: c.setCatalog(catalog);
0539: } catch (SQLException sqle) {
0540: destroyPool();
0541: throw sqle;
0542: }
0543: }
0544:
0545: public String getCatalog() throws SQLException {
0546: if (closed)
0547: throw new SQLException("Connection is closed");
0548: String str = null;
0549: try {
0550: str = getCatalog();
0551: } catch (SQLException sqle) {
0552: destroyPool();
0553: throw sqle;
0554: }
0555: return str;
0556: }
0557:
0558: public void setTransactionIsolation(int level)
0559: throws SQLException {
0560: if (closed)
0561: throw new SQLException("Connection is closed");
0562: try {
0563: c.setTransactionIsolation(level);
0564: } catch (SQLException sqle) {
0565: destroyPool();
0566: throw sqle;
0567: }
0568: }
0569:
0570: public int getTransactionIsolation() throws SQLException {
0571: if (closed)
0572: throw new SQLException("Connection is closed");
0573: int i;
0574: try {
0575: i = c.getTransactionIsolation();
0576: } catch (SQLException sqle) {
0577: destroyPool();
0578: throw sqle;
0579: }
0580: return i;
0581: }
0582:
0583: public SQLWarning getWarnings() throws SQLException {
0584: if (closed)
0585: throw new SQLException("Connection is closed");
0586: SQLWarning warn = null;
0587: try {
0588: warn = c.getWarnings();
0589: } catch (SQLException sqle) {
0590: destroyPool();
0591: throw sqle;
0592: }
0593: return warn;
0594: }
0595:
0596: public void clearWarnings() throws SQLException {
0597: if (closed)
0598: throw new SQLException("Connection is closed");
0599: try {
0600: c.clearWarnings();
0601: } catch (SQLException sqle) {
0602: destroyPool();
0603: throw sqle;
0604: }
0605: }
0606:
0607: public java.util.Map getTypeMap() throws SQLException {
0608: if (closed)
0609: throw new SQLException("Connection is closed");
0610: java.util.Map map = null;
0611: try {
0612: map = c.getTypeMap();
0613: } catch (SQLException sqle) {
0614: destroyPool();
0615: throw sqle;
0616: }
0617: return map;
0618: }
0619:
0620: public void setTypeMap(java.util.Map map)
0621: throws SQLException {
0622: if (closed)
0623: throw new SQLException("Connection is closed");
0624: try {
0625: c.setTypeMap(map);
0626: } catch (SQLException sqle) {
0627: destroyPool();
0628: throw sqle;
0629: }
0630: }
0631:
0632: // begin jdk1.4 compatability
0633: public void setHoldability(int holdability)
0634: throws SQLException {
0635: if (closed)
0636: throw new SQLException("Connection is closed");
0637: try {
0638: c.setHoldability(holdability);
0639: } catch (SQLException sqle) {
0640: destroyPool();
0641: throw sqle;
0642: }
0643: }
0644:
0645: public int getHoldability() throws SQLException {
0646: if (closed)
0647: throw new SQLException("Connection is closed");
0648: try {
0649: return c.getHoldability();
0650: } catch (SQLException sqle) {
0651: destroyPool();
0652: throw sqle;
0653: }
0654: }
0655:
0656: public Savepoint setSavepoint() throws SQLException {
0657: if (closed)
0658: throw new SQLException("Connection is closed");
0659: try {
0660: return c.setSavepoint();
0661: } catch (SQLException sqle) {
0662: destroyPool();
0663: throw sqle;
0664: }
0665: }
0666:
0667: public Savepoint setSavepoint(String s) throws SQLException {
0668: if (closed)
0669: throw new SQLException("Connection is closed");
0670: try {
0671: return c.setSavepoint(s);
0672: } catch (SQLException sqle) {
0673: destroyPool();
0674: throw sqle;
0675: }
0676: }
0677:
0678: public void rollback(Savepoint savepoint)
0679: throws SQLException {
0680: if (closed)
0681: throw new SQLException("Connection is closed");
0682: try {
0683: c.rollback(savepoint);
0684: } catch (SQLException sqle) {
0685: destroyPool();
0686: throw sqle;
0687: }
0688: }
0689:
0690: public void releaseSavepoint(Savepoint savepoint)
0691: throws SQLException {
0692: if (closed)
0693: throw new SQLException("Connection is closed");
0694: try {
0695: c.releaseSavepoint(savepoint);
0696: } catch (SQLException sqle) {
0697: destroyPool();
0698: throw sqle;
0699: }
0700: }
0701:
0702: public Statement createStatement(int a, int b, int p)
0703: throws SQLException {
0704: if (closed)
0705: throw new SQLException("Connection is closed");
0706: Statement statement = null;
0707:
0708: int rc = 0; // retry count
0709: while (true) {
0710: try {
0711: statement = new PoolStatement(c
0712: .createStatement(a, b, p));
0713: statements.add(statement);
0714: return statement;
0715: } catch (SQLException sqle) {
0716: if (rc < maxRetries && isRetryable(sqle)) {
0717: rc++;
0718: try {
0719: Thread.sleep(retryTimeout);
0720: } catch (InterruptedException ie) {
0721: }
0722: } else {
0723: destroyPool();
0724: throw sqle;
0725: }
0726: }
0727: }
0728: }
0729:
0730: public PreparedStatement prepareStatement(String sql,
0731: int a, int b, int p) throws SQLException {
0732: if (closed)
0733: throw new SQLException("Connection is closed");
0734: PreparedStatement statement = null;
0735: try {
0736: statement = (PreparedStatement) new PoolPreparedStatement(
0737: c.prepareStatement(sql, a, b, p));
0738: statements.add(statement);
0739: } catch (SQLException sqle) {
0740: destroyPool();
0741: throw sqle;
0742: }
0743: return statement;
0744: }
0745:
0746: public CallableStatement prepareCall(String sql, int a,
0747: int b, int p) throws SQLException {
0748: if (closed)
0749: throw new SQLException("Connection is closed");
0750: CallableStatement statement = null;
0751: try {
0752: statement = new PoolCallableStatement(c
0753: .prepareCall(sql, a, b, p));
0754: statements.add(statement);
0755: } catch (SQLException sqle) {
0756: destroyPool();
0757: throw sqle;
0758: }
0759: return statement;
0760:
0761: }
0762:
0763: public PreparedStatement prepareStatement(String sql, int a)
0764: throws SQLException {
0765: if (closed)
0766: throw new SQLException("Connection is closed");
0767: PreparedStatement statement = null;
0768: try {
0769: statement = (PreparedStatement) new PoolPreparedStatement(
0770: c.prepareStatement(sql, a));
0771: statements.add(statement);
0772: } catch (SQLException sqle) {
0773: destroyPool();
0774: throw sqle;
0775: }
0776: return statement;
0777:
0778: }
0779:
0780: public PreparedStatement prepareStatement(String sql,
0781: int ci[]) throws SQLException {
0782: if (closed)
0783: throw new SQLException("Connection is closed");
0784: PreparedStatement statement = null;
0785: try {
0786: statement = (PreparedStatement) new PoolPreparedStatement(
0787: c.prepareStatement(sql, ci));
0788: statements.add(statement);
0789: } catch (SQLException sqle) {
0790: destroyPool();
0791: throw sqle;
0792: }
0793: return statement;
0794: }
0795:
0796: public PreparedStatement prepareStatement(String sql,
0797: String cn[]) throws SQLException {
0798: if (closed)
0799: throw new SQLException("Connection is closed");
0800: PreparedStatement statement = null;
0801: try {
0802: statement = (PreparedStatement) new PoolPreparedStatement(
0803: c.prepareStatement(sql, cn));
0804: statements.add(statement);
0805: } catch (SQLException sqle) {
0806: destroyPool();
0807: throw sqle;
0808: }
0809: return statement;
0810: }
0811:
0812: // example of where I'd like to go here:
0813: public PreparedStatement x_prepareStatement(
0814: final String sql, final String cn[])
0815: throws SQLException {
0816: return recordPreparedStatement(new PreparedStatementConstructor() {
0817: public PreparedStatement create()
0818: throws SQLException {
0819: return c.prepareStatement(sql, cn);
0820: }
0821: });
0822: }
0823:
0824: private final PreparedStatement recordPreparedStatement(
0825: PreparedStatementConstructor c) throws SQLException {
0826: checkOpen();
0827: try {
0828: PreparedStatement statement = new PoolPreparedStatement(
0829: c.create());
0830: statements.add(statement);
0831: return statement;
0832: } catch (SQLException sqle) {
0833: destroyPool();
0834: throw sqle;
0835: }
0836: }
0837:
0838: private final void checkOpen() throws SQLException {
0839: if (closed)
0840: throw new SQLException("Connection is closed");
0841: }
0842:
0843: // end jdk1.4 compatability
0844:
0845: /**
0846: * A wrapper for a Statement object. Most operations are
0847: * delegated to the wrapped object. The close operation goes
0848: * through the PoolConnection wrapper to keep track of which
0849: * statements have been closed and which haven't.
0850: */
0851: class PoolStatement implements java.sql.Statement {
0852: java.sql.Statement theStatement;
0853:
0854: public PoolStatement(java.sql.Statement theStatement) {
0855: this .theStatement = theStatement;
0856: }
0857:
0858: public void addBatch(String sql)
0859: throws java.sql.SQLException {
0860: try {
0861: theStatement.addBatch(sql);
0862: } catch (SQLException sqle) {
0863: PoolConnection.this .destroyPool();
0864: throw sqle;
0865: }
0866: }
0867:
0868: public void clearBatch() throws java.sql.SQLException {
0869: try {
0870: theStatement.clearBatch();
0871: } catch (SQLException sqle) {
0872: PoolConnection.this .destroyPool();
0873: throw sqle;
0874: }
0875: }
0876:
0877: public int[] executeBatch()
0878: throws java.sql.SQLException {
0879: int[] i;
0880: try {
0881: i = theStatement.executeBatch();
0882: } catch (SQLException sqle) {
0883: PoolConnection.this .destroyPool();
0884: throw sqle;
0885: }
0886: return i;
0887: }
0888:
0889: public Connection getConnection()
0890: throws java.sql.SQLException {
0891: Connection conn = null;
0892: try {
0893: conn = theStatement.getConnection();
0894: } catch (SQLException sqle) {
0895: PoolConnection.this .destroyPool();
0896: throw sqle;
0897: }
0898: return conn;
0899: }
0900:
0901: public int getFetchDirection()
0902: throws java.sql.SQLException {
0903: int i;
0904: try {
0905: i = theStatement.getFetchDirection();
0906: } catch (SQLException sqle) {
0907: PoolConnection.this .destroyPool();
0908: throw sqle;
0909: }
0910: return i;
0911: }
0912:
0913: public int getFetchSize() throws java.sql.SQLException {
0914: int i;
0915: try {
0916: i = theStatement.getFetchSize();
0917: } catch (SQLException sqle) {
0918: PoolConnection.this .destroyPool();
0919: throw sqle;
0920: }
0921: return i;
0922: }
0923:
0924: public int getResultSetConcurrency()
0925: throws java.sql.SQLException {
0926: int i;
0927: try {
0928: i = theStatement.getResultSetConcurrency();
0929: } catch (SQLException sqle) {
0930: PoolConnection.this .destroyPool();
0931: throw sqle;
0932: }
0933: return i;
0934: }
0935:
0936: public int getResultSetType()
0937: throws java.sql.SQLException {
0938: int i;
0939: try {
0940: i = theStatement.getResultSetType();
0941: } catch (SQLException sqle) {
0942: PoolConnection.this .destroyPool();
0943: throw sqle;
0944: }
0945: return i;
0946: }
0947:
0948: public void setFetchDirection(int direction)
0949: throws java.sql.SQLException {
0950: try {
0951: theStatement.setFetchDirection(direction);
0952: } catch (SQLException sqle) {
0953: PoolConnection.this .destroyPool();
0954: throw sqle;
0955: }
0956: }
0957:
0958: public void setFetchSize(int rows)
0959: throws java.sql.SQLException {
0960: try {
0961: theStatement.setFetchSize(rows);
0962: } catch (SQLException sqle) {
0963: PoolConnection.this .destroyPool();
0964: throw sqle;
0965: }
0966: }
0967:
0968: public java.sql.ResultSet executeQuery(
0969: java.lang.String arg0)
0970: throws java.sql.SQLException {
0971: java.sql.ResultSet rs = null;
0972: try {
0973: rs = theStatement.executeQuery(arg0);
0974: } catch (SQLException sqle) {
0975: PoolConnection.this .destroyPool();
0976: throw sqle;
0977: }
0978: return rs;
0979: }
0980:
0981: public int executeUpdate(java.lang.String arg0)
0982: throws java.sql.SQLException {
0983: int i;
0984: try {
0985: i = theStatement.executeUpdate(arg0);
0986: } catch (SQLException sqle) {
0987: PoolConnection.this .destroyPool();
0988: throw sqle;
0989: }
0990: return i;
0991: }
0992:
0993: public void close() throws java.sql.SQLException {
0994: try {
0995: closeStatement(this );
0996: } catch (SQLException sqle) {
0997: PoolConnection.this .destroyPool();
0998: throw sqle;
0999: }
1000: }
1001:
1002: public int getMaxFieldSize()
1003: throws java.sql.SQLException {
1004: int i;
1005: try {
1006: i = theStatement.getMaxFieldSize();
1007: } catch (SQLException sqle) {
1008: PoolConnection.this .destroyPool();
1009: throw sqle;
1010: }
1011: return i;
1012: }
1013:
1014: public void setMaxFieldSize(int arg0)
1015: throws java.sql.SQLException {
1016: try {
1017: theStatement.setMaxFieldSize(arg0);
1018: } catch (SQLException sqle) {
1019: PoolConnection.this .destroyPool();
1020: throw sqle;
1021: }
1022: }
1023:
1024: public int getMaxRows() throws java.sql.SQLException {
1025: int i;
1026: try {
1027: i = theStatement.getMaxRows();
1028: } catch (SQLException sqle) {
1029: PoolConnection.this .destroyPool();
1030: throw sqle;
1031: }
1032: return i;
1033: }
1034:
1035: public void setMaxRows(int arg0)
1036: throws java.sql.SQLException {
1037: try {
1038: theStatement.setMaxRows(arg0);
1039: } catch (SQLException sqle) {
1040: PoolConnection.this .destroyPool();
1041: throw sqle;
1042: }
1043: }
1044:
1045: public void setEscapeProcessing(boolean arg0)
1046: throws java.sql.SQLException {
1047: try {
1048: theStatement.setEscapeProcessing(arg0);
1049: } catch (SQLException sqle) {
1050: PoolConnection.this .destroyPool();
1051: throw sqle;
1052: }
1053: }
1054:
1055: public int getQueryTimeout()
1056: throws java.sql.SQLException {
1057: int i;
1058: try {
1059: i = theStatement.getQueryTimeout();
1060: } catch (SQLException sqle) {
1061: PoolConnection.this .destroyPool();
1062: throw sqle;
1063: }
1064: return i;
1065: }
1066:
1067: public void setQueryTimeout(int arg0)
1068: throws java.sql.SQLException {
1069: try {
1070: theStatement.setQueryTimeout(arg0);
1071: } catch (SQLException sqle) {
1072: PoolConnection.this .destroyPool();
1073: throw sqle;
1074: }
1075: }
1076:
1077: public void cancel() throws java.sql.SQLException {
1078: try {
1079: theStatement.cancel();
1080: } catch (SQLException sqle) {
1081: PoolConnection.this .destroyPool();
1082: throw sqle;
1083: }
1084: }
1085:
1086: public java.sql.SQLWarning getWarnings()
1087: throws java.sql.SQLException {
1088: java.sql.SQLWarning warn = null;
1089: try {
1090: warn = theStatement.getWarnings();
1091: } catch (SQLException sqle) {
1092: PoolConnection.this .destroyPool();
1093: throw sqle;
1094: }
1095: return warn;
1096: }
1097:
1098: public void clearWarnings()
1099: throws java.sql.SQLException {
1100: try {
1101: theStatement.clearWarnings();
1102: } catch (SQLException sqle) {
1103: PoolConnection.this .destroyPool();
1104: throw sqle;
1105: }
1106: }
1107:
1108: public void setCursorName(java.lang.String arg0)
1109: throws java.sql.SQLException {
1110: try {
1111: theStatement.setCursorName(arg0);
1112: } catch (SQLException sqle) {
1113: PoolConnection.this .destroyPool();
1114: throw sqle;
1115: }
1116: }
1117:
1118: public boolean execute(java.lang.String arg0)
1119: throws java.sql.SQLException {
1120: boolean b;
1121: try {
1122: b = theStatement.execute(arg0);
1123: } catch (SQLException sqle) {
1124: PoolConnection.this .destroyPool();
1125: throw sqle;
1126: }
1127: return b;
1128: }
1129:
1130: public java.sql.ResultSet getResultSet()
1131: throws java.sql.SQLException {
1132: java.sql.ResultSet rs = null;
1133: try {
1134: rs = theStatement.getResultSet();
1135: } catch (SQLException sqle) {
1136: PoolConnection.this .destroyPool();
1137: throw sqle;
1138: }
1139: return rs;
1140: }
1141:
1142: public int getUpdateCount()
1143: throws java.sql.SQLException {
1144: int i;
1145: try {
1146: i = theStatement.getUpdateCount();
1147: } catch (SQLException sqle) {
1148: PoolConnection.this .destroyPool();
1149: throw sqle;
1150: }
1151: return i;
1152: }
1153:
1154: public boolean getMoreResults()
1155: throws java.sql.SQLException {
1156: boolean b;
1157: try {
1158: b = theStatement.getMoreResults();
1159: } catch (SQLException sqle) {
1160: PoolConnection.this .destroyPool();
1161: throw sqle;
1162: }
1163: return b;
1164: }
1165:
1166: // begin jdk 1.4 compatability
1167: public boolean getMoreResults(int current)
1168: throws java.sql.SQLException {
1169: try {
1170: return theStatement.getMoreResults(current);
1171: } catch (SQLException sqle) {
1172: PoolConnection.this .destroyPool();
1173: throw sqle;
1174: }
1175: }
1176:
1177: public ResultSet getGeneratedKeys()
1178: throws java.sql.SQLException {
1179: try {
1180: return theStatement.getGeneratedKeys();
1181: } catch (SQLException sqle) {
1182: PoolConnection.this .destroyPool();
1183: throw sqle;
1184: }
1185: }
1186:
1187: public int executeUpdate(String sql, int agk)
1188: throws java.sql.SQLException {
1189: try {
1190: return theStatement.executeUpdate(sql, agk);
1191: } catch (SQLException sqle) {
1192: PoolConnection.this .destroyPool();
1193: throw sqle;
1194: }
1195: }
1196:
1197: public int executeUpdate(String sql, int ci[])
1198: throws java.sql.SQLException {
1199: try {
1200: return theStatement.executeUpdate(sql, ci);
1201: } catch (SQLException sqle) {
1202: PoolConnection.this .destroyPool();
1203: throw sqle;
1204: }
1205: }
1206:
1207: public int executeUpdate(String sql, String cn[])
1208: throws java.sql.SQLException {
1209: try {
1210: return theStatement.executeUpdate(sql, cn);
1211: } catch (SQLException sqle) {
1212: PoolConnection.this .destroyPool();
1213: throw sqle;
1214: }
1215: }
1216:
1217: public boolean execute(String sql, int agk)
1218: throws java.sql.SQLException {
1219: try {
1220: return theStatement.execute(sql, agk);
1221: } catch (SQLException sqle) {
1222: PoolConnection.this .destroyPool();
1223: throw sqle;
1224: }
1225: }
1226:
1227: public boolean execute(String sql, int ci[])
1228: throws java.sql.SQLException {
1229: try {
1230: return theStatement.execute(sql, ci);
1231: } catch (SQLException sqle) {
1232: PoolConnection.this .destroyPool();
1233: throw sqle;
1234: }
1235: }
1236:
1237: public boolean execute(String sql, String cn[])
1238: throws java.sql.SQLException {
1239: try {
1240: return theStatement.execute(sql, cn);
1241: } catch (SQLException sqle) {
1242: PoolConnection.this .destroyPool();
1243: throw sqle;
1244: }
1245: }
1246:
1247: public int getResultSetHoldability()
1248: throws java.sql.SQLException {
1249: try {
1250: return theStatement.getResultSetHoldability();
1251: } catch (SQLException sqle) {
1252: PoolConnection.this .destroyPool();
1253: throw sqle;
1254: }
1255: }
1256: // end jdk 1.4 compatability
1257: }
1258:
1259: /**
1260: * A wrapper for a PreparedStatement object. All operations are
1261: * delegated to the wrapped object. The close operation in the
1262: * base class goes through the PoolConnection wrapper to keep
1263: * track of which statements have been closed and which haven't.
1264: */
1265: class PoolPreparedStatement extends PoolStatement implements
1266: java.sql.PreparedStatement {
1267: private java.sql.PreparedStatement thePreparedStatement;
1268:
1269: public PoolPreparedStatement(
1270: java.sql.PreparedStatement thePreparedStatement) {
1271: super (thePreparedStatement);
1272: this .thePreparedStatement = thePreparedStatement;
1273: }
1274:
1275: public void addBatch() throws java.sql.SQLException {
1276: try {
1277: thePreparedStatement.addBatch();
1278: } catch (SQLException sqle) {
1279: PoolConnection.this .destroyPool();
1280: throw sqle;
1281: }
1282: }
1283:
1284: public ResultSetMetaData getMetaData()
1285: throws java.sql.SQLException {
1286: ResultSetMetaData data = null;
1287: try {
1288: data = thePreparedStatement.getMetaData();
1289: } catch (SQLException sqle) {
1290: PoolConnection.this .destroyPool();
1291: throw sqle;
1292: }
1293: return data;
1294: }
1295:
1296: public void setArray(int i, Array x)
1297: throws java.sql.SQLException {
1298: try {
1299: thePreparedStatement.setArray(i, x);
1300: } catch (SQLException sqle) {
1301: PoolConnection.this .destroyPool();
1302: throw sqle;
1303: }
1304: }
1305:
1306: public void setBlob(int i, Blob x)
1307: throws java.sql.SQLException {
1308: try {
1309: thePreparedStatement.setBlob(i, x);
1310: } catch (SQLException sqle) {
1311: PoolConnection.this .destroyPool();
1312: throw sqle;
1313: }
1314: }
1315:
1316: public void setCharacterStream(int paramIndex,
1317: java.io.Reader reader, int length)
1318: throws java.sql.SQLException {
1319: try {
1320: thePreparedStatement.setCharacterStream(
1321: paramIndex, reader, length);
1322: } catch (SQLException sqle) {
1323: PoolConnection.this .destroyPool();
1324: throw sqle;
1325: }
1326: }
1327:
1328: public void setClob(int i, Clob x)
1329: throws java.sql.SQLException {
1330: try {
1331: thePreparedStatement.setClob(i, x);
1332: } catch (SQLException sqle) {
1333: PoolConnection.this .destroyPool();
1334: throw sqle;
1335: }
1336: }
1337:
1338: public void setRef(int i, Ref x)
1339: throws java.sql.SQLException {
1340: try {
1341: thePreparedStatement.setRef(i, x);
1342: } catch (SQLException sqle) {
1343: PoolConnection.this .destroyPool();
1344: throw sqle;
1345: }
1346: }
1347:
1348: public void setDate(int i, java.sql.Date myDate,
1349: Calendar cal) throws java.sql.SQLException {
1350: try {
1351: thePreparedStatement.setDate(i, myDate, cal);
1352: } catch (SQLException sqle) {
1353: PoolConnection.this .destroyPool();
1354: throw sqle;
1355: }
1356: }
1357:
1358: public void setTime(int paramIndex, Time x, Calendar cal)
1359: throws java.sql.SQLException {
1360: try {
1361: thePreparedStatement
1362: .setTime(paramIndex, x, cal);
1363: } catch (SQLException sqle) {
1364: PoolConnection.this .destroyPool();
1365: throw sqle;
1366: }
1367: }
1368:
1369: public void setTimestamp(int paramIndex,
1370: java.sql.Timestamp x, Calendar cal)
1371: throws java.sql.SQLException {
1372: try {
1373: thePreparedStatement.setTimestamp(paramIndex,
1374: x, cal);
1375: } catch (SQLException sqle) {
1376: PoolConnection.this .destroyPool();
1377: throw sqle;
1378: }
1379: }
1380:
1381: public java.sql.ResultSet executeQuery()
1382: throws java.sql.SQLException {
1383: java.sql.ResultSet rs = null;
1384: try {
1385: rs = thePreparedStatement.executeQuery();
1386: } catch (SQLException sqle) {
1387: PoolConnection.this .destroyPool();
1388: throw sqle;
1389: }
1390: return rs;
1391: }
1392:
1393: public int executeUpdate() throws java.sql.SQLException {
1394: int i;
1395: try {
1396: i = thePreparedStatement.executeUpdate();
1397: } catch (SQLException sqle) {
1398: PoolConnection.this .destroyPool();
1399: throw sqle;
1400: }
1401: return i;
1402: }
1403:
1404: public void setNull(int arg0, int arg1)
1405: throws java.sql.SQLException {
1406: try {
1407: thePreparedStatement.setNull(arg0, arg1);
1408: } catch (SQLException sqle) {
1409: PoolConnection.this .destroyPool();
1410: throw sqle;
1411: }
1412: }
1413:
1414: public void setNull(int arg0, int arg1, String typeName)
1415: throws java.sql.SQLException {
1416: try {
1417: thePreparedStatement.setNull(arg0, arg1,
1418: typeName);
1419: } catch (SQLException sqle) {
1420: PoolConnection.this .destroyPool();
1421: throw sqle;
1422: }
1423: }
1424:
1425: public void setBoolean(int arg0, boolean arg1)
1426: throws java.sql.SQLException {
1427: try {
1428: thePreparedStatement.setBoolean(arg0, arg1);
1429: } catch (SQLException sqle) {
1430: PoolConnection.this .destroyPool();
1431: throw sqle;
1432: }
1433: }
1434:
1435: public void setByte(int arg0, byte arg1)
1436: throws java.sql.SQLException {
1437: try {
1438: thePreparedStatement.setByte(arg0, arg1);
1439: } catch (SQLException sqle) {
1440: PoolConnection.this .destroyPool();
1441: throw sqle;
1442: }
1443: }
1444:
1445: public void setShort(int arg0, short arg1)
1446: throws java.sql.SQLException {
1447: try {
1448: thePreparedStatement.setShort(arg0, arg1);
1449: } catch (SQLException sqle) {
1450: PoolConnection.this .destroyPool();
1451: throw sqle;
1452: }
1453: }
1454:
1455: public void setInt(int arg0, int arg1)
1456: throws java.sql.SQLException {
1457: try {
1458: thePreparedStatement.setInt(arg0, arg1);
1459: } catch (SQLException sqle) {
1460: PoolConnection.this .destroyPool();
1461: throw sqle;
1462: }
1463: }
1464:
1465: public void setLong(int arg0, long arg1)
1466: throws java.sql.SQLException {
1467: try {
1468: thePreparedStatement.setLong(arg0, arg1);
1469: } catch (SQLException sqle) {
1470: PoolConnection.this .destroyPool();
1471: throw sqle;
1472: }
1473: }
1474:
1475: public void setFloat(int arg0, float arg1)
1476: throws java.sql.SQLException {
1477: try {
1478: thePreparedStatement.setFloat(arg0, arg1);
1479: } catch (SQLException sqle) {
1480: PoolConnection.this .destroyPool();
1481: throw sqle;
1482: }
1483: }
1484:
1485: public void setDouble(int arg0, double arg1)
1486: throws java.sql.SQLException {
1487: try {
1488: thePreparedStatement.setDouble(arg0, arg1);
1489: } catch (SQLException sqle) {
1490: PoolConnection.this .destroyPool();
1491: throw sqle;
1492: }
1493: }
1494:
1495: public void setBigDecimal(int arg0,
1496: java.math.BigDecimal arg1)
1497: throws java.sql.SQLException {
1498: try {
1499: thePreparedStatement.setBigDecimal(arg0, arg1);
1500: } catch (SQLException sqle) {
1501: PoolConnection.this .destroyPool();
1502: throw sqle;
1503: }
1504: }
1505:
1506: public void setString(int arg0, java.lang.String arg1)
1507: throws java.sql.SQLException {
1508: try {
1509: thePreparedStatement.setString(arg0, arg1);
1510: } catch (SQLException sqle) {
1511: PoolConnection.this .destroyPool();
1512: throw sqle;
1513: }
1514: }
1515:
1516: public void setBytes(int arg0, byte[] arg1)
1517: throws java.sql.SQLException {
1518: try {
1519: thePreparedStatement.setBytes(arg0, arg1);
1520: } catch (SQLException sqle) {
1521: PoolConnection.this .destroyPool();
1522: throw sqle;
1523: }
1524: }
1525:
1526: public void setDate(int arg0, java.sql.Date arg1)
1527: throws java.sql.SQLException {
1528: try {
1529: thePreparedStatement.setDate(arg0, arg1);
1530: } catch (SQLException sqle) {
1531: PoolConnection.this .destroyPool();
1532: throw sqle;
1533: }
1534: }
1535:
1536: public void setTime(int arg0, java.sql.Time arg1)
1537: throws java.sql.SQLException {
1538: try {
1539: thePreparedStatement.setTime(arg0, arg1);
1540: } catch (SQLException sqle) {
1541: PoolConnection.this .destroyPool();
1542: throw sqle;
1543: }
1544: }
1545:
1546: public void setTimestamp(int arg0,
1547: java.sql.Timestamp arg1)
1548: throws java.sql.SQLException {
1549: try {
1550: thePreparedStatement.setTimestamp(arg0, arg1);
1551: } catch (SQLException sqle) {
1552: PoolConnection.this .destroyPool();
1553: throw sqle;
1554: }
1555: }
1556:
1557: public void setAsciiStream(int arg0,
1558: java.io.InputStream arg1, int arg2)
1559: throws java.sql.SQLException {
1560: try {
1561: thePreparedStatement.setAsciiStream(arg0, arg1,
1562: arg2);
1563: } catch (SQLException sqle) {
1564: PoolConnection.this .destroyPool();
1565: throw sqle;
1566: }
1567: }
1568:
1569: /**
1570: * @deprecated
1571: **/
1572: public void setUnicodeStream(int arg0,
1573: java.io.InputStream arg1, int arg2)
1574: throws java.sql.SQLException {
1575: throw new java.sql.SQLException(
1576: "Method not supported");
1577: // thePreparedStatement.setUnicodeStream(arg0, arg1, arg2);
1578: }
1579:
1580: public void setBinaryStream(int arg0,
1581: java.io.InputStream arg1, int arg2)
1582: throws java.sql.SQLException {
1583: try {
1584: thePreparedStatement.setBinaryStream(arg0,
1585: arg1, arg2);
1586: } catch (SQLException sqle) {
1587: PoolConnection.this .destroyPool();
1588: throw sqle;
1589: }
1590: }
1591:
1592: public void clearParameters()
1593: throws java.sql.SQLException {
1594: try {
1595: thePreparedStatement.clearParameters();
1596: } catch (SQLException sqle) {
1597: PoolConnection.this .destroyPool();
1598: throw sqle;
1599: }
1600: }
1601:
1602: public void setObject(int arg0, java.lang.Object arg1,
1603: int arg2, int arg3)
1604: throws java.sql.SQLException {
1605: try {
1606: thePreparedStatement.setObject(arg0, arg1,
1607: arg2, arg3);
1608: } catch (SQLException sqle) {
1609: PoolConnection.this .destroyPool();
1610: throw sqle;
1611: }
1612: }
1613:
1614: public void setObject(int arg0, java.lang.Object arg1,
1615: int arg2) throws java.sql.SQLException {
1616: try {
1617: thePreparedStatement
1618: .setObject(arg0, arg1, arg2);
1619: } catch (SQLException sqle) {
1620: PoolConnection.this .destroyPool();
1621: throw sqle;
1622: }
1623: }
1624:
1625: public void setObject(int arg0, java.lang.Object arg1)
1626: throws java.sql.SQLException {
1627: try {
1628: thePreparedStatement.setObject(arg0, arg1);
1629: } catch (SQLException sqle) {
1630: PoolConnection.this .destroyPool();
1631: throw sqle;
1632: }
1633: }
1634:
1635: public boolean execute() throws java.sql.SQLException {
1636: boolean b;
1637: try {
1638: b = thePreparedStatement.execute();
1639: } catch (SQLException sqle) {
1640: PoolConnection.this .destroyPool();
1641: throw sqle;
1642: }
1643: return b;
1644: }
1645:
1646: // begin jdk 1.4 compatability
1647: public void setURL(int param, URL x)
1648: throws java.sql.SQLException {
1649: try {
1650: thePreparedStatement.setURL(param, x);
1651: } catch (SQLException sqle) {
1652: PoolConnection.this .destroyPool();
1653: throw sqle;
1654: }
1655: }
1656:
1657: public ParameterMetaData getParameterMetaData()
1658: throws java.sql.SQLException {
1659: try {
1660: return thePreparedStatement
1661: .getParameterMetaData();
1662: } catch (SQLException sqle) {
1663: PoolConnection.this .destroyPool();
1664: throw sqle;
1665: }
1666: }
1667: // end jdk 1.4 compatability
1668:
1669: }
1670:
1671: /**
1672: * A wrapper for a CallableStatement object. All operations are
1673: * delegated to the wrapped object. The close operation in the
1674: * base class goes through the PoolConnection wrapper to keep
1675: * track of which statements have been closed and which haven't.
1676: */
1677: class PoolCallableStatement extends PoolPreparedStatement
1678: implements java.sql.CallableStatement {
1679: private java.sql.CallableStatement theCallableStatement;
1680:
1681: public PoolCallableStatement(
1682: java.sql.CallableStatement theCallableStatement) {
1683: super (theCallableStatement);
1684: this .theCallableStatement = theCallableStatement;
1685: }
1686:
1687: public Array getArray(int i)
1688: throws java.sql.SQLException {
1689: Array a = null;
1690: try {
1691: a = theCallableStatement.getArray(i);
1692: } catch (SQLException sqle) {
1693: PoolConnection.this .destroyPool();
1694: throw sqle;
1695: }
1696: return a;
1697: }
1698:
1699: /** @deprecated **/
1700: public java.math.BigDecimal getBigDecimal(int paramIndex)
1701: throws java.sql.SQLException {
1702: java.math.BigDecimal bd;
1703: try {
1704: bd = theCallableStatement
1705: .getBigDecimal(paramIndex);
1706: } catch (SQLException sqle) {
1707: PoolConnection.this .destroyPool();
1708: throw sqle;
1709: }
1710: return bd;
1711: }
1712:
1713: public Blob getBlob(int i) throws java.sql.SQLException {
1714: Blob b = null;
1715: try {
1716: b = theCallableStatement.getBlob(i);
1717: } catch (SQLException sqle) {
1718: PoolConnection.this .destroyPool();
1719: throw sqle;
1720: }
1721: return b;
1722: }
1723:
1724: public Clob getClob(int i) throws java.sql.SQLException {
1725: Clob c = null;
1726: try {
1727: c = theCallableStatement.getClob(i);
1728: } catch (SQLException sqle) {
1729: PoolConnection.this .destroyPool();
1730: throw sqle;
1731: }
1732: return c;
1733: }
1734:
1735: public java.sql.Date getDate(int paramIndex,
1736: Calendar cal) throws java.sql.SQLException {
1737: java.sql.Date d = null;
1738: try {
1739: d = theCallableStatement.getDate(paramIndex,
1740: cal);
1741: } catch (SQLException sqle) {
1742: PoolConnection.this .destroyPool();
1743: throw sqle;
1744: }
1745: return d;
1746: }
1747:
1748: public Object getObject(int i, Map map)
1749: throws java.sql.SQLException {
1750: Object o = null;
1751: try {
1752: o = theCallableStatement.getObject(i, map);
1753: } catch (SQLException sqle) {
1754: PoolConnection.this .destroyPool();
1755: throw sqle;
1756: }
1757: return o;
1758: }
1759:
1760: public Ref getRef(int i) throws java.sql.SQLException {
1761: Ref r = null;
1762: try {
1763: r = theCallableStatement.getRef(i);
1764: } catch (SQLException sqle) {
1765: PoolConnection.this .destroyPool();
1766: throw sqle;
1767: }
1768: return r;
1769: }
1770:
1771: public Time getTime(int paramIndex, Calendar cal)
1772: throws java.sql.SQLException {
1773: Time t = null;
1774: try {
1775: t = theCallableStatement.getTime(paramIndex,
1776: cal);
1777: } catch (SQLException sqle) {
1778: PoolConnection.this .destroyPool();
1779: throw sqle;
1780: }
1781: return t;
1782: }
1783:
1784: public Timestamp getTimestamp(int paramIndex,
1785: Calendar cal) throws java.sql.SQLException {
1786: Timestamp ts = null;
1787: try {
1788: ts = theCallableStatement.getTimestamp(
1789: paramIndex, cal);
1790: } catch (SQLException sqle) {
1791: PoolConnection.this .destroyPool();
1792: throw sqle;
1793: }
1794: return ts;
1795: }
1796:
1797: public void registerOutParameter(int paramIndex,
1798: int sqlType, String typeName)
1799: throws java.sql.SQLException {
1800: try {
1801: theCallableStatement.registerOutParameter(
1802: paramIndex, sqlType, typeName);
1803: } catch (SQLException sqle) {
1804: PoolConnection.this .destroyPool();
1805: throw sqle;
1806: }
1807: }
1808:
1809: public void registerOutParameter(int arg0, int arg1)
1810: throws java.sql.SQLException {
1811: try {
1812: theCallableStatement.registerOutParameter(arg0,
1813: arg1);
1814: } catch (SQLException sqle) {
1815: PoolConnection.this .destroyPool();
1816: throw sqle;
1817: }
1818: }
1819:
1820: public void registerOutParameter(int arg0, int arg1,
1821: int arg2) throws java.sql.SQLException {
1822: try {
1823: theCallableStatement.registerOutParameter(arg0,
1824: arg1, arg2);
1825: } catch (SQLException sqle) {
1826: PoolConnection.this .destroyPool();
1827: throw sqle;
1828: }
1829: }
1830:
1831: public boolean wasNull() throws java.sql.SQLException {
1832: boolean b;
1833: try {
1834: b = theCallableStatement.wasNull();
1835: } catch (SQLException sqle) {
1836: PoolConnection.this .destroyPool();
1837: throw sqle;
1838: }
1839: return b;
1840: }
1841:
1842: public java.lang.String getString(int arg0)
1843: throws java.sql.SQLException {
1844: java.lang.String str = null;
1845: try {
1846: str = theCallableStatement.getString(arg0);
1847: } catch (SQLException sqle) {
1848: PoolConnection.this .destroyPool();
1849: throw sqle;
1850: }
1851: return str;
1852: }
1853:
1854: public boolean getBoolean(int arg0)
1855: throws java.sql.SQLException {
1856: boolean b;
1857: try {
1858: b = theCallableStatement.getBoolean(arg0);
1859: } catch (SQLException sqle) {
1860: PoolConnection.this .destroyPool();
1861: throw sqle;
1862: }
1863: return b;
1864: }
1865:
1866: public byte getByte(int arg0)
1867: throws java.sql.SQLException {
1868: byte b;
1869: try {
1870: b = theCallableStatement.getByte(arg0);
1871: } catch (SQLException sqle) {
1872: PoolConnection.this .destroyPool();
1873: throw sqle;
1874: }
1875: return b;
1876: }
1877:
1878: public short getShort(int arg0)
1879: throws java.sql.SQLException {
1880: short s;
1881: try {
1882: s = theCallableStatement.getShort(arg0);
1883: } catch (SQLException sqle) {
1884: PoolConnection.this .destroyPool();
1885: throw sqle;
1886: }
1887: return s;
1888: }
1889:
1890: public int getInt(int arg0)
1891: throws java.sql.SQLException {
1892: int i;
1893: try {
1894: i = theCallableStatement.getInt(arg0);
1895: } catch (SQLException sqle) {
1896: PoolConnection.this .destroyPool();
1897: throw sqle;
1898: }
1899: return i;
1900: }
1901:
1902: public long getLong(int arg0)
1903: throws java.sql.SQLException {
1904: long l;
1905: try {
1906: l = theCallableStatement.getLong(arg0);
1907: } catch (SQLException sqle) {
1908: PoolConnection.this .destroyPool();
1909: throw sqle;
1910: }
1911: return l;
1912: }
1913:
1914: public float getFloat(int arg0)
1915: throws java.sql.SQLException {
1916: float f;
1917: try {
1918: f = theCallableStatement.getFloat(arg0);
1919: } catch (SQLException sqle) {
1920: PoolConnection.this .destroyPool();
1921: throw sqle;
1922: }
1923: return f;
1924: }
1925:
1926: public double getDouble(int arg0)
1927: throws java.sql.SQLException {
1928: double d;
1929: try {
1930: d = theCallableStatement.getDouble(arg0);
1931: } catch (SQLException sqle) {
1932: PoolConnection.this .destroyPool();
1933: throw sqle;
1934: }
1935: return d;
1936: }
1937:
1938: /** @deprecated **/
1939: public java.math.BigDecimal getBigDecimal(int arg0,
1940: int arg1) throws java.sql.SQLException {
1941: try {
1942: return theCallableStatement.getBigDecimal(arg0,
1943: arg1);
1944: } catch (SQLException sqle) {
1945: PoolConnection.this .destroyPool();
1946: throw sqle;
1947: }
1948: }
1949:
1950: public byte[] getBytes(int arg0)
1951: throws java.sql.SQLException {
1952: byte[] b;
1953: try {
1954: b = theCallableStatement.getBytes(arg0);
1955: } catch (SQLException sqle) {
1956: PoolConnection.this .destroyPool();
1957: throw sqle;
1958: }
1959: return b;
1960: }
1961:
1962: public java.sql.Date getDate(int arg0)
1963: throws java.sql.SQLException {
1964: java.sql.Date date = null;
1965: try {
1966: date = theCallableStatement.getDate(arg0);
1967: } catch (SQLException sqle) {
1968: PoolConnection.this .destroyPool();
1969: throw sqle;
1970: }
1971: return date;
1972: }
1973:
1974: public java.sql.Time getTime(int arg0)
1975: throws java.sql.SQLException {
1976: java.sql.Time time = null;
1977: try {
1978: time = theCallableStatement.getTime(arg0);
1979: } catch (SQLException sqle) {
1980: PoolConnection.this .destroyPool();
1981: throw sqle;
1982: }
1983: return time;
1984: }
1985:
1986: public java.sql.Timestamp getTimestamp(int arg0)
1987: throws java.sql.SQLException {
1988: java.sql.Timestamp ts = null;
1989: try {
1990: ts = theCallableStatement.getTimestamp(arg0);
1991: } catch (SQLException sqle) {
1992: PoolConnection.this .destroyPool();
1993: throw sqle;
1994: }
1995: return ts;
1996: }
1997:
1998: public java.lang.Object getObject(int arg0)
1999: throws java.sql.SQLException {
2000: java.lang.Object o = null;
2001: try {
2002: o = theCallableStatement.getObject(arg0);
2003: } catch (SQLException sqle) {
2004: PoolConnection.this .destroyPool();
2005: throw sqle;
2006: }
2007: return o;
2008: }
2009:
2010: // begin jdk 1.4 compatability
2011: public void registerOutParameter(String pn, int sqltype)
2012: throws java.sql.SQLException {
2013: try {
2014: theCallableStatement.registerOutParameter(pn,
2015: sqltype);
2016: } catch (SQLException sqle) {
2017: PoolConnection.this .destroyPool();
2018: throw sqle;
2019: }
2020: }
2021:
2022: public void registerOutParameter(String pn,
2023: int sqltype, int scale)
2024: throws java.sql.SQLException {
2025: try {
2026: theCallableStatement.registerOutParameter(pn,
2027: sqltype, scale);
2028: } catch (SQLException sqle) {
2029: PoolConnection.this .destroyPool();
2030: throw sqle;
2031: }
2032: }
2033:
2034: public void registerOutParameter(String pn,
2035: int sqltype, String tn)
2036: throws java.sql.SQLException {
2037: try {
2038: theCallableStatement.registerOutParameter(pn,
2039: sqltype, tn);
2040: } catch (SQLException sqle) {
2041: PoolConnection.this .destroyPool();
2042: throw sqle;
2043: }
2044: }
2045:
2046: public URL getURL(int pi) throws java.sql.SQLException {
2047: try {
2048: return theCallableStatement.getURL(pi);
2049: } catch (SQLException sqle) {
2050: PoolConnection.this .destroyPool();
2051: throw sqle;
2052: }
2053: }
2054:
2055: public void setURL(String pn, URL v)
2056: throws java.sql.SQLException {
2057: try {
2058: theCallableStatement.setURL(pn, v);
2059: } catch (SQLException sqle) {
2060: PoolConnection.this .destroyPool();
2061: throw sqle;
2062: }
2063: }
2064:
2065: public void setNull(String pn, int sqlt)
2066: throws java.sql.SQLException {
2067: try {
2068: theCallableStatement.setNull(pn, sqlt);
2069: } catch (SQLException sqle) {
2070: PoolConnection.this .destroyPool();
2071: throw sqle;
2072: }
2073: }
2074:
2075: public void setBoolean(String pn, boolean x)
2076: throws java.sql.SQLException {
2077: try {
2078: theCallableStatement.setBoolean(pn, x);
2079: } catch (SQLException sqle) {
2080: PoolConnection.this .destroyPool();
2081: throw sqle;
2082: }
2083: }
2084:
2085: public void setByte(String pn, byte x)
2086: throws java.sql.SQLException {
2087: try {
2088: theCallableStatement.setByte(pn, x);
2089: } catch (SQLException sqle) {
2090: PoolConnection.this .destroyPool();
2091: throw sqle;
2092: }
2093: }
2094:
2095: public void setShort(String pn, short x)
2096: throws java.sql.SQLException {
2097: try {
2098: theCallableStatement.setShort(pn, x);
2099: } catch (SQLException sqle) {
2100: PoolConnection.this .destroyPool();
2101: throw sqle;
2102: }
2103: }
2104:
2105: public void setInt(String pn, int x)
2106: throws java.sql.SQLException {
2107: try {
2108: theCallableStatement.setInt(pn, x);
2109: } catch (SQLException sqle) {
2110: PoolConnection.this .destroyPool();
2111: throw sqle;
2112: }
2113: }
2114:
2115: public void setLong(String pn, long x)
2116: throws java.sql.SQLException {
2117: try {
2118: theCallableStatement.setLong(pn, x);
2119: } catch (SQLException sqle) {
2120: PoolConnection.this .destroyPool();
2121: throw sqle;
2122: }
2123: }
2124:
2125: public void setFloat(String pn, float x)
2126: throws java.sql.SQLException {
2127: try {
2128: theCallableStatement.setFloat(pn, x);
2129: } catch (SQLException sqle) {
2130: PoolConnection.this .destroyPool();
2131: throw sqle;
2132: }
2133: }
2134:
2135: public void setDouble(String pn, double x)
2136: throws java.sql.SQLException {
2137: try {
2138: theCallableStatement.setDouble(pn, x);
2139: } catch (SQLException sqle) {
2140: PoolConnection.this .destroyPool();
2141: throw sqle;
2142: }
2143: }
2144:
2145: public void setBigDecimal(String pn, BigDecimal x)
2146: throws java.sql.SQLException {
2147: try {
2148: theCallableStatement.setBigDecimal(pn, x);
2149: } catch (SQLException sqle) {
2150: PoolConnection.this .destroyPool();
2151: throw sqle;
2152: }
2153: }
2154:
2155: public void setString(String pn, String x)
2156: throws java.sql.SQLException {
2157: try {
2158: theCallableStatement.setString(pn, x);
2159: } catch (SQLException sqle) {
2160: PoolConnection.this .destroyPool();
2161: throw sqle;
2162: }
2163: }
2164:
2165: public void setBytes(String pn, byte[] x)
2166: throws java.sql.SQLException {
2167: try {
2168: theCallableStatement.setBytes(pn, x);
2169: } catch (SQLException sqle) {
2170: PoolConnection.this .destroyPool();
2171: throw sqle;
2172: }
2173: }
2174:
2175: public void setDate(String pn, java.sql.Date x)
2176: throws java.sql.SQLException {
2177: try {
2178: theCallableStatement.setDate(pn, x);
2179: } catch (SQLException sqle) {
2180: PoolConnection.this .destroyPool();
2181: throw sqle;
2182: }
2183: }
2184:
2185: public void setTime(String pn, Time x)
2186: throws java.sql.SQLException {
2187: try {
2188: theCallableStatement.setTime(pn, x);
2189: } catch (SQLException sqle) {
2190: PoolConnection.this .destroyPool();
2191: throw sqle;
2192: }
2193: }
2194:
2195: public void setTimestamp(String pn, Timestamp x)
2196: throws java.sql.SQLException {
2197: try {
2198: theCallableStatement.setTimestamp(pn, x);
2199: } catch (SQLException sqle) {
2200: PoolConnection.this .destroyPool();
2201: throw sqle;
2202: }
2203: }
2204:
2205: public void setAsciiStream(String pn, InputStream x,
2206: int l) throws java.sql.SQLException {
2207: try {
2208: theCallableStatement.setAsciiStream(pn, x, l);
2209: } catch (SQLException sqle) {
2210: PoolConnection.this .destroyPool();
2211: throw sqle;
2212: }
2213: }
2214:
2215: public void setBinaryStream(String pn, InputStream x,
2216: int l) throws java.sql.SQLException {
2217: try {
2218: theCallableStatement.setBinaryStream(pn, x, l);
2219: } catch (SQLException sqle) {
2220: PoolConnection.this .destroyPool();
2221: throw sqle;
2222: }
2223: }
2224:
2225: public void setObject(String pn, Object x, int tt, int s)
2226: throws java.sql.SQLException {
2227: try {
2228: theCallableStatement.setObject(pn, x, tt, s);
2229: } catch (SQLException sqle) {
2230: PoolConnection.this .destroyPool();
2231: throw sqle;
2232: }
2233: }
2234:
2235: public void setObject(String pn, Object x, int tt)
2236: throws java.sql.SQLException {
2237: try {
2238: theCallableStatement.setObject(pn, x, tt);
2239: } catch (SQLException sqle) {
2240: PoolConnection.this .destroyPool();
2241: throw sqle;
2242: }
2243: }
2244:
2245: public void setObject(String pn, Object x)
2246: throws java.sql.SQLException {
2247: try {
2248: theCallableStatement.setObject(pn, x);
2249: } catch (SQLException sqle) {
2250: PoolConnection.this .destroyPool();
2251: throw sqle;
2252: }
2253: }
2254:
2255: public void setCharacterStream(String pn, Reader x,
2256: int l) throws java.sql.SQLException {
2257: try {
2258: theCallableStatement.setCharacterStream(pn, x,
2259: l);
2260: } catch (SQLException sqle) {
2261: PoolConnection.this .destroyPool();
2262: throw sqle;
2263: }
2264: }
2265:
2266: public void setDate(String pn, java.sql.Date x,
2267: Calendar cal) throws java.sql.SQLException {
2268: try {
2269: theCallableStatement.setDate(pn, x, cal);
2270: } catch (SQLException sqle) {
2271: PoolConnection.this .destroyPool();
2272: throw sqle;
2273: }
2274: }
2275:
2276: public void setTime(String pn, Time x, Calendar cal)
2277: throws java.sql.SQLException {
2278: try {
2279: theCallableStatement.setTime(pn, x, cal);
2280: } catch (SQLException sqle) {
2281: PoolConnection.this .destroyPool();
2282: throw sqle;
2283: }
2284: }
2285:
2286: public void setTimestamp(String pn, Timestamp x,
2287: Calendar cal) throws java.sql.SQLException {
2288: try {
2289: theCallableStatement.setTimestamp(pn, x, cal);
2290: } catch (SQLException sqle) {
2291: PoolConnection.this .destroyPool();
2292: throw sqle;
2293: }
2294: }
2295:
2296: public void setNull(String pn, int st, String tn)
2297: throws java.sql.SQLException {
2298: try {
2299: theCallableStatement.setNull(pn, st, tn);
2300: } catch (SQLException sqle) {
2301: PoolConnection.this .destroyPool();
2302: throw sqle;
2303: }
2304: }
2305:
2306: public String getString(String pn)
2307: throws java.sql.SQLException {
2308: try {
2309: return theCallableStatement.getString(pn);
2310: } catch (SQLException sqle) {
2311: PoolConnection.this .destroyPool();
2312: throw sqle;
2313: }
2314: }
2315:
2316: public boolean getBoolean(String pn)
2317: throws java.sql.SQLException {
2318: try {
2319: return theCallableStatement.getBoolean(pn);
2320: } catch (SQLException sqle) {
2321: PoolConnection.this .destroyPool();
2322: throw sqle;
2323: }
2324: }
2325:
2326: public byte getByte(String pn)
2327: throws java.sql.SQLException {
2328: try {
2329: return theCallableStatement.getByte(pn);
2330: } catch (SQLException sqle) {
2331: PoolConnection.this .destroyPool();
2332: throw sqle;
2333: }
2334: }
2335:
2336: public short getShort(String pn)
2337: throws java.sql.SQLException {
2338: try {
2339: return theCallableStatement.getShort(pn);
2340: } catch (SQLException sqle) {
2341: PoolConnection.this .destroyPool();
2342: throw sqle;
2343: }
2344: }
2345:
2346: public int getInt(String pn)
2347: throws java.sql.SQLException {
2348: try {
2349: return theCallableStatement.getInt(pn);
2350: } catch (SQLException sqle) {
2351: PoolConnection.this .destroyPool();
2352: throw sqle;
2353: }
2354: }
2355:
2356: public long getLong(String pn)
2357: throws java.sql.SQLException {
2358: try {
2359: return theCallableStatement.getLong(pn);
2360: } catch (SQLException sqle) {
2361: PoolConnection.this .destroyPool();
2362: throw sqle;
2363: }
2364: }
2365:
2366: public float getFloat(String pn)
2367: throws java.sql.SQLException {
2368: try {
2369: return theCallableStatement.getFloat(pn);
2370: } catch (SQLException sqle) {
2371: PoolConnection.this .destroyPool();
2372: throw sqle;
2373: }
2374: }
2375:
2376: public double getDouble(String pn)
2377: throws java.sql.SQLException {
2378: try {
2379: return theCallableStatement.getDouble(pn);
2380: } catch (SQLException sqle) {
2381: PoolConnection.this .destroyPool();
2382: throw sqle;
2383: }
2384: }
2385:
2386: public byte[] getBytes(String pn)
2387: throws java.sql.SQLException {
2388: try {
2389: return theCallableStatement.getBytes(pn);
2390: } catch (SQLException sqle) {
2391: PoolConnection.this .destroyPool();
2392: throw sqle;
2393: }
2394: }
2395:
2396: public java.sql.Date getDate(String pn)
2397: throws java.sql.SQLException {
2398: try {
2399: return theCallableStatement.getDate(pn);
2400: } catch (SQLException sqle) {
2401: PoolConnection.this .destroyPool();
2402: throw sqle;
2403: }
2404: }
2405:
2406: public Time getTime(String pn)
2407: throws java.sql.SQLException {
2408: try {
2409: return theCallableStatement.getTime(pn);
2410: } catch (SQLException sqle) {
2411: PoolConnection.this .destroyPool();
2412: throw sqle;
2413: }
2414: }
2415:
2416: public Timestamp getTimestamp(String pn)
2417: throws java.sql.SQLException {
2418: try {
2419: return theCallableStatement.getTimestamp(pn);
2420: } catch (SQLException sqle) {
2421: PoolConnection.this .destroyPool();
2422: throw sqle;
2423: }
2424: }
2425:
2426: public Object getObject(String pn)
2427: throws java.sql.SQLException {
2428: try {
2429: return theCallableStatement.getObject(pn);
2430: } catch (SQLException sqle) {
2431: PoolConnection.this .destroyPool();
2432: throw sqle;
2433: }
2434: }
2435:
2436: public BigDecimal getBigDecimal(String pn)
2437: throws java.sql.SQLException {
2438: try {
2439: return theCallableStatement.getBigDecimal(pn);
2440: } catch (SQLException sqle) {
2441: PoolConnection.this .destroyPool();
2442: throw sqle;
2443: }
2444: }
2445:
2446: public Object getObject(String pn, Map m)
2447: throws java.sql.SQLException {
2448: try {
2449: return theCallableStatement.getObject(pn, m);
2450: } catch (SQLException sqle) {
2451: PoolConnection.this .destroyPool();
2452: throw sqle;
2453: }
2454: }
2455:
2456: public Ref getRef(String pn)
2457: throws java.sql.SQLException {
2458: try {
2459: return theCallableStatement.getRef(pn);
2460: } catch (SQLException sqle) {
2461: PoolConnection.this .destroyPool();
2462: throw sqle;
2463: }
2464: }
2465:
2466: public Blob getBlob(String pn)
2467: throws java.sql.SQLException {
2468: try {
2469: return theCallableStatement.getBlob(pn);
2470: } catch (SQLException sqle) {
2471: PoolConnection.this .destroyPool();
2472: throw sqle;
2473: }
2474: }
2475:
2476: public Clob getClob(String pn)
2477: throws java.sql.SQLException {
2478: try {
2479: return theCallableStatement.getClob(pn);
2480: } catch (SQLException sqle) {
2481: PoolConnection.this .destroyPool();
2482: throw sqle;
2483: }
2484: }
2485:
2486: public Array getArray(String pn)
2487: throws java.sql.SQLException {
2488: try {
2489: return theCallableStatement.getArray(pn);
2490: } catch (SQLException sqle) {
2491: PoolConnection.this .destroyPool();
2492: throw sqle;
2493: }
2494: }
2495:
2496: public java.sql.Date getDate(String pn, Calendar c)
2497: throws java.sql.SQLException {
2498: try {
2499: return theCallableStatement.getDate(pn, c);
2500: } catch (SQLException sqle) {
2501: PoolConnection.this .destroyPool();
2502: throw sqle;
2503: }
2504: }
2505:
2506: public Time getTime(String pn, Calendar c)
2507: throws java.sql.SQLException {
2508: try {
2509: return theCallableStatement.getTime(pn, c);
2510: } catch (SQLException sqle) {
2511: PoolConnection.this .destroyPool();
2512: throw sqle;
2513: }
2514: }
2515:
2516: public Timestamp getTimestamp(String pn, Calendar c)
2517: throws java.sql.SQLException {
2518: try {
2519: return theCallableStatement.getTimestamp(pn, c);
2520: } catch (SQLException sqle) {
2521: PoolConnection.this .destroyPool();
2522: throw sqle;
2523: }
2524: }
2525:
2526: public URL getURL(String pn)
2527: throws java.sql.SQLException {
2528: try {
2529: return theCallableStatement.getURL(pn);
2530: } catch (SQLException sqle) {
2531: PoolConnection.this .destroyPool();
2532: throw sqle;
2533: }
2534: }
2535: // end jdk 1.4 compatability
2536: }
2537: }
2538: }
2539:
2540: /**
2541: * One of the three main functions of this class. This is intended
2542: * as a drop-in replacement for DriverManager.getConnection(). The
2543: * connection return may have been previously used.
2544: */
2545: public static Connection getConnection(String dbURL,
2546: Properties props) throws SQLException {
2547: return getConnection(dbURL, (String) props.get("user"),
2548: (String) props.get("password"));
2549: }
2550:
2551: /**
2552: * One of the three main functions of this class. This is intended
2553: * as a drop-in replacement for DriverManager.getConnection(). The
2554: * connection return may have been previously used.
2555: */
2556: public static Connection getConnection(String dbURL, String user,
2557: String passwd) throws SQLException {
2558: String key = dbURL + SEP + user;
2559: DBConnectionPool pool;
2560: boolean createdPool = false;
2561:
2562: synchronized (dbConnectionPools) {
2563: pool = (DBConnectionPool) dbConnectionPools.get(key);
2564: if (pool == null) {
2565: pool = new DBConnectionPool(key);
2566: dbConnectionPools.put(key, pool);
2567: createdPool = true;
2568: }
2569: }
2570:
2571: if (createdPool) {
2572: ensureTimer();
2573: }
2574:
2575: return pool.findConnection(dbURL, user, passwd);
2576: }
2577:
2578: private static final Object timer_lock = new Object();
2579: private static Thread timer;
2580:
2581: private static void ensureTimer() {
2582: synchronized (timer_lock) {
2583: if (timer != null)
2584: return;
2585: Runnable r = new Runnable() {
2586: public void run() {
2587: timerRun();
2588: }
2589: };
2590: timer = new Thread(r, "DBConnectionPool Timer");
2591: timer.setDaemon(true);
2592: timer.start();
2593: }
2594: }
2595:
2596: private static void timerRun() {
2597: while (true) {
2598: // pause
2599: try {
2600: Thread.sleep(TIMEOUT_CHECK_INTERVAL);
2601: } catch (InterruptedException e) {
2602: }
2603:
2604: // check timeouts
2605: try {
2606: checkAllTimeouts();
2607: } catch (Throwable t) {
2608: // Emergency measures to keep thread from dying.
2609: System.err
2610: .println("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"
2611: + "Uncaught Exception or Error in DBConnectionPool:");
2612: t.printStackTrace();
2613: System.err.println("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
2614: }
2615: }
2616: }
2617:
2618: private static void checkAllTimeouts() {
2619: synchronized (dbConnectionPools) {
2620: // get pools as array
2621: int n = dbConnectionPools.size();
2622: if (n <= 0)
2623: return;
2624: DBConnectionPool[] pools = new DBConnectionPool[n];
2625: Iterator iter = dbConnectionPools.values().iterator();
2626: for (int i = 0; i < n; i++) {
2627: pools[i++] = (DBConnectionPool) iter.next();
2628: }
2629:
2630: // call "checkTimeout" on each pool
2631: long now = System.currentTimeMillis();
2632: for (int i = 0; i < pools.length; i++) {
2633: try {
2634: pools[i].checkTimeout(now);
2635: } catch (Exception e) {
2636: e.printStackTrace();
2637: }
2638: }
2639: }
2640: }
2641:
2642: /**
2643: * A List of entries for connections we have opened.
2644: */
2645: private ArrayList entries = new ArrayList();
2646:
2647: /**
2648: * The maximum number of connections we permit in this
2649: * pool. Obtained from the first connection opened in this pool.
2650: */
2651: private int maxConnections = -1;
2652:
2653: /** How many times to retry a getConnection when failed due to a recoverable exception **/
2654: private int maxRetries = 30; // retry for a whole minute.
2655:
2656: /** How frequently should recoverable getConnections be retried? **/
2657: private long retryTimeout = 5 * 1000L; // 5 seconds
2658:
2659: /**
2660: *
2661: */
2662: private synchronized boolean containsConnection(
2663: DBConnectionPoolEntry entry) {
2664: return entries.contains(entry);
2665: }
2666:
2667: /**
2668: * Closes all of the currently unused Connections in this pool. Connections
2669: * that are currently open must destroy themselves when they become unused.
2670: */
2671: private synchronized void destroyPool() {
2672: while (!entries.isEmpty()) {
2673: DBConnectionPoolEntry entry = (DBConnectionPoolEntry) entries
2674: .get(0);
2675: entries.remove(entry);
2676: if (!entry.inUse)
2677: entry.destroy();
2678: }
2679: notifyAll();
2680: }
2681:
2682: /** Encapsulate logic to decide if a given exception is likely to be
2683: * transitory and so the connection attempt worthwhile retrying.
2684: **/
2685: private static boolean isRetryable(SQLException e) {
2686: while (e != null) {
2687: String m = e.getMessage();
2688: if (m.startsWith("ORA-00604")) { // recursive error
2689: e = e.getNextException();
2690: } else if (m.startsWith("ORA-00020") || // maximum number of processes (100) exceeded [too many connections]
2691: m.startsWith("ORA-00018") || // maximum number of sessions exceeded [?]
2692: m.startsWith("ORA-01000") // maximum open cursors exceeded [too many open statements]
2693: ) {
2694: return true;
2695: } else if (m.indexOf("Cannot connect to MySQL") > -1) { // MySQL DB unreachable
2696: return true;
2697: } else {
2698: return false;
2699: }
2700: }
2701: return false;
2702: }
2703:
2704: private synchronized Connection findConnection(String dbURL,
2705: String user, String passwd) throws SQLException {
2706: int retries = 0; // how many retries have we done?
2707: boolean waitingP = false;
2708: while (true) {
2709: for (Iterator e = entries.iterator(); e.hasNext();) {
2710: DBConnectionPoolEntry entry = (DBConnectionPoolEntry) e
2711: .next();
2712: if (!entry.inUse) {
2713: entry.inUse = true;
2714: return entry.getPoolConnection();
2715: }
2716: }
2717:
2718: if (maxConnections < 0 || entries.size() < maxConnections) {
2719: try {
2720: Connection conn = DriverManager.getConnection(
2721: dbURL, user, passwd);
2722: if (maxConnections < 0) {
2723: maxConnections = conn.getMetaData()
2724: .getMaxConnections();
2725: if (maxConnections < 1
2726: || maxConnections > MAX_CONNECTIONS) {
2727: maxConnections = MAX_CONNECTIONS;
2728: }
2729: }
2730: DBConnectionPoolEntry entry = new DBConnectionPoolEntry(
2731: conn);
2732: entries.add(entry);
2733: if (waitingP) {
2734: waitingCounter--;
2735: if (logger.isDebugEnabled()) {
2736: logger.debug("Finished waiting for " + key
2737: + " (" + waitingCounter + ")");
2738: }
2739: }
2740: } catch (SQLException sqle) {
2741: if (logger.isWarnEnabled()) {
2742: logger.warn("DBConnectionPool " + key
2743: + " saw exception", sqle);
2744: }
2745: if (retries < maxRetries && isRetryable(sqle)) {
2746: retries++;
2747: waitingP = true;
2748: waitingCounter++;
2749: if (logger.isDebugEnabled()) {
2750: logger.debug("Waiting to retry for " + key
2751: + " (" + waitingCounter + ")");
2752: }
2753: try {
2754: wait(retryTimeout);
2755: } catch (InterruptedException e) {
2756: }
2757: } else {
2758: throw sqle;
2759: }
2760: }
2761: } else {
2762: try {
2763: if (!waitingP) {
2764: waitingP = true;
2765: waitingCounter++;
2766: if (logger.isDebugEnabled()) {
2767: logger.debug("Waiting for " + key + " ("
2768: + waitingCounter + " of "
2769: + entries.size() + "/"
2770: + maxConnections + ")");
2771: }
2772: }
2773: wait();
2774: } catch (InterruptedException e) {
2775: }
2776: }
2777: }
2778: }
2779:
2780: private synchronized void delete(DBConnectionPoolEntry entry) {
2781: entries.remove(entry);
2782: entry.destroy();
2783: notifyAll();
2784: }
2785:
2786: private synchronized void release(DBConnectionPoolEntry entry) {
2787: entry.inUse = false;
2788: entry.lastUsed = System.currentTimeMillis();
2789: notifyAll();
2790: }
2791:
2792: private synchronized void checkTimeout(long now) {
2793: if (entries.size() > 0) {
2794: ArrayList entriesToDelete = new ArrayList();
2795: for (Iterator e = entries.iterator(); e.hasNext();) {
2796: DBConnectionPoolEntry entry = (DBConnectionPoolEntry) e
2797: .next();
2798: if (!entry.inUse) {
2799: if (entry.lastUsed < (now - TIMEOUT)) {
2800: entriesToDelete.add(entry);
2801: }
2802: }
2803: }
2804: int ndrops = entriesToDelete.size();
2805: if (ndrops > 0) {
2806: if (logger.isDebugEnabled()) {
2807: logger.debug("DBConnectionPool " + key
2808: + " dropping " + entriesToDelete.size()
2809: + " entries");
2810: }
2811: for (Iterator e = entriesToDelete.iterator(); e
2812: .hasNext();) {
2813: DBConnectionPoolEntry entry = (DBConnectionPoolEntry) e
2814: .next();
2815: delete(entry);
2816: }
2817: }
2818: }
2819: }
2820:
2821: //
2822: // driver registration
2823: //
2824:
2825: /** A Map of drivernames to Driver classes **/
2826: private static Map drivers = new HashMap();
2827:
2828: /** Register a driver carefully **/
2829: public static void registerDriver(String driverName)
2830: throws Exception {
2831: synchronized (drivers) {
2832: if (drivers.get(driverName) != null)
2833: return;
2834:
2835: Driver driver = (Driver) (Class.forName(driverName)
2836: .newInstance());
2837: DriverManager.registerDriver(driver);
2838: drivers.put(driverName, driver);
2839: }
2840: }
2841:
2842: static interface PreparedStatementConstructor {
2843: PreparedStatement create() throws SQLException;
2844: }
2845: }
|