KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > mchange > v2 > c3p0 > impl > DefaultConnectionTester


1 /*
2  * Distributed as part of c3p0 v.0.9.1
3  *
4  * Copyright (C) 2005 Machinery For Change, Inc.
5  *
6  * Author: Steve Waldman <swaldman@mchange.com>
7  *
8  * This library is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU Lesser General Public License version 2.1, as
10  * published by the Free Software Foundation.
11  *
12  * This software is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public License
18  * along with this software; see the file LICENSE. If not, write to the
19  * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
20  * Boston, MA 02111-1307, USA.
21  */

22
23
24 package com.mchange.v2.c3p0.impl;
25
26 import java.sql.*;
27 import java.util.*;
28 import com.mchange.v2.log.*;
29 import com.mchange.v2.c3p0.AbstractConnectionTester;
30 import com.mchange.v2.c3p0.FullQueryConnectionTester;
31 import com.mchange.v1.db.sql.ResultSetUtils;
32 import com.mchange.v1.db.sql.StatementUtils;
33
34 public class DefaultConnectionTester extends AbstractConnectionTester
35 {
36     final static MLogger logger = MLog.getLogger( DefaultConnectionTester.class );
37
38     final static int HASH_CODE = DefaultConnectionTester.class.getName().hashCode();
39
40     final static Set INVALID_DB_STATES;
41
42     static
43     {
44         Set temp = new HashSet();
45         temp.add("08001"); //SQL State "Unable to connect to data source"
46
temp.add("08007"); //SQL State "Connection failure during transaction"
47

48         // MySql appently uses this state to indicate a stale, expired
49
// connection when the database is fine, so we'll not presume
50
// this SQL state signals an invalid database.
51
//temp.add("08S01"); //SQL State "Communication link failure"
52

53         INVALID_DB_STATES = Collections.unmodifiableSet( temp );
54     }
55     
56     public int activeCheckConnection(Connection c, String JavaDoc query, Throwable JavaDoc[] rootCauseOutParamHolder)
57     {
58 // if (Debug.DEBUG && Debug.TRACE == Debug.TRACE_MAX && logger.isLoggable( MLevel.FINER ) )
59
// logger.finer("Entering DefaultConnectionTester.activeCheckConnection(Connection c, String query). [query=" + query + "]");
60

61         if (query == null)
62             return activeCheckConnectionNoQuery( c, rootCauseOutParamHolder);
63         else
64         {
65             Statement stmt = null;
66             ResultSet rs = null;
67             try
68             {
69                 //if (Math.random() < 0.1)
70
// throw new NullPointerException("Test.");
71

72                 stmt = c.createStatement();
73                 rs = stmt.executeQuery( query );
74                 //rs.next();
75
return CONNECTION_IS_OKAY;
76             }
77             catch (SQLException e)
78             {
79                 if (Debug.DEBUG && logger.isLoggable( MLevel.FINE ) )
80                     logger.log( MLevel.FINE, "Connection " + c + " failed Connection test with an Exception! [query=" + query + "]", e );
81                 
82                 if (rootCauseOutParamHolder != null)
83                     rootCauseOutParamHolder[0] = e;
84
85                 String JavaDoc state = e.getSQLState();
86                 if ( INVALID_DB_STATES.contains( state ) )
87                 {
88                     if (logger.isLoggable(MLevel.WARNING))
89                         logger.log(MLevel.WARNING,
90                                         "SQL State '" + state +
91                                         "' of Exception which occurred during a Connection test (test with query '" + query +
92                                         "') implies that the database is invalid, " +
93                                         "and the pool should refill itself with fresh Connections.", e);
94                     return DATABASE_IS_INVALID;
95                 }
96                 else
97                     return CONNECTION_IS_INVALID;
98             }
99             catch (Exception JavaDoc e)
100             {
101                 if ( Debug.DEBUG && logger.isLoggable( MLevel.FINE ))
102                     logger.log( MLevel.FINE, "Connection " + c + " failed Connection test with an Exception!", e );
103
104                 if (rootCauseOutParamHolder != null)
105                     rootCauseOutParamHolder[0] = e;
106
107                 return CONNECTION_IS_INVALID;
108             }
109             finally
110             {
111                 ResultSetUtils.attemptClose( rs );
112                 StatementUtils.attemptClose( stmt );
113
114 // if (Debug.DEBUG && Debug.TRACE == Debug.TRACE_MAX && logger.isLoggable( MLevel.FINER ) )
115
// logger.finer("Exiting DefaultConnectionTester.activeCheckConnection(Connection c, String query). [query=" + query + "]");
116
}
117         }
118     }
119
120     public int statusOnException(Connection c, Throwable JavaDoc t, String JavaDoc query, Throwable JavaDoc[] rootCauseOutParamHolder)
121     {
122 // if (Debug.DEBUG && Debug.TRACE == Debug.TRACE_MAX && logger.isLoggable( MLevel.FINER ) )
123
// logger.finer("Entering DefaultConnectionTester.statusOnException(Connection c, Throwable t, String query) " + queryInfo(query));
124

125         if (Debug.DEBUG && Debug.TRACE == Debug.TRACE_MAX && logger.isLoggable( MLevel.FINER ) )
126             logger.log(MLevel.FINER, "Testing a Connection in response to an Exception:", t);
127
128         try
129         {
130             if (t instanceof SQLException)
131             {
132                 String JavaDoc state = ((SQLException) t).getSQLState();
133                 if ( INVALID_DB_STATES.contains( state ) )
134                 {
135                     if (logger.isLoggable(MLevel.WARNING))
136                         logger.log(MLevel.WARNING,
137                                         "SQL State '" + state +
138                                         "' of Exception tested by statusOnException() implies that the database is invalid, " +
139                                         "and the pool should refill itself with fresh Connections.", t);
140                     return DATABASE_IS_INVALID;
141                 }
142                 else
143                     return activeCheckConnection(c, query, rootCauseOutParamHolder);
144             }
145             else //something is broke
146
{
147                 if ( logger.isLoggable( MLevel.FINE ) )
148                     logger.log( MLevel.FINE, "Connection test failed because test-provoking Throwable is an unexpected, non-SQLException.", t);
149                 if (rootCauseOutParamHolder != null)
150                     rootCauseOutParamHolder[0] = t;
151                 return CONNECTION_IS_INVALID;
152             }
153         }
154         catch (Exception JavaDoc e)
155         {
156             if ( Debug.DEBUG && logger.isLoggable( MLevel.FINE ))
157                 logger.log( MLevel.FINE, "Connection " + c + " failed Connection test with an Exception!", e );
158
159             if (rootCauseOutParamHolder != null)
160                 rootCauseOutParamHolder[0] = e;
161
162             return CONNECTION_IS_INVALID;
163         }
164         finally
165         {
166 // if (Debug.DEBUG && Debug.TRACE == Debug.TRACE_MAX)
167
// {
168
// if ( logger.isLoggable( MLevel.FINER ) )
169
// logger.finer("Exiting DefaultConnectionTester.statusOnException(Connection c, Throwable t, String query) " + queryInfo(query));
170
// }
171
}
172     }
173
174     private static String JavaDoc queryInfo(String JavaDoc query)
175     { return (query == null ? "[using default system-table query]" : "[query=" + query + "]"); }
176
177     private int activeCheckConnectionNoQuery(Connection c, Throwable JavaDoc[] rootCauseOutParamHolder)
178     {
179 // if (Debug.DEBUG && Debug.TRACE == Debug.TRACE_MAX && logger.isLoggable( MLevel.FINER ) )
180
// logger.finer("Entering DefaultConnectionTester.activeCheckConnection(Connection c). [using default system-table query]");
181

182         ResultSet rs = null;
183         try
184         {
185             rs = c.getMetaData().getTables( null,
186                             null,
187                             "PROBABLYNOT",
188                             new String JavaDoc[] {"TABLE"} );
189             return CONNECTION_IS_OKAY;
190         }
191         catch (SQLException e)
192         {
193             if ( Debug.DEBUG && logger.isLoggable( MLevel.FINE ))
194                 logger.log( MLevel.FINE, "Connection " + c + " failed default system-table Connection test with an Exception!", e );
195
196             if (rootCauseOutParamHolder != null)
197                 rootCauseOutParamHolder[0] = e;
198
199             String JavaDoc state = e.getSQLState();
200             if ( INVALID_DB_STATES.contains( state ) )
201             {
202                 if (logger.isLoggable(MLevel.WARNING))
203                     logger.log(MLevel.WARNING,
204                                     "SQL State '" + state +
205                                     "' of Exception which occurred during a Connection test (fallback DatabaseMetaData test) implies that the database is invalid, " +
206                                     "and the pool should refill itself with fresh Connections.", e);
207                 return DATABASE_IS_INVALID;
208             }
209             else
210                 return CONNECTION_IS_INVALID;
211         }
212         catch (Exception JavaDoc e)
213         {
214             if ( Debug.DEBUG && logger.isLoggable( MLevel.FINE ))
215                 logger.log( MLevel.FINE, "Connection " + c + " failed default system-table Connection test with an Exception!", e );
216
217             if (rootCauseOutParamHolder != null)
218                 rootCauseOutParamHolder[0] = e;
219
220             return CONNECTION_IS_INVALID;
221         }
222         finally
223         {
224             ResultSetUtils.attemptClose( rs );
225 // if (Debug.DEBUG && Debug.TRACE == Debug.TRACE_MAX && logger.isLoggable( MLevel.FINER ) )
226
// logger.finer("Exiting DefaultConnectionTester.activeCheckConnection(Connection c). [using default system-table query]");
227
}
228     }
229
230
231     public boolean equals( Object JavaDoc o )
232     { return ( o != null && o.getClass() == DefaultConnectionTester.class ); }
233
234     public int hashCode()
235     { return HASH_CODE; }
236 }
237
238
Popular Tags