KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > snaq > db > CacheConnection


1 /*
2     DBPool - JDBC Connection Pool Manager
3     Copyright (c) Giles Winstanley
4 */

5 package snaq.db;
6
7 import snaq.util.Reusable;
8 import java.sql.*;
9 import java.util.*;
10
11 /**
12  * Connection wrapper that implements statement caching.
13  * @see snaq.db.CachedStatement
14  * @see snaq.db.CachedPreparedStatement
15  * @see snaq.db.CachedCallableStatement
16  * @author Giles Winstanley
17  */

18 public final class CacheConnection implements Connection, StatementListener, Reusable
19 {
20     // Constants for determining ResultSet parameters for statements.
21
private static int DEFAULT_RESULTSET_TYPE = ResultSet.TYPE_FORWARD_ONLY;
22     private static int DEFAULT_RESULTSET_CONCURRENCY = ResultSet.CONCUR_READ_ONLY;
23     private static int DEFAULT_RESULTSET_HOLDABILITY = ResultSet.HOLD_CURSORS_OVER_COMMIT;
24
25     protected ConnectionPool pool;
26     protected Connection con;
27     // Statement cache (List of Statement)
28
protected List ss = new ArrayList();
29     protected List ssUsed = new ArrayList();
30     // PreparedStatement cache (Map of List of PreparedStatement)
31
protected Map ps = new HashMap();
32     protected List psUsed = new ArrayList();
33     // CallableStatement cache (Map of List of CallableStatement)
34
protected Map cs = new HashMap();
35     protected List csUsed = new ArrayList();
36     // Non-cached statements
37
protected List nonCachable = new ArrayList();
38     // Other variables
39
private boolean cacheS, cacheP, cacheC;
40     private int ssReq, ssHit;
41     private int psReq, psHit;
42     private int csReq, csHit;
43     private boolean open = true;
44
45
46     /**
47      * Creates a new CacheConnection object, using the supplied Connection.
48      */

49     public CacheConnection(ConnectionPool pool, Connection con)
50     {
51         this.pool = pool;
52         this.con = con;
53         setCacheAll(true);
54         ssReq = ssHit = psReq = psHit = csReq = csHit = 0;
55     }
56
57     /**
58      * Added to provide caching support.
59      */

60     void setOpen()
61     {
62         open = true;
63     }
64
65     /**
66      * Added to provide caching support.
67      */

68     boolean isOpen()
69     {
70         return open;
71     }
72
73     /**
74      * Sets whether to use caching for Statements.
75      */

76     public void setCacheStatements(boolean cache)
77     {
78         // Release statements if required
79
if (cacheS && !cache)
80         {
81             try { flushSpareStatements(); }
82             catch (SQLException sqle) { pool.log(sqle); }
83         }
84         this.cacheS = cache;
85     }
86
87     /**
88      * Sets whether to use caching for PreparedStatements.
89      */

90     public void setCachePreparedStatements(boolean cache)
91     {
92         // Release statements if required
93
if (cacheP && !cache)
94         {
95             try { flushSparePreparedStatements(); }
96             catch (SQLException sqle) { pool.log(sqle); }
97         }
98         this.cacheP = cache;
99     }
100
101     /**
102      * Sets whether to use caching for CallableStatements.
103      */

104     public void setCacheCallableStatements(boolean cache)
105     {
106         // Release statements if required
107
if (cacheC && !cache)
108         {
109             try { flushSpareCallableStatements(); }
110             catch (SQLException sqle) { pool.log(sqle); }
111         }
112         this.cacheC = cache;
113     }
114
115     /**
116      * Sets whether to use caching for all types of Statement.
117      */

118     public void setCacheAll(boolean cache)
119     {
120         setCacheStatements(cache);
121         setCachePreparedStatements(cache);
122         setCacheCallableStatements(cache);
123     }
124
125     /** Returns whether caching of CallableStatements is enabled. */
126     public boolean isCachingAllStatements() { return cacheS && cacheP && cacheC; }
127
128     /** Returns whether caching of CallableStatements is enabled. */
129     public boolean isCachingStatements() { return cacheS; }
130
131     /** Returns whether caching of CallableStatements is enabled. */
132     public boolean isCachingPreparedStatements() { return cacheP; }
133
134     /** Returns whether caching of CallableStatements is enabled. */
135     public boolean isCachingCallableStatements() { return cacheC; }
136
137     /**
138      * Returns the raw underlying Connection object for which this provides
139      * a wrapper. This is provided as a convenience method for using database-specific
140      * features for which the Connection object needs to be upcast.
141      * (e.g. to use Oracle-specific features needs to be cast to oracle.jdbc.OracleConnection).
142      * <em>To maintain the stability of the pooling system it is important that the
143      * raw connection is not destabilized when used in this way.</em>
144      */

145     public Connection getRawConnection()
146     {
147         return con;
148     }
149
150     //******************************
151
// Connection interface methods
152
//******************************
153

154     /** Overrides method to provide caching support. */
155     public Statement createStatement() throws SQLException
156     {
157         return createStatement(DEFAULT_RESULTSET_TYPE, DEFAULT_RESULTSET_CONCURRENCY, DEFAULT_RESULTSET_HOLDABILITY);
158     }
159
160     /** Overrides method to provide caching support. */
161     public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException
162     {
163         return createStatement(resultSetType, resultSetConcurrency, DEFAULT_RESULTSET_HOLDABILITY);
164     }
165
166     /** Overrides method to provide caching support. */
167     public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException
168     {
169         CachedStatement cs = null;
170         if (!cacheS)
171         {
172             cs = new CachedStatement(con.createStatement(resultSetType, resultSetConcurrency, resultSetHoldability));
173             cs.setStatementListener(this);
174             cs.setOpen();
175         }
176         else
177         {
178             synchronized(ss)
179             {
180                 ssReq++;
181                 // Find Statement matching criteria required
182
for (Iterator it = ss.iterator(); it.hasNext();)
183                 {
184                     CachedStatement x = (CachedStatement)it.next();
185                     if (x.getResultSetType() == resultSetType &&
186                                     x.getResultSetConcurrency() == resultSetConcurrency &&
187                                     x.getResultSetHoldability() == resultSetHoldability)
188                     {
189                         cs = x;
190                         it.remove();
191                     }
192                 }
193                 // Prepare Statement for user
194
if (cs != null)
195                 {
196                     cs.setOpen();
197                     ssHit++;
198                     if (pool.isDebug())
199                         pool.log("Statement cache hit [" + cs.getParametersString() + "] - " + calcHitRate(ssHit, ssReq));
200                 }
201                 else
202                 {
203                     cs = new CachedStatement(con.createStatement(resultSetType, resultSetConcurrency, resultSetHoldability));
204                     cs.setStatementListener(this);
205                     cs.setOpen();
206                     if (pool.isDebug())
207                         pool.log("Statement cache miss [" + cs.getParametersString() + "] - " + calcHitRate(ssHit, ssReq));
208                 }
209             }
210         }
211         ssUsed.add(cs);
212         return cs;
213     }
214
215     /** Overrides method to provide caching support. */
216     public PreparedStatement prepareStatement(String JavaDoc sql) throws SQLException
217     {
218         return prepareStatement(sql, DEFAULT_RESULTSET_TYPE, DEFAULT_RESULTSET_CONCURRENCY, DEFAULT_RESULTSET_HOLDABILITY);
219     }
220
221     /** Overrides method to provide caching support. */
222     public PreparedStatement prepareStatement(String JavaDoc sql, int resultSetType, int resultSetConcurrency) throws SQLException
223     {
224         return prepareStatement(sql, resultSetType, resultSetConcurrency, DEFAULT_RESULTSET_HOLDABILITY);
225     }
226
227     /**
228      * Overrides method to provide caching support.
229      */

230     public PreparedStatement prepareStatement(String JavaDoc sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException
231     {
232         CachedPreparedStatement cps = null;
233         if (!cacheP)
234         {
235             cps = new CachedPreparedStatement(sql, con.prepareStatement(sql, resultSetType, resultSetConcurrency, resultSetHoldability));
236             cps.setStatementListener(this);
237             cps.setOpen();
238         }
239         else
240         {
241             synchronized(ps)
242             {
243                 psReq++;
244                 // Get List of cached PreparedStatements with matching SQL
245
List list = (List)ps.get(sql);
246                 if (list != null && !list.isEmpty())
247                 {
248                     // Find first free PreparedStatement with matching parameters
249
for (Iterator it = list.iterator(); it.hasNext();)
250                     {
251                         CachedPreparedStatement x = (CachedPreparedStatement)it.next();
252                         if (x.getResultSetType() == resultSetType &&
253                                         x.getResultSetConcurrency() == resultSetConcurrency &&
254                                         x.getResultSetHoldability() == resultSetHoldability)
255                         {
256                             cps = x;
257                             it.remove();
258                         }
259                     }
260                     // Remove cache mapping if list empty
261
if (list.isEmpty())
262                         ps.remove(sql);
263                 }
264                 // Prepare PreparedStatement for user
265
if (cps != null)
266                 {
267                     cps.setOpen();
268                     psHit++;
269                     if (pool.isDebug())
270                         pool.log("PreparedStatement cache hit [" + sql + "," + cps.getParametersString() + "] - " + calcHitRate(psHit, psReq));
271                 }
272                 else
273                 {
274                     cps = new CachedPreparedStatement(sql, con.prepareStatement(sql, resultSetType, resultSetConcurrency, resultSetHoldability));
275                     cps.setStatementListener(this);
276                     cps.setOpen();
277                     if (pool.isDebug())
278                         pool.log("PreparedStatement cache miss [" + sql + "," + cps.getParametersString() + "] - " + calcHitRate(psHit, psReq));
279                 }
280             }
281         }
282         psUsed.add(cps);
283         return cps;
284     }
285
286     /** Overrides method to provide caching support. */
287     public CallableStatement prepareCall(String JavaDoc sql) throws SQLException
288     {
289         return prepareCall(sql, DEFAULT_RESULTSET_TYPE, DEFAULT_RESULTSET_CONCURRENCY, DEFAULT_RESULTSET_HOLDABILITY);
290     }
291
292     /** Overrides method to provide caching support. */
293     public CallableStatement prepareCall(String JavaDoc sql, int resultSetType, int resultSetConcurrency) throws SQLException
294     {
295         return prepareCall(sql, resultSetType, resultSetConcurrency, DEFAULT_RESULTSET_HOLDABILITY);
296     }
297
298     /**
299      * Overrides method to provide caching support.
300      */

301     public CallableStatement prepareCall(String JavaDoc sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException
302     {
303         CachedCallableStatement ccs = null;
304         if (!cacheC)
305         {
306             ccs = new CachedCallableStatement(sql, con.prepareCall(sql));
307             ccs.setStatementListener(this);
308             ccs.setOpen();
309         }
310         else
311         {
312             synchronized(cs)
313             {
314                 csReq++;
315                 // Get List of cached CallableStatements with matching SQL
316
List list = (List)cs.get(sql);
317                 if (list != null && !list.isEmpty())
318                 {
319                     // Find first free CallableStatement with matching parameters
320
for (Iterator it = list.iterator(); it.hasNext();)
321                     {
322                         CachedCallableStatement x = (CachedCallableStatement)it.next();
323                         if (x.getResultSetType() == resultSetType &&
324                                         x.getResultSetConcurrency() == resultSetConcurrency &&
325                                         x.getResultSetHoldability() == resultSetHoldability)
326                         {
327                             ccs = x;
328                             it.remove();
329                         }
330                     }
331                     // Remove cache mapping if list empty
332
if (list.isEmpty())
333                         cs.remove(sql);
334                 }
335                 // Prepare CallableStatement for user
336
if (ccs != null)
337                 {
338                     ccs.setOpen();
339                     csHit++;
340                     if (pool.isDebug())
341                         pool.log("CallableStatement cache hit [" + sql + "," + ccs.getParametersString() + "] - " + calcHitRate(csHit, csReq));
342                 }
343                 else
344                 {
345                     CallableStatement st = con.prepareCall(sql);
346                     ccs = new CachedCallableStatement(sql, st);
347                     ccs.setStatementListener(this);
348                     ccs.setOpen();
349                     if (pool.isDebug())
350                         pool.log("CallableStatement cache miss [" + sql + "," + ccs.getParametersString() + "] - " + calcHitRate(csHit, csReq));
351                 }
352             }
353         }
354         csUsed.add(ccs);
355         return ccs;
356     }
357
358     /**
359      * Callback invoked when a statement is closed.
360      */

361     public void statementClosed(CachedStatement s) throws SQLException
362     {
363         if (s instanceof CachedPreparedStatement)
364         {
365             synchronized(ps)
366             {
367                 String JavaDoc key = ((CachedPreparedStatement)s).getSQLString();
368                 psUsed.remove(s);
369                 // If caching disabled close statement
370
if (!cacheP)
371                     s.release();
372                 else // else try to recycle it
373
{
374                     try
375                     {
376                         s.recycle();
377                         // Place back in cache
378
List list = (List)ps.get(key);
379                         if (list == null)
380                         {
381                             list = new ArrayList();
382                             ps.put(key, list);
383                         }
384                         list.add(s);
385                     }
386                     catch (SQLException sqle)
387                     {
388                         s.release();
389                     }
390                 }
391             }
392         }
393         else if (s instanceof CachedCallableStatement)
394         {
395             synchronized(cs)
396             {
397                 String JavaDoc key = ((CachedCallableStatement)s).getSQLString();
398                 csUsed.remove(s);
399                 // If caching disabled close statement
400
if (!cacheC)
401                     s.release();
402                 else // else try to recycle it
403
{
404                     try
405                     {
406                         s.recycle();
407                         // Place back in cache
408
List list = (List)cs.get(key);
409                         if (list == null)
410                         {
411                             list = new ArrayList();
412                             cs.put(key, list);
413                         }
414                         list.add(s);
415                     }
416                     catch (SQLException sqle)
417                     {
418                         s.release();
419                     }
420                 }
421             }
422         }
423         else if (s instanceof CachedStatement)
424         {
425             synchronized(ss)
426             {
427                 ssUsed.remove(s);
428                 // If caching disabled close statement
429
if (!cacheS)
430                     s.release();
431                 else // else try to recycle it
432
{
433                     try
434                     {
435                         s.recycle();
436                         ss.add(s);
437                     }
438                     catch (SQLException sqle)
439                     {
440                         s.release();
441                     }
442                 }
443             }
444         }
445     }
446
447     private String JavaDoc calcHitRate(int hits, int reqs)
448     {
449         return (reqs == 0) ? "" : (((float)hits / reqs) * 100f) + "% hit rate";
450     }
451
452     public String JavaDoc nativeSQL(String JavaDoc sql) throws SQLException
453     {
454         return con.nativeSQL(sql);
455     }
456
457     public void setAutoCommit(boolean autoCommit) throws SQLException
458     {
459         con.setAutoCommit(autoCommit);
460     }
461
462     public boolean getAutoCommit() throws SQLException
463     {
464         return con.getAutoCommit();
465     }
466
467     public void commit() throws SQLException
468     {
469         con.commit();
470     }
471
472     public void rollback() throws SQLException
473     {
474         con.rollback();
475     }
476
477     /**
478      * Puts connection back in a state where it can be reused.
479      */

480     public void recycle() throws SQLException
481     {
482         // Close all open Statements
483
if (cacheS)
484         {
485             int count = (ssUsed != null) ? ssUsed.size() : 0;
486             if (count > 0)
487             {
488                 if (pool.isDebug())
489                     pool.log("Cleaning " + count + " cached Statement" + (count > 1 ? "s" : ""));
490                 synchronized(ssUsed)
491                 {
492                     while (!ssUsed.isEmpty())
493                         ((Statement)ssUsed.remove(0)).close();
494                 }
495             }
496         }
497         else
498         {
499             flushOpenStatements();
500             flushSpareStatements();
501         }
502
503         // Close all open PreparedStatements
504
if (cacheP)
505         {
506             int count = (psUsed != null) ? psUsed.size() : 0;
507             if (count > 0)
508             {
509                 if (pool.isDebug())
510                     pool.log("Cleaning " + count + " cached PreparedStatement" + (count > 1 ? "s" : ""));
511                 synchronized(psUsed)
512                 {
513                     while (!psUsed.isEmpty())
514                         ((CachedPreparedStatement)psUsed.remove(0)).close();
515                 }
516             }
517         }
518         else
519         {
520             flushOpenPreparedStatements();
521             flushSparePreparedStatements();
522         }
523
524         // Close all open CallableStatements
525
if (cacheC)
526         {
527             int count = (csUsed != null) ? csUsed.size() : 0;
528             if (count > 0)
529             {
530                 if (pool.isDebug())
531                     pool.log("Cleaning " + count + " cached CallableStatement" + (count > 1 ? "s" : ""));
532                 synchronized(csUsed)
533                 {
534                     while (!csUsed.isEmpty())
535                         ((CachedCallableStatement)csUsed.remove(0)).close();
536                 }
537             }
538         }
539         else
540         {
541             flushOpenCallableStatements();
542             flushSpareCallableStatements();
543         }
544
545         // Close all open non-cachable PreparedStatements.
546
flushOpenNonCachableStatements();
547
548         // Put connection back in default state
549
if (!getAutoCommit())
550         {
551             try { rollback(); }
552             catch (SQLException sqle) { pool.log(sqle); }
553             setAutoCommit(true);
554         }
555         clearWarnings();
556         
557         // Clear type map entries.
558
Map tm = getTypeMap();
559         if (tm != null)
560             tm.clear();
561     }
562
563     /**
564      * Overrides method to provide caching support.
565      */

566     public void close() throws SQLException
567     {
568         if (!open)
569             throw new SQLException("Connection already closed");
570         open = false;
571         // Hand itself back to the pool
572
pool.freeConnection(this);
573     }
574
575     /**
576      * Returns the current number of spare Statements that are cached.
577      */

578     public int getSpareStatementCount()
579     {
580         return ss.size();
581     }
582
583     /**
584      * Returns the current number of Statements that are in use
585      * (not including PreparedStatements &amp; CallableStatements).
586      */

587     public int getOpenStatementCount()
588     {
589         return ssUsed.size();
590     }
591
592     /**
593      * Returns the current number of spare PreparedStatements that are cached.
594      */

595     public int getSparePreparedStatementCount()
596     {
597         int count = 0;
598         synchronized(ps)
599         {
600             for (Iterator it = ps.values().iterator(); it.hasNext();)
601                 count += ((List)it.next()).size();
602         }
603         return count;
604     }
605
606     /**
607      * Returns the current number of PreparedStatements that are in use
608      * (not including CallableStatements).
609      */

610     public int getOpenPreparedStatementCount()
611     {
612         return psUsed.size();
613     }
614
615     /**
616      * Returns the current number of spare CallableStatements that are cached.
617      */

618     public int getSpareCallableStatementCount()
619     {
620         int count = 0;
621         synchronized(cs)
622         {
623             for (Iterator it = cs.values().iterator(); it.hasNext();)
624                 count += ((List)it.next()).size();
625         }
626         return count;
627     }
628
629     /**
630      * Returns the current number of CallableStatements that are in use.
631      */

632     public int getOpenCallableStatementCount()
633     {
634         return csUsed.size();
635     }
636
637     /**
638      * Returns the current number of non-cachable statements that are in use.
639      * (Currently only some PreparedStatements are non-cachable by virtue of
640      * a request made at creation for support for auto-generated keys.)
641      * @see snaq.db.CacheConnection#prepareStatement(String, int)
642      * @see snaq.db.CacheConnection#prepareStatement(String, int[])
643      * @see snaq.db.CacheConnection#prepareStatement(String, String[])
644      */

645     public int getOpenNonCachableStatementCount()
646     {
647         return nonCachable.size();
648     }
649
650     /**
651      * Flushes the spare Statement caches for this connection.
652      */

653     protected void flushSpareStatements() throws SQLException
654     {
655         // Close all cached Statements
656
int count = (ss != null) ? ss.size() : 0;
657         if (count > 0)
658         {
659             if (pool.isDebug())
660                 pool.log("Closing " + count + " cached Statement" + (count > 1 ? "s" : ""));
661             synchronized(ss)
662             {
663                 while (!ss.isEmpty())
664                     ((CachedStatement)ss.remove(0)).release();
665             }
666         }
667     }
668
669     /**
670      * Flushes the open Statement cache for this connection.
671      */

672     protected void flushOpenStatements() throws SQLException
673     {
674         // Close all open Statements
675
int count = (ssUsed != null) ? ssUsed.size() : 0;
676         if (count > 0)
677         {
678             if (pool.isDebug())
679                 pool.log("Closing " + count + " open Statement" + (count > 1 ? "s" : ""));
680             synchronized(ssUsed)
681             {
682                 while (!ssUsed.isEmpty())
683                     ((CachedStatement)ssUsed.remove(0)).release();
684             }
685         }
686     }
687
688     /**
689      * Flushes the spare PreparedStatement cache for this connection.
690      */

691     protected void flushSparePreparedStatements() throws SQLException
692     {
693         // Close all cached PreparedStatements
694
int count = (ps != null) ? ps.size() : 0;
695         if (count > 0)
696         {
697             if (pool.isDebug())
698                 pool.log("Closing " + count + " cached PreparedStatement" + (count > 1 ? "s" : ""));
699             synchronized(ps)
700             {
701                 for (Iterator iter = ps.values().iterator(); iter.hasNext();)
702                 {
703                     List list = (List)iter.next();
704                     for (Iterator it = list.iterator(); it.hasNext();)
705                         ((CachedPreparedStatement)it.next()).release();
706                 }
707                 ps.clear();
708             }
709         }
710     }
711
712     /**
713      * Flushes the open PreparedStatement cache for this connection.
714      */

715     protected void flushOpenPreparedStatements() throws SQLException
716     {
717         // Close all open PreparedStatements
718
int count = (psUsed != null) ? psUsed.size() : 0;
719         if (count > 0)
720         {
721             if (pool.isDebug())
722                 pool.log("Closing " + count + " open PreparedStatement" + (count > 1 ? "s" : ""));
723             synchronized(psUsed)
724             {
725                 while (!psUsed.isEmpty())
726                     ((CachedPreparedStatement)psUsed.remove(0)).release();
727             }
728         }
729     }
730
731     /**
732      * Flushes the spare CallableStatement cache for this connection.
733      */

734     protected void flushSpareCallableStatements() throws SQLException
735     {
736         // Close all cached CallableStatements
737
int count = (cs != null) ? cs.size() : 0;
738         if (count > 0)
739         {
740             if (pool.isDebug())
741                 pool.log("Closing " + count + " cached CallableStatement" + (count > 1 ? "s" : ""));
742             synchronized(cs)
743             {
744                 for (Iterator iter = cs.values().iterator(); iter.hasNext();)
745                 {
746                     List list = (List)iter.next();
747                     for (Iterator it = list.iterator(); it.hasNext();)
748                         ((CachedCallableStatement)it.next()).release();
749                 }
750                 cs.clear();
751             }
752         }
753     }
754
755     /**
756      * Flushes the open CallableStatement cache for this connection.
757      */

758     protected void flushOpenCallableStatements() throws SQLException
759     {
760         // Close all open CallableStatements
761
int count = (csUsed != null) ? csUsed.size() : 0;
762         if (count > 0)
763         {
764             if (pool.isDebug())
765                 pool.log("Closing " + count + " open CallableStatement" + (count > 1 ? "s" : ""));
766             synchronized(csUsed)
767             {
768                 while (!csUsed.isEmpty())
769                     ((CachedCallableStatement)csUsed.remove(0)).release();
770             }
771         }
772     }
773
774     /**
775      * Flushes the non-cachable Statements for this connection.
776      */

777     protected void flushOpenNonCachableStatements() throws SQLException
778     {
779         int count = (nonCachable != null) ? nonCachable.size() : 0;
780         if (count > 0)
781         {
782             if (pool.isDebug())
783                 pool.log("Closing " + count + " open non-cachable Statement" + (count > 1 ? "s" : ""));
784             synchronized(nonCachable)
785             {
786                 while (!nonCachable.isEmpty())
787                 {
788                     try { ((Statement)nonCachable.remove(0)).close(); }
789                     catch (SQLException sqle) { pool.log(sqle); }
790                 }
791             }
792         }
793     }
794
795     /**
796      * Destroys the wrapped connection.
797      */

798     public void release() throws SQLException
799     {
800         open = false;
801         ArrayList list = new ArrayList();
802
803         try { flushSpareStatements(); flushOpenStatements(); }
804         catch (SQLException e) { list.add(e); }
805         try { flushSparePreparedStatements(); flushOpenPreparedStatements(); }
806         catch (SQLException e) { list.add(e); }
807         try { flushSpareCallableStatements(); flushOpenCallableStatements(); }
808         catch (SQLException e) { list.add(e); }
809         try { flushOpenNonCachableStatements(); }
810         catch (SQLException e) { list.add(e); }
811
812         try { con.close(); }
813         catch (SQLException e) { list.add(e); }
814
815         if (!list.isEmpty())
816         {
817             SQLException sqle = new SQLException("Problem releasing connection resources");
818             for (Iterator it = list.iterator(); it.hasNext();)
819             {
820                 SQLException x = (SQLException)it.next();
821                 sqle.setNextException(x);
822                 sqle = x;
823             }
824             throw sqle;
825         }
826     }
827
828     public boolean isClosed() throws SQLException
829     {
830         return con.isClosed();
831     }
832
833     public DatabaseMetaData getMetaData() throws SQLException
834     {
835         return con.getMetaData();
836     }
837
838     public void setReadOnly(boolean readOnly) throws SQLException
839     {
840         con.setReadOnly(readOnly);
841     }
842
843     public boolean isReadOnly() throws SQLException
844     {
845         return con.isReadOnly();
846     }
847
848     public void setCatalog(String JavaDoc catalog) throws SQLException
849     {
850         con.setCatalog(catalog);
851     }
852
853     public String JavaDoc getCatalog() throws SQLException
854     {
855         return con.getCatalog();
856     }
857
858     public void setTransactionIsolation(int level) throws SQLException
859     {
860         con.setTransactionIsolation(level);
861     }
862
863     public int getTransactionIsolation() throws SQLException
864     {
865         return con.getTransactionIsolation();
866     }
867
868     public SQLWarning getWarnings() throws SQLException
869     {
870         return con.getWarnings();
871     }
872
873     public void clearWarnings() throws SQLException
874     {
875         con.clearWarnings();
876     }
877
878     public Map getTypeMap() throws SQLException
879     {
880         return con.getTypeMap();
881     }
882
883     public void setTypeMap(Map map) throws SQLException
884     {
885         con.setTypeMap(map);
886     }
887
888     //**********************************
889
// Interface methods from JDBC 3.0
890
//**********************************
891

892     public void setHoldability(int holdability) throws SQLException
893     {
894         con.setHoldability(holdability);
895     }
896
897     public int getHoldability() throws SQLException
898     {
899         return con.getHoldability();
900     }
901
902     public Savepoint setSavepoint() throws SQLException
903     {
904         return con.setSavepoint();
905     }
906
907     public Savepoint setSavepoint(String JavaDoc name) throws SQLException
908     {
909         return con.setSavepoint(name);
910     }
911
912     public void rollback(Savepoint savepoint) throws SQLException
913     {
914         con.rollback(savepoint);
915     }
916
917     public void releaseSavepoint(Savepoint savepoint) throws SQLException
918     {
919         con.releaseSavepoint(savepoint);
920     }
921
922     public PreparedStatement prepareStatement(String JavaDoc sql, int autoGeneratedKeys) throws SQLException
923     {
924         PreparedStatement x = con.prepareStatement(sql, autoGeneratedKeys);
925         nonCachable.add(x);
926         return x;
927     }
928
929     public PreparedStatement prepareStatement(String JavaDoc sql, int[] columnIndexes) throws SQLException
930     {
931         PreparedStatement x = con.prepareStatement(sql, columnIndexes);
932         nonCachable.add(x);
933         return x;
934     }
935
936     public PreparedStatement prepareStatement(String JavaDoc sql, String JavaDoc[] columnNames) throws SQLException
937     {
938         PreparedStatement x = con.prepareStatement(sql, columnNames);
939         nonCachable.add(x);
940         return x;
941     }
942 }
Popular Tags