001: /*
002: * Copyright (c) 1998 - 2005 Versant Corporation
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * Versant Corporation - initial API and implementation
010: */
011: package com.versant.core.jdbc.conn;
012:
013: import com.versant.core.common.BindingSupportImpl;
014: import com.versant.core.common.Debug;
015: import com.versant.core.logging.LogEventStore;
016:
017: import java.sql.*;
018:
019: /**
020: * A JDBC connection belonging to a JDBCConnectionPool.
021: *
022: * @see JDBCConnectionPool
023: */
024: public final class PooledConnection extends LoggingConnection {
025:
026: private final JDBCConnectionPool pool;
027: private boolean destroyed; // connection has been timedout
028: public boolean idle; // is connection idle (i.e. in pool)?
029: public PooledConnection prev, next; // linked list for JDBConnectionPool
030: public int age; // number of times con has been returned to the pool
031: private long lastActivityTime;
032: // Time when something last happened on this connection. This is used
033: // to cleanup active connections that are stuck.
034:
035: private int cachedTransationIsolation = -1;
036: private boolean cachedAutoCommit;
037:
038: public PooledConnection(JDBCConnectionPool pool, Connection con,
039: LogEventStore pes, boolean usePsPool, int psCacheMax) {
040: super (con, pes, usePsPool, psCacheMax, pool.isClearBatch());
041: this .pool = pool;
042: }
043:
044: public JDBCConnectionPool getPool() {
045: return pool;
046: }
047:
048: public synchronized long getLastActivityTime() {
049: return lastActivityTime;
050: }
051:
052: public synchronized void updateLastActivityTime() {
053: lastActivityTime = System.currentTimeMillis();
054: }
055:
056: /**
057: * Return ps to the pool.
058: * @see PooledPreparedStatement#close
059: */
060: public void returnPreparedStatement(PooledPreparedStatement ps)
061: throws SQLException {
062: updateLastActivityTime();
063: super .returnPreparedStatement(ps);
064: }
065:
066: /**
067: * This is just going to return the connection to the pool.
068: */
069: public void close() {
070: if (Debug.DEBUG) {
071: if (idle)
072: throw BindingSupportImpl.getInstance().internal(
073: "con in pool");
074: }
075: pool.returnConnection(this );
076: }
077:
078: public void setHoldability(int holdability) throws SQLException {
079: if (Debug.DEBUG) {
080: if (idle)
081: throw BindingSupportImpl.getInstance().internal(
082: "con in pool");
083: }
084: super .setHoldability(holdability);
085: }
086:
087: public int getHoldability() throws SQLException {
088: if (Debug.DEBUG) {
089: if (idle)
090: throw BindingSupportImpl.getInstance().internal(
091: "con in pool");
092: }
093: return super .getHoldability();
094: }
095:
096: public Savepoint setSavepoint() throws SQLException {
097: if (Debug.DEBUG) {
098: if (idle)
099: throw BindingSupportImpl.getInstance().internal(
100: "con in pool");
101: }
102: return super .setSavepoint();
103: }
104:
105: public Savepoint setSavepoint(String name) throws SQLException {
106: if (Debug.DEBUG) {
107: if (idle)
108: throw BindingSupportImpl.getInstance().internal(
109: "con in pool");
110: }
111: return super .setSavepoint(name);
112: }
113:
114: public void rollback(Savepoint savepoint) throws SQLException {
115: if (Debug.DEBUG) {
116: if (idle)
117: throw BindingSupportImpl.getInstance().internal(
118: "con in pool");
119: }
120: super .rollback(savepoint);
121: }
122:
123: public void releaseSavepoint(Savepoint savepoint)
124: throws SQLException {
125: if (Debug.DEBUG) {
126: if (idle)
127: throw BindingSupportImpl.getInstance().internal(
128: "con in pool");
129: }
130: super .releaseSavepoint(savepoint);
131: }
132:
133: public Statement createStatement(int resultSetType,
134: int resultSetConcurrency, int resultSetHoldability)
135: throws SQLException {
136: if (Debug.DEBUG) {
137: if (idle)
138: throw BindingSupportImpl.getInstance().internal(
139: "con in pool");
140: }
141: return super .createStatement(resultSetType,
142: resultSetConcurrency, resultSetHoldability);
143: }
144:
145: public PreparedStatement prepareStatement(String sql,
146: int resultSetType, int resultSetConcurrency,
147: int resultSetHoldability) throws SQLException {
148: if (Debug.DEBUG) {
149: if (idle)
150: throw BindingSupportImpl.getInstance().internal(
151: "con in pool");
152: }
153: return super .prepareStatement(sql, resultSetType,
154: resultSetConcurrency, resultSetHoldability);
155: }
156:
157: public CallableStatement prepareCall(String sql, int resultSetType,
158: int resultSetConcurrency, int resultSetHoldability)
159: throws SQLException {
160: if (Debug.DEBUG) {
161: if (idle)
162: throw BindingSupportImpl.getInstance().internal(
163: "con in pool");
164: }
165: return super .prepareCall(sql, resultSetType,
166: resultSetConcurrency, resultSetHoldability);
167: }
168:
169: public PreparedStatement prepareStatement(String sql,
170: int autoGeneratedKeys) throws SQLException {
171: if (Debug.DEBUG) {
172: if (idle)
173: throw BindingSupportImpl.getInstance().internal(
174: "con in pool");
175: }
176: return super .prepareStatement(sql, autoGeneratedKeys);
177: }
178:
179: public PreparedStatement prepareStatement(String sql,
180: int columnIndexes[]) throws SQLException {
181: if (Debug.DEBUG) {
182: if (idle)
183: throw BindingSupportImpl.getInstance().internal(
184: "con in pool");
185: }
186: return super .prepareStatement(sql, columnIndexes);
187: }
188:
189: public PreparedStatement prepareStatement(String sql,
190: String columnNames[]) throws SQLException {
191: if (Debug.DEBUG) {
192: if (idle)
193: throw BindingSupportImpl.getInstance().internal(
194: "con in pool");
195: }
196: return super .prepareStatement(sql, columnNames);
197: }
198:
199: public String nativeSQL(String sql) throws SQLException {
200: if (Debug.DEBUG) {
201: if (idle)
202: throw BindingSupportImpl.getInstance().internal(
203: "con in pool");
204: }
205: return super .nativeSQL(sql);
206: }
207:
208: public boolean getAutoCommit() throws SQLException {
209: if (Debug.DEBUG) {
210: if (idle)
211: throw BindingSupportImpl.getInstance().internal(
212: "con in pool");
213: }
214: return cachedAutoCommit = super .getAutoCommit();
215: }
216:
217: public boolean getCachedAutoCommit() {
218: return cachedAutoCommit;
219: }
220:
221: public boolean isClosed() throws SQLException {
222: if (Debug.DEBUG) {
223: if (idle)
224: throw BindingSupportImpl.getInstance().internal(
225: "con in pool");
226: }
227: return super .isClosed();
228: }
229:
230: public DatabaseMetaData getMetaData() throws SQLException {
231: if (Debug.DEBUG) {
232: if (idle)
233: throw BindingSupportImpl.getInstance().internal(
234: "con in pool");
235: }
236: return super .getMetaData();
237: }
238:
239: public void setReadOnly(boolean readOnly) throws SQLException {
240: if (Debug.DEBUG) {
241: if (idle)
242: throw BindingSupportImpl.getInstance().internal(
243: "con in pool");
244: }
245: super .setReadOnly(readOnly);
246: }
247:
248: public boolean isReadOnly() throws SQLException {
249: if (Debug.DEBUG) {
250: if (idle)
251: throw BindingSupportImpl.getInstance().internal(
252: "con in pool");
253: }
254: return super .isReadOnly();
255: }
256:
257: public void setCatalog(String catalog) throws SQLException {
258: if (Debug.DEBUG) {
259: if (idle)
260: throw BindingSupportImpl.getInstance().internal(
261: "con in pool");
262: }
263: super .setCatalog(catalog);
264: }
265:
266: public String getCatalog() throws SQLException {
267: if (Debug.DEBUG) {
268: if (idle)
269: throw BindingSupportImpl.getInstance().internal(
270: "con in pool");
271: }
272: return super .getCatalog();
273: }
274:
275: public void setTransactionIsolation(int level) throws SQLException {
276: if (Debug.DEBUG) {
277: if (idle)
278: throw BindingSupportImpl.getInstance().internal(
279: "con in pool");
280: }
281: super .setTransactionIsolation(level);
282: cachedTransationIsolation = level;
283: }
284:
285: public int getTransactionIsolation() throws SQLException {
286: if (Debug.DEBUG) {
287: if (idle)
288: throw BindingSupportImpl.getInstance().internal(
289: "con in pool");
290: }
291: return cachedTransationIsolation = super
292: .getTransactionIsolation();
293: }
294:
295: public int getCachedTransactionIsolation() throws SQLException {
296: if (Debug.DEBUG) {
297: if (idle)
298: throw BindingSupportImpl.getInstance().internal(
299: "con in pool");
300: }
301: if (cachedTransationIsolation >= 0)
302: return cachedTransationIsolation;
303: return cachedTransationIsolation = super
304: .getTransactionIsolation();
305: }
306:
307: public SQLWarning getWarnings() throws SQLException {
308: if (Debug.DEBUG) {
309: if (idle)
310: throw BindingSupportImpl.getInstance().internal(
311: "con in pool");
312: }
313: return super .getWarnings();
314: }
315:
316: public void clearWarnings() throws SQLException {
317: if (Debug.DEBUG) {
318: if (idle)
319: throw BindingSupportImpl.getInstance().internal(
320: "con in pool");
321: }
322: super .clearWarnings();
323: }
324:
325: public Statement createStatement(int resultSetType,
326: int resultSetConcurrency) throws SQLException {
327: if (Debug.DEBUG) {
328: if (idle)
329: throw BindingSupportImpl.getInstance().internal(
330: "con in pool");
331: }
332: return super .createStatement(resultSetType,
333: resultSetConcurrency);
334: }
335:
336: public CallableStatement prepareCall(String sql, int resultSetType,
337: int resultSetConcurrency) throws SQLException {
338: if (Debug.DEBUG) {
339: if (idle)
340: throw BindingSupportImpl.getInstance().internal(
341: "con in pool");
342: }
343: return super .prepareCall(sql, resultSetType,
344: resultSetConcurrency);
345: }
346:
347: public java.util.Map getTypeMap() throws SQLException {
348: if (Debug.DEBUG) {
349: if (idle)
350: throw BindingSupportImpl.getInstance().internal(
351: "con in pool");
352: }
353: return super .getTypeMap();
354: }
355:
356: public void setTypeMap(java.util.Map map) throws SQLException {
357: if (Debug.DEBUG) {
358: if (idle)
359: throw BindingSupportImpl.getInstance().internal(
360: "con in pool");
361: }
362: super .setTypeMap(map);
363: }
364:
365: public Statement createStatement() throws SQLException {
366: updateLastActivityTime();
367: if (Debug.DEBUG) {
368: if (idle)
369: throw BindingSupportImpl.getInstance().internal(
370: "con in pool");
371: }
372: return super .createStatement();
373: }
374:
375: public PreparedStatement prepareStatement(String sql)
376: throws SQLException {
377: if (Debug.DEBUG) {
378: if (idle)
379: throw BindingSupportImpl.getInstance().internal(
380: "con in pool");
381: }
382: return super .prepareStatement(sql);
383: }
384:
385: public PreparedStatement prepareStatement(String sql,
386: int resultSetType, int resultSetConcurrency)
387: throws SQLException {
388: if (Debug.DEBUG) {
389: if (idle)
390: throw BindingSupportImpl.getInstance().internal(
391: "con in pool");
392: }
393: return super .prepareStatement(sql, resultSetType,
394: resultSetConcurrency);
395: }
396:
397: public CallableStatement prepareCall(String sql)
398: throws SQLException {
399: if (Debug.DEBUG) {
400: if (idle)
401: throw BindingSupportImpl.getInstance().internal(
402: "con in pool");
403: }
404: return super .prepareCall(sql);
405: }
406:
407: public void setAutoCommit(boolean autoCommit) throws SQLException {
408: if (Debug.DEBUG) {
409: if (idle)
410: throw BindingSupportImpl.getInstance().internal(
411: "con in pool");
412: }
413: super .setAutoCommit(autoCommit);
414: cachedAutoCommit = autoCommit;
415: }
416:
417: public void commit() throws SQLException {
418: if (Debug.DEBUG) {
419: if (idle)
420: throw BindingSupportImpl.getInstance().internal(
421: "con in pool");
422: }
423: super .commit();
424: }
425:
426: public void rollback() throws SQLException {
427: if (Debug.DEBUG) {
428: if (idle)
429: throw BindingSupportImpl.getInstance().internal(
430: "con in pool");
431: }
432: super .rollback();
433: }
434:
435: /**
436: * Has this connection been destroyed?
437: * @see #destroy()
438: */
439: public boolean isDestroyed() {
440: return destroyed;
441: }
442:
443: /**
444: * Forceably close the real connection and set a flag to make sure this
445: * connection will not go back in the pool. Any exceptions on close
446: * are silently discarded. This is a NOP if the connection has already
447: * been destroyed.
448: * @see #isDestroyed()
449: */
450: public void destroy() {
451: if (destroyed)
452: return;
453: this .destroyed = true;
454: try {
455: super .close();
456: } catch (SQLException e) {
457: // ignore
458: }
459: }
460:
461: }
|