Most clients need never use or know about this interface -- c3p0-provided Connections 10 | * can be treated like any other Connection.
11 | * 12 | *An interface implemented by proxy Connections returned 13 | * by c3p0 PooledDataSources. It provides protected access to the underlying 14 | * dbms-vendor specific Connection, which may be useful if you want to 15 | * access non-standard API offered by your jdbc driver. 16 | */ 17 | public interface C3P0ProxyConnection extends Connection 18 | { 19 | /** 20 | * A token representing an unwrapped, unproxied jdbc Connection 21 | * for use in {@link #rawConnectionOperation} 22 | */ 23 | public final static Object RAW_CONNECTION = new Object(); 24 | 25 | /** 26 | *
Allows one to work with the unproxied, raw Connection. Some 27 | * database companies never got over the "common interfaces mean 28 | * no more vendor lock-in!" thing, and offer non-standard API 29 | * on their Connections. This method permits you to "pierce" the 30 | * connection-pooling layer to call non-standard methods on the 31 | * original Connection, or to pass the original Connections to 32 | * functions that are not implementation neutral.
33 | * 34 | *To use this functionality, you'll need to cast a Connection 35 | * retrieved from a c3p0 PooledDataSource to a 36 | * C3P0ProxyConnection.
37 | * 38 | *This method works by making a reflective call of method m
on
39 | * Object target
(which may be null for static methods), passing
40 | * and argument list args
. For the method target, or for any argument,
41 | * you may substitute the special token C3P0ProxyConnection.RAW_CONNECTION
Any Statements or ResultSets returned by the operation will be proxied 44 | * and c3p0-managed, meaning that these resources will be automatically closed 45 | * if the user does not close them first when this Connection is checked back 46 | * into the pool. Any other resources returned by the operation are the user's 47 | * responsibility to clean up!
48 | * 49 | *Incautious use of this method can corrupt the Connection pool, by breaking the invariant 50 | * that all checked-in Connections should be equivalent. If your vendor supplies API 51 | * that allows you to modify the state or configuration of a Connection in some nonstandard way, 52 | * you might use this method to do so, and then check the Connection back into the pool. 53 | * When you fetch another Connection from the PooledDataSource, it will be undefined 54 | * whether the Connection returned will have your altered configuration, or the default 55 | * configuration of a "fresh" Connection. Thus, it is inadvisable to use this method to call 56 | * nonstandard mutators. 57 | */ 58 | public Object rawConnectionOperation(Method m, Object target, Object[] args) 59 | throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, SQLException; 60 | } 61 | -------------------------------------------------------------------------------- /src-proxy-interface/com/mchange/v2/c3p0/C3P0ProxyStatement.java: -------------------------------------------------------------------------------- 1 | package com.mchange.v2.c3p0; 2 | 3 | import java.sql.Statement; 4 | import java.sql.SQLException; 5 | import java.lang.reflect.Method; 6 | import java.lang.reflect.InvocationTargetException; 7 | 8 | /** 9 | *
Most clients need never use or know about this interface -- c3p0-provided Statements 10 | * can be treated like any other Statement.
11 | * 12 | *An interface implemented by proxy Connections returned 13 | * by c3p0 PooledDataSources. It provides protected access to the underlying 14 | * dbms-vendor specific Connection, which may be useful if you want to 15 | * access non-standard API offered by your jdbc driver. 16 | */ 17 | public interface C3P0ProxyStatement extends Statement 18 | { 19 | /** 20 | * A token representing an unwrapped, unproxied jdbc Connection 21 | * for use in {@link #rawStatementOperation} 22 | */ 23 | public final static Object RAW_STATEMENT = new Object(); 24 | 25 | /** 26 | *
Allows one to work with the unproxied, raw vendor-provided Statement . Some 27 | * database companies never got over the "common interfaces mean 28 | * no more vendor lock-in!" thing, and offer non-standard API 29 | * on their Statements. This method permits you to "pierce" the 30 | * connection-pooling layer to call non-standard methods on the 31 | * original Statement, or to pass the original Statement to 32 | * functions that are not implementation neutral.
33 | * 34 | *To use this functionality, you'll need to cast a Statement 35 | * retrieved from a c3p0-provided Connection to a 36 | * C3P0ProxyStatement.
37 | * 38 | *This method works by making a reflective call of method m
on
39 | * Object target
(which may be null for static methods), passing
40 | * and argument list args
. For the method target, or for any argument,
41 | * you may substitute the special token C3P0ProxyStatement.RAW_STATEMENT
Any ResultSets returned by the operation will be proxied 44 | * and c3p0-managed, meaning that these resources will be automatically closed 45 | * if the user does not close them first when this Statement is closed or checked 46 | * into the statement cache. Any other resources returned by the operation are the user's 47 | * responsibility to clean up!
48 | * 49 | *If you have turned statement pooling on, incautious use of this method can corrupt the 50 | * PreparedStatement cache, by breaking the invariant 51 | * that all cached PreparedStatements should be equivalent to a PreparedStatement newly created 52 | * with the same arguments to prepareStatement(...) or prepareCall(...). If your vendor supplies API 53 | * that allows you to modify the state or configuration of a Statement in some nonstandard way, 54 | * and you do not undo this modification prior to closing the Statement or the Connection that 55 | * prepared it, future preparers of the same Statement may or may not see your modification, 56 | * depending on your use of the cache. Thus, it is inadvisable to use this method to call 57 | * nonstandard mutators on PreparedStatements if statement pooling is turned on.. 58 | */ 59 | public Object rawStatementOperation(Method m, Object target, Object[] args) 60 | throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, SQLException; 61 | } 62 | -------------------------------------------------------------------------------- /src-proxy-interface/com/mchange/v2/c3p0/impl/ProxyResultSetDetachable.java: -------------------------------------------------------------------------------- 1 | package com.mchange.v2.c3p0.impl; 2 | 3 | import java.sql.ResultSet; 4 | 5 | /** 6 | * This is an internal interface, not intended for use by library users. 7 | * (It is exposed publicly only for use by c3p0's code generation library.) 8 | */ 9 | public interface ProxyResultSetDetachable 10 | { 11 | void detachProxyResultSet( ResultSet prs ); 12 | } 13 | 14 | -------------------------------------------------------------------------------- /src/com/mchange/v2/c3p0/AbstractConnectionCustomizer.java: -------------------------------------------------------------------------------- 1 | package com.mchange.v2.c3p0; 2 | 3 | import java.util.Map; 4 | import java.sql.Connection; 5 | import java.sql.SQLException; 6 | 7 | /** 8 | * An abstract implementation of the 9 | * ConnectionCustomizer interface 10 | * in which all methods are no-ops. 11 | * 12 | * Just a convenience class since 13 | * most clients will only need to 14 | * implement a single method. 15 | */ 16 | public abstract class AbstractConnectionCustomizer implements ConnectionCustomizer 17 | { 18 | protected Map extensionsForToken( String parentDataSourceIdentityToken ) 19 | { return C3P0Registry.extensionsForToken( parentDataSourceIdentityToken ); } 20 | 21 | public void onAcquire( Connection c, String parentDataSourceIdentityToken ) throws Exception 22 | {} 23 | 24 | public void onDestroy( Connection c, String parentDataSourceIdentityToken ) throws Exception 25 | {} 26 | 27 | public void onCheckOut( Connection c, String parentDataSourceIdentityToken ) throws Exception 28 | {} 29 | 30 | public void onCheckIn( Connection c, String parentDataSourceIdentityToken ) throws Exception 31 | {} 32 | 33 | public boolean equals( Object o ) { return this.getClass().equals( o.getClass() ); } 34 | public int hashCode() { return this.getClass().getName().hashCode(); } 35 | } 36 | -------------------------------------------------------------------------------- /src/com/mchange/v2/c3p0/AbstractConnectionTester.java: -------------------------------------------------------------------------------- 1 | package com.mchange.v2.c3p0; 2 | 3 | import java.sql.Connection; 4 | 5 | /** 6 | *
Having expanded the once-simple ConnectionTester interface to support both 7 | * user-specified queries and return of root cause Exceptions (via an out-param), 8 | * this interface has grown unnecessarily complex.
9 | * 10 | *If you wish to implement a custom Connection tester, here is the simple 11 | * way to do it
12 | * 13 | *public int activeCheckConnection(Connection c, String preferredTestQuery, Throwable[] rootCauseOutParamHolder)
public int statusOnException(Connection c, Throwable t, String preferredTestQuery, Throwable[] rootCauseOutParamHolder)
preferredTestQuery
and
23 | * rootCauseOutParamHolder
to be null
.Parameter rootCauseOutParamHolder
is an optional parameter, which if supplied, will be a Throwable array whose size
27 | * it at least one. If a Connection test fails because of some Exception, the Connection tester may set this Exception as the
28 | * zero-th element of the array to provide information about why and how the test failed.
preferredTestQuery
and rootCauseOutParamHolder
34 | * can be null.
35 | */
36 | public abstract int activeCheckConnection(Connection c, String preferredTestQuery, Throwable[] rootCauseOutParamHolder);
37 |
38 | /**
39 | * Override, but remember that preferredTestQuery
and rootCauseOutParamHolder
40 | * can be null.
41 | */
42 | public abstract int statusOnException(Connection c, Throwable t, String preferredTestQuery, Throwable[] rootCauseOutParamHolder);
43 |
44 | //usually just leave the rest of these as-is
45 | public int activeCheckConnection(Connection c)
46 | { return activeCheckConnection( c, null, null); }
47 |
48 | public int activeCheckConnection(Connection c, Throwable[] rootCauseOutParamHolder)
49 | { return activeCheckConnection( c, null, rootCauseOutParamHolder); }
50 |
51 | public int activeCheckConnection(Connection c, String preferredTestQuery)
52 | { return activeCheckConnection( c, preferredTestQuery, null); }
53 |
54 | public int statusOnException(Connection c, Throwable t)
55 | { return statusOnException( c, t, null, null); }
56 |
57 | public int statusOnException(Connection c, Throwable t, Throwable[] rootCauseOutParamHolder)
58 | { return statusOnException( c, t, null, rootCauseOutParamHolder); }
59 |
60 | public int statusOnException(Connection c, Throwable t, String preferredTestQuery)
61 | { return statusOnException( c, t, preferredTestQuery, null); }
62 |
63 | public boolean equals( Object o ) { return this.getClass().equals( o.getClass() ); }
64 | public int hashCode() { return this.getClass().getName().hashCode(); }
65 | }
66 |
--------------------------------------------------------------------------------
/src/com/mchange/v2/c3p0/ComboPooledDataSource.java:
--------------------------------------------------------------------------------
1 | package com.mchange.v2.c3p0;
2 |
3 | import java.io.*;
4 | import javax.naming.*;
5 |
6 | /**
7 | * For the meaning of most of these properties, please see c3p0's top-level documentation!
8 | */ 9 | public final class ComboPooledDataSource extends AbstractComboPooledDataSource implements Serializable, Referenceable 10 | { 11 | public ComboPooledDataSource() 12 | { super(); } 13 | 14 | public ComboPooledDataSource( boolean autoregister ) 15 | { super( autoregister ); } 16 | 17 | public ComboPooledDataSource(String configName) 18 | { super( configName ); } 19 | 20 | 21 | // serialization stuff -- set up bound/constrained property event handlers on deserialization 22 | private static final long serialVersionUID = 1; 23 | private static final short VERSION = 0x0002; 24 | 25 | private void writeObject( ObjectOutputStream oos ) throws IOException 26 | { 27 | oos.writeShort( VERSION ); 28 | } 29 | 30 | private void readObject( ObjectInputStream ois ) throws IOException, ClassNotFoundException 31 | { 32 | short version = ois.readShort(); 33 | switch (version) 34 | { 35 | case VERSION: 36 | //ok 37 | break; 38 | default: 39 | throw new IOException("Unsupported Serialized Version: " + version); 40 | } 41 | } 42 | } 43 | 44 | -------------------------------------------------------------------------------- /src/com/mchange/v2/c3p0/ConnectionCustomizer.java: -------------------------------------------------------------------------------- 1 | package com.mchange.v2.c3p0; 2 | 3 | import java.sql.Connection; 4 | import java.sql.SQLException; 5 | 6 | /** 7 | *Implementations of this interface should 8 | * be immutable, and should offer public, 9 | * no argument constructors.
10 | * 11 | *The methods are handed raw, physical 12 | * database Connections, not c3p0-generated 13 | * proxies.
14 | * 15 | *Although c3p0 will ensure this with 16 | * respect to state controlled by 17 | * standard JDBC methods, any modifications 18 | * of vendor-specific state shold be made 19 | * consistently so that all Connections 20 | * in the pool are interchangable.
21 | */ 22 | public interface ConnectionCustomizer 23 | { 24 | /** 25 | *Called immediately after a 26 | * Connection is acquired from the 27 | * underlying database for 28 | * incorporation into the pool.
29 | * 30 | *This method is only called once 31 | * per Connection. If standard JDBC 32 | * Connection properties are modified — 33 | * specifically catalog, holdability, transactionIsolation, 34 | * readOnly, and typeMap — those modifications 35 | * will override defaults throughout 36 | * the Connection's tenure in the 37 | * pool.
38 | */ 39 | public void onAcquire( Connection c, String parentDataSourceIdentityToken ) 40 | throws Exception; 41 | 42 | /** 43 | * Called immediately before a 44 | * Connection is destroyed after 45 | * being removed from the pool. 46 | */ 47 | public void onDestroy( Connection c, String parentDataSourceIdentityToken ) 48 | throws Exception; 49 | 50 | /** 51 | * Called immediately before a 52 | * Connection is made available to 53 | * a client upon checkout. 54 | */ 55 | public void onCheckOut( Connection c, String parentDataSourceIdentityToken ) 56 | throws Exception; 57 | 58 | /** 59 | * Called immediately after a 60 | * Connection is checked in, 61 | * prior to reincorporation 62 | * into the pool. 63 | */ 64 | public void onCheckIn( Connection c, String parentDataSourceIdentityToken ) 65 | throws Exception; 66 | } 67 | -------------------------------------------------------------------------------- /src/com/mchange/v2/c3p0/ConnectionTester.java: -------------------------------------------------------------------------------- 1 | package com.mchange.v2.c3p0; 2 | 3 | import java.io.Serializable; 4 | import java.sql.Connection; 5 | 6 | /** 7 | *Define your own Connection tester if you want to 8 | * override c3p0's default behavior for testing the validity 9 | * of Connections and responding to Connection errors encountered.
10 | * 11 | *Recommended: If you'd like your ConnectionTester
12 | * to support the user-configured preferredTestQuery
13 | * parameter, please implement {@link com.mchange.v2.c3p0.UnifiedConnectionTester}.
14 | *
15 | *
ConnectionTesters should be Serializable, immutable, 16 | * and must have public, no-arg constructors.
17 | * 18 | * @see com.mchange.v2.c3p0.UnifiedConnectionTester 19 | * @see com.mchange.v2.c3p0.AbstractConnectionTester 20 | */ 21 | public interface ConnectionTester extends Serializable 22 | { 23 | public final static int CONNECTION_IS_OKAY = 0; 24 | public final static int CONNECTION_IS_INVALID = -1; 25 | public final static int DATABASE_IS_INVALID = -8; 26 | 27 | public int activeCheckConnection(Connection c); 28 | 29 | public int statusOnException(Connection c, Throwable t); 30 | } 31 | -------------------------------------------------------------------------------- /src/com/mchange/v2/c3p0/FixedThreadPoolExecutorTaskRunnerFactory.java: -------------------------------------------------------------------------------- 1 | package com.mchange.v2.c3p0; 2 | 3 | import java.util.Timer; 4 | import java.util.concurrent.Executor; 5 | import java.util.concurrent.Executors; 6 | import java.util.concurrent.ThreadFactory; 7 | import javax.sql.ConnectionPoolDataSource; 8 | import com.mchange.v2.async.ThreadPoolReportingAsynchronousRunner; 9 | 10 | /** 11 | * This implementation supports all relevant config, includingnumHelperThreads
, maxAdministrativeTaskTime
,
12 | * contextClassLoaderSource
, and privilegeSpawnedThreads
.
13 | */
14 | public final class FixedThreadPoolExecutorTaskRunnerFactory extends AbstractExecutorTaskRunnerFactory
15 | {
16 | // for lazy initialization, called only on first-use
17 | protected Executor findCreateExecutor( TaskRunnerInit init )
18 | {
19 | ThreadFactory tf = new TaskRunnerThreadFactory( init.contextClassLoaderSourceIfSupported, init.privilege_spawned_threads_if_supported, init.threadLabelIfSupported, null );
20 | return Executors.newFixedThreadPool( init.num_threads_if_supported, tf );
21 | }
22 |
23 | protected boolean taskRunnerOwnsExecutor() { return true; }
24 |
25 | protected ThreadPoolReportingAsynchronousRunner createTaskRunner( TaskRunnerInit init, Timer timer )
26 | { return new FixedThreadPoolExecutorAsynchronousRunner( init, timer ); }
27 |
28 | protected final class FixedThreadPoolExecutorAsynchronousRunner extends AbstractExecutorAsynchronousRunner
29 | {
30 | protected FixedThreadPoolExecutorAsynchronousRunner( TaskRunnerInit init, Timer timer )
31 | { super( init, timer ); }
32 |
33 | public int getThreadCount() { return init.num_threads_if_supported; }
34 | public int getIdleCount() { return getThreadCount() - getActiveCount(); }
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/com/mchange/v2/c3p0/FullQueryConnectionTester.java:
--------------------------------------------------------------------------------
1 | package com.mchange.v2.c3p0;
2 |
3 | import java.sql.Connection;
4 |
5 | public interface FullQueryConnectionTester extends QueryConnectionTester
6 | {
7 | public int statusOnException(Connection c, Throwable t, String preferredTestQuery);
8 | }
9 |
10 |
--------------------------------------------------------------------------------
/src/com/mchange/v2/c3p0/PoolBackedDataSource.java:
--------------------------------------------------------------------------------
1 | package com.mchange.v2.c3p0;
2 |
3 | import com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource;
4 |
5 | public final class PoolBackedDataSource extends AbstractPoolBackedDataSource implements PooledDataSource
6 | {
7 | public PoolBackedDataSource( boolean autoregister )
8 | { super( autoregister ); }
9 |
10 | public PoolBackedDataSource()
11 | { this( true ); }
12 |
13 | public PoolBackedDataSource(String configName)
14 | {
15 | this();
16 | initializeNamedConfig( configName, false );
17 | }
18 |
19 | // no support for a longer form with config
20 | public String toString( boolean show_config ) { return this.toString(); }
21 |
22 | }
23 |
24 |
--------------------------------------------------------------------------------
/src/com/mchange/v2/c3p0/QueryConnectionTester.java:
--------------------------------------------------------------------------------
1 | package com.mchange.v2.c3p0;
2 |
3 | import java.sql.Connection;
4 |
5 | public interface QueryConnectionTester extends ConnectionTester
6 | {
7 | public int activeCheckConnection(Connection c, String preferredTestQuery);
8 | }
9 |
10 |
--------------------------------------------------------------------------------
/src/com/mchange/v2/c3p0/SQLWarnings.java:
--------------------------------------------------------------------------------
1 | package com.mchange.v2.c3p0;
2 |
3 | import java.sql.Connection;
4 | import java.sql.SQLException;
5 | import java.sql.SQLWarning;
6 |
7 | import com.mchange.v2.log.MLevel;
8 | import com.mchange.v2.log.MLog;
9 | import com.mchange.v2.log.MLogger;
10 |
11 | public final class SQLWarnings
12 | {
13 | final static MLogger logger = MLog.getLogger( SQLWarnings.class );
14 |
15 | public static void logAndClearWarnings(Connection con) throws SQLException
16 | {
17 | if (logger.isLoggable(MLevel.INFO))
18 | {
19 | for(SQLWarning w = con.getWarnings(); w != null; w = w.getNextWarning())
20 | logger.log(MLevel.INFO, w.getMessage(), w);
21 | }
22 | con.clearWarnings();
23 | }
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/src/com/mchange/v2/c3p0/TaskRunnerFactory.java:
--------------------------------------------------------------------------------
1 | package com.mchange.v2.c3p0;
2 |
3 | import java.util.Timer;
4 | import javax.sql.ConnectionPoolDataSource;
5 | import com.mchange.v2.async.*;
6 |
7 | /**
8 | * A TaskRunnerFactory should be an immutable class with a public, no-arg constructor, and implement equals and hashCode methods to help support canonicalization.
9 | *
10 | * The createTaskRunner
method will receive values for all supportable
11 | * configuration. It is up to the implementation to decide and document what config it can or cannot support.
12 | *
13 | * Implementations may find it convenient to capture configuration information as a {@link TaskRunnerInit}.
14 | */
15 | public interface TaskRunnerFactory
16 | {
17 | public ThreadPoolReportingAsynchronousRunner createTaskRunner(
18 | int num_threads_if_supported,
19 | int max_administrative_task_time_if_supported, // in seconds!
20 | String contextClassLoaderSourceIfSupported,
21 | boolean privilege_spawned_threads_if_supported,
22 | String threadLabelIfSupported,
23 | ConnectionPoolDataSource cpds,
24 | Timer timer
25 | );
26 | }
27 |
--------------------------------------------------------------------------------
/src/com/mchange/v2/c3p0/TaskRunnerInit.java:
--------------------------------------------------------------------------------
1 | package com.mchange.v2.c3p0;
2 |
3 | import java.util.*;
4 |
5 | /**
6 | * All fields will always be supplied from configuration and calling code,
7 | * the "if supported" stuff is just a reminder that TaskRunner implementations
8 | * need not and may not support the provided config.
9 | *
10 | * (It's a fine idea to log a note, if some config will be ignored!)
11 | */
12 | public final class TaskRunnerInit
13 | {
14 | public final int num_threads_if_supported;
15 | public final int max_administrative_task_time_if_supported; // in seconds!
16 | public final String contextClassLoaderSourceIfSupported;
17 | public final boolean privilege_spawned_threads_if_supported;
18 | public final String threadLabelIfSupported;
19 | public final Map otherProperties;
20 |
21 | public TaskRunnerInit (
22 | int num_threads_if_supported,
23 | int max_administrative_task_time_if_supported, // in seconds!
24 | String contextClassLoaderSourceIfSupported,
25 | boolean privilege_spawned_threads_if_supported,
26 | String threadLabelIfSupported,
27 | HashMap otherProperties
28 | )
29 | {
30 | this.num_threads_if_supported = num_threads_if_supported;
31 | this.max_administrative_task_time_if_supported = max_administrative_task_time_if_supported; // in seconds!
32 | this.contextClassLoaderSourceIfSupported = contextClassLoaderSourceIfSupported;
33 | this.privilege_spawned_threads_if_supported = privilege_spawned_threads_if_supported;
34 | this.threadLabelIfSupported = threadLabelIfSupported;
35 | this.otherProperties = Collections.unmodifiableMap( (HashMap) otherProperties.clone() );
36 | }
37 |
38 | public boolean equals( Object o )
39 | {
40 | if (o instanceof TaskRunnerInit)
41 | {
42 | TaskRunnerInit other = (TaskRunnerInit) o;
43 | return
44 | this.num_threads_if_supported == other.num_threads_if_supported &&
45 | this.max_administrative_task_time_if_supported == other.max_administrative_task_time_if_supported &&
46 | this.contextClassLoaderSourceIfSupported.equals( other.contextClassLoaderSourceIfSupported ) &&
47 | this.privilege_spawned_threads_if_supported == other.privilege_spawned_threads_if_supported &&
48 | this.threadLabelIfSupported.equals( other.threadLabelIfSupported ) &&
49 | this.otherProperties.equals(other.otherProperties);
50 | }
51 | else
52 | return false;
53 | }
54 |
55 | public int hashCode()
56 | {
57 | return
58 | this.num_threads_if_supported ^
59 | this.max_administrative_task_time_if_supported ^
60 | this.contextClassLoaderSourceIfSupported.hashCode() ^
61 | (this.privilege_spawned_threads_if_supported ? 1 : 0) ^
62 | this.threadLabelIfSupported.hashCode() ^
63 | this.otherProperties.hashCode();
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/src/com/mchange/v2/c3p0/TaskRunnerThreadFactory.java:
--------------------------------------------------------------------------------
1 | package com.mchange.v2.c3p0;
2 |
3 | import com.mchange.v2.log.*;
4 |
5 | import java.security.AccessController;
6 | import java.security.PrivilegedAction;
7 |
8 | import java.util.concurrent.ThreadFactory;
9 |
10 | public final class TaskRunnerThreadFactory implements ThreadFactory
11 | {
12 | private final static MLogger logger = MLog.getLogger( TaskRunnerThreadFactory.class );
13 |
14 | private final static ClassLoader LIBRARY_CLASSLOADER_INSTANCE = TaskRunnerThreadFactory.class.getClassLoader();
15 |
16 | private static interface ContextClassLoaderSetter
17 | {
18 | public void set(Thread t);
19 | }
20 |
21 | private final static ContextClassLoaderSetter NO_CLASSLOADER = new ContextClassLoaderSetter()
22 | {
23 | public void set(Thread t) { t.setContextClassLoader(null); }
24 | };
25 | private final static ContextClassLoaderSetter LIBRARY_CLASSLOADER = new ContextClassLoaderSetter()
26 | {
27 | public void set(Thread t) { t.setContextClassLoader(LIBRARY_CLASSLOADER_INSTANCE); }
28 | };
29 | private final static ContextClassLoaderSetter CALLER_CLASSLOADER = new ContextClassLoaderSetter()
30 | {
31 | public void set(Thread t) { /* t.setContextClassLoader(Thread.currentThread().getContextClassLoader()); */ } // just let it propogate, it's the default
32 | };
33 |
34 | //MT: Unchanging post-constuctor
35 | ContextClassLoaderSetter contextClassLoaderSetter;
36 | boolean privilege_spawned_threads;
37 | String threadLabel;
38 | ThreadGroup threadGroup;
39 |
40 | //MT: Protected by this' lock
41 | int count = 0;
42 |
43 | public TaskRunnerThreadFactory( String contextClassLoaderSource, boolean privilege_spawned_threads, String threadLabel, ThreadGroup threadGroup /* can be null */ )
44 | {
45 | if ("none".equalsIgnoreCase(contextClassLoaderSource))
46 | this.contextClassLoaderSetter = NO_CLASSLOADER;
47 | else if ("library".equalsIgnoreCase(contextClassLoaderSource))
48 | this.contextClassLoaderSetter = LIBRARY_CLASSLOADER;
49 | else
50 | {
51 | if ( logger.isLoggable( MLevel.WARNING ) && ! "caller".equalsIgnoreCase( contextClassLoaderSource ) )
52 | logger.log( MLevel.WARNING, "Unknown contextClassLoaderSource: " + contextClassLoaderSource + " -- should be 'caller', 'library', or 'none'. Using default value 'caller'." );
53 | this.contextClassLoaderSetter = CALLER_CLASSLOADER;
54 | }
55 | this.privilege_spawned_threads = privilege_spawned_threads;
56 | this.threadLabel = threadLabel;
57 | this.threadGroup = threadGroup;
58 | }
59 |
60 | private synchronized int nextCount()
61 | { return ++count; }
62 |
63 | private Thread createUnprivileged(Runnable r)
64 | {
65 | Thread out = new Thread(threadGroup, r, threadLabel + "-" + nextCount());
66 | contextClassLoaderSetter.set(out);
67 | return out;
68 | }
69 |
70 | public Thread newThread(final Runnable r)
71 | {
72 | if ( privilege_spawned_threads )
73 | {
74 | PrivilegedAction privilegedRun = new PrivilegedAction()
75 | {
76 | public Object run() { return createUnprivileged(r); }
77 | };
78 | return (Thread) AccessController.doPrivileged( privilegedRun );
79 | }
80 | else
81 | return createUnprivileged(r);
82 | }
83 | }
84 |
85 |
--------------------------------------------------------------------------------
/src/com/mchange/v2/c3p0/UnifiedConnectionTester.java:
--------------------------------------------------------------------------------
1 | package com.mchange.v2.c3p0;
2 |
3 | import java.sql.Connection;
4 |
5 | /**
6 | * Having expanded the once-simple ConnectionTester interface to support both 7 | * user-specified queries and return of root cause Exceptions (via an out-param), 8 | * this interface has grown unnecessarily complex.
9 | * 10 | *If you wish to implement a custom Connection tester, here is the simple 11 | * way to do it
12 | * 13 | *public int activeCheckConnection(Connection c, String preferredTestQuery, Throwable[] rootCauseOutParamHolder)
public int statusOnException(Connection c, Throwable t, String preferredTestQuery, Throwable[] rootCauseOutParamHolder)
preferredTestQuery
and
23 | * rootCauseOutParamHolder
to be null
.Parameter rootCauseOutParamHolder
is an optional parameter, which if supplied, will be a Throwable array whose size
27 | * it at least one. If a Connection test fails because of some Exception, the Connection tester may set this Exception as the
28 | * zero-th element of the array to provide information about why and how the test failed.
For the meaning of most of these properties, please see c3p0's top-level documentation!
11 | */ 12 | public final class AfterCloseLoggingComboPooledDataSource extends AbstractComboPooledDataSource implements Serializable, Referenceable 13 | { 14 | public AfterCloseLoggingComboPooledDataSource() 15 | { super(); } 16 | 17 | public AfterCloseLoggingComboPooledDataSource( boolean autoregister ) 18 | { super( autoregister ); } 19 | 20 | public AfterCloseLoggingComboPooledDataSource(String configName) 21 | { super( configName ); } 22 | 23 | public Connection getConnection() throws SQLException 24 | { return AfterCloseLoggingConnectionWrapper.wrap( super.getConnection() ); } 25 | 26 | public Connection getConnection(String user, String password) throws SQLException 27 | { return AfterCloseLoggingConnectionWrapper.wrap( super.getConnection(user, password) ); } 28 | 29 | // serialization stuff 30 | private static final long serialVersionUID = 1; 31 | private static final short VERSION = 0x0001; 32 | 33 | private void writeObject( ObjectOutputStream oos ) throws IOException 34 | { 35 | oos.writeShort( VERSION ); 36 | } 37 | 38 | private void readObject( ObjectInputStream ois ) throws IOException, ClassNotFoundException 39 | { 40 | short version = ois.readShort(); 41 | switch (version) 42 | { 43 | case VERSION: 44 | //ok 45 | break; 46 | default: 47 | throw new IOException("Unsupported Serialized Version: " + version); 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/com/mchange/v2/c3p0/debug/AfterCloseLoggingConnectionWrapper.java: -------------------------------------------------------------------------------- 1 | package com.mchange.v2.c3p0.debug; 2 | 3 | import java.lang.reflect.*; 4 | import java.sql.*; 5 | import com.mchange.v2.log.*; 6 | import com.mchange.v2.c3p0.*; 7 | import com.mchange.v2.reflect.*; 8 | import com.mchange.v2.sql.filter.*; 9 | 10 | public class AfterCloseLoggingConnectionWrapper extends FilterConnection 11 | { 12 | final static MLogger logger = MLog.getLogger( AfterCloseLoggingConnectionWrapper.class ); 13 | 14 | public static Connection wrap( Connection inner ) 15 | { 16 | try 17 | { 18 | Constructor ctor = ReflectUtils.findProxyConstructor( AfterCloseLoggingConnectionWrapper.class.getClassLoader(), Connection.class ); 19 | return (Connection) ctor.newInstance( new AfterCloseLoggingInvocationHandler( inner ) ); 20 | } 21 | catch ( Exception e ) 22 | { 23 | if ( logger.isLoggable( MLevel.SEVERE ) ) 24 | logger.log( MLevel.SEVERE, "An unexpected Exception occured while trying to instantiate a dynamic proxy.", e ); 25 | 26 | throw new RuntimeException( e ); 27 | } 28 | } 29 | 30 | private static class AfterCloseLoggingInvocationHandler implements InvocationHandler 31 | { 32 | final Connection inner; 33 | 34 | volatile SQLWarning closeStackTrace = null; 35 | 36 | AfterCloseLoggingInvocationHandler( Connection inner ) 37 | { this.inner = inner; } 38 | 39 | public Object invoke(Object proxy, Method method, Object[] args) throws Throwable 40 | { 41 | if ( "close".equals( method.getName() ) && closeStackTrace == null ) 42 | closeStackTrace = new SQLWarning("DEBUG STACK TRACE -- " + inner + ".close() first-call stack trace."); 43 | else if ( closeStackTrace != null ) 44 | { 45 | if ( logger.isLoggable( MLevel.INFO ) ) 46 | logger.log( MLevel.INFO, String.format("Method '%s' called after call to Connection close().", method) ); 47 | if ( logger.isLoggable( MLevel.FINE ) ) 48 | { 49 | logger.log( MLevel.FINE, "After-close() method call stack trace:", new SQLWarning("DEBUG STACK TRACE -- ILLEGAL use of " + inner + " after call to close()." ) ); 50 | logger.log( MLevel.FINE, "Original close() call stack trace:", closeStackTrace ); 51 | } 52 | } 53 | 54 | return method.invoke( inner, args ); 55 | } 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /src/com/mchange/v2/c3p0/debug/CloseLoggingComboPooledDataSource.java: -------------------------------------------------------------------------------- 1 | package com.mchange.v2.c3p0.debug; 2 | 3 | import java.io.*; 4 | import java.sql.*; 5 | import javax.naming.*; 6 | import com.mchange.v2.log.*; 7 | import com.mchange.v2.c3p0.*; 8 | 9 | /** 10 | *For the meaning of most of these properties, please see c3p0's top-level documentation!
11 | */ 12 | public final class CloseLoggingComboPooledDataSource extends AbstractComboPooledDataSource implements Serializable, Referenceable 13 | { 14 | volatile MLevel level = MLevel.INFO; 15 | 16 | public void setCloseLogLevel( MLevel level ) { this.level = level; } 17 | public MLevel getCloseLogLevel() { return level; } 18 | 19 | public CloseLoggingComboPooledDataSource() 20 | { super(); } 21 | 22 | public CloseLoggingComboPooledDataSource( boolean autoregister ) 23 | { super( autoregister ); } 24 | 25 | public CloseLoggingComboPooledDataSource(String configName) 26 | { super( configName ); } 27 | 28 | public Connection getConnection() throws SQLException 29 | { return new CloseLoggingConnectionWrapper( super.getConnection(), level ); } 30 | 31 | public Connection getConnection(String user, String password) throws SQLException 32 | { return new CloseLoggingConnectionWrapper( super.getConnection(user, password), level ); } 33 | 34 | // serialization stuff -- set up bound/constrained property event handlers on deserialization 35 | private static final long serialVersionUID = 1; 36 | private static final short VERSION = 0x0001; 37 | 38 | private void writeObject( ObjectOutputStream oos ) throws IOException 39 | { 40 | oos.writeShort( VERSION ); 41 | } 42 | 43 | private void readObject( ObjectInputStream ois ) throws IOException, ClassNotFoundException 44 | { 45 | short version = ois.readShort(); 46 | switch (version) 47 | { 48 | case VERSION: 49 | //ok 50 | break; 51 | default: 52 | throw new IOException("Unsupported Serialized Version: " + version); 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/com/mchange/v2/c3p0/debug/CloseLoggingConnectionWrapper.java: -------------------------------------------------------------------------------- 1 | package com.mchange.v2.c3p0.debug; 2 | 3 | import java.sql.*; 4 | import com.mchange.v2.log.*; 5 | import com.mchange.v2.c3p0.*; 6 | import com.mchange.v2.sql.filter.*; 7 | 8 | public class CloseLoggingConnectionWrapper extends FilterConnection 9 | { 10 | final static MLogger logger = MLog.getLogger( CloseLoggingConnectionWrapper.class ); 11 | 12 | final MLevel level; 13 | 14 | public CloseLoggingConnectionWrapper( Connection conn, MLevel level ) 15 | { 16 | super( conn ); 17 | this.level = level; 18 | } 19 | 20 | public void close() throws SQLException 21 | { 22 | super.close(); 23 | if ( logger.isLoggable( level ) ) 24 | logger.log( level, "DEBUG: A Connection has closed been close()ed without error.", new SQLWarning("DEBUG STACK TRACE -- Connection.close() was called.") ); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/com/mchange/v2/c3p0/debug/ConstructionLoggingComboPooledDataSource.java: -------------------------------------------------------------------------------- 1 | package com.mchange.v2.c3p0.debug; 2 | 3 | import java.io.*; 4 | import java.sql.*; 5 | import javax.naming.*; 6 | import com.mchange.v2.log.*; 7 | import com.mchange.v2.c3p0.*; 8 | 9 | /** 10 | *For the meaning of most of these properties, please see c3p0's top-level documentation!
11 | */ 12 | public final class ConstructionLoggingComboPooledDataSource extends AbstractComboPooledDataSource implements Serializable, Referenceable 13 | { 14 | final static MLogger logger = MLog.getLogger( ConstructionLoggingComboPooledDataSource.class ); 15 | 16 | public ConstructionLoggingComboPooledDataSource() 17 | { 18 | super(); 19 | if ( logger.isLoggable( MLevel.FINE ) ) 20 | logger.log( MLevel.FINE, 21 | "Creation of ConstructionLoggingComboPooledDataSource.", 22 | new Exception("DEBUG STACK TRACE -- CREATION OF ConstructionLoggingComboPooledDataSource") ); 23 | } 24 | 25 | public ConstructionLoggingComboPooledDataSource( boolean autoregister ) 26 | { 27 | super( autoregister ); 28 | if ( logger.isLoggable( MLevel.FINE ) ) 29 | logger.log( MLevel.FINE, 30 | "Creation of ConstructionLoggingComboPooledDataSource.", 31 | new Exception("DEBUG STACK TRACE -- CREATION OF ConstructionLoggingComboPooledDataSource") ); 32 | } 33 | 34 | public ConstructionLoggingComboPooledDataSource(String configName) 35 | { 36 | super( configName ); 37 | if ( logger.isLoggable( MLevel.FINE ) ) 38 | logger.log( MLevel.FINE, 39 | "Creation of ConstructionLoggingComboPooledDataSource.", 40 | new Exception("DEBUG STACK TRACE -- CREATION OF ConstructionLoggingComboPooledDataSource") ); 41 | } 42 | 43 | // serialization stuff 44 | private static final long serialVersionUID = 1; 45 | private static final short VERSION = 0x0001; 46 | 47 | private void writeObject( ObjectOutputStream oos ) throws IOException 48 | { 49 | oos.writeShort( VERSION ); 50 | } 51 | 52 | private void readObject( ObjectInputStream ois ) throws IOException, ClassNotFoundException 53 | { 54 | short version = ois.readShort(); 55 | switch (version) 56 | { 57 | case VERSION: 58 | //ok 59 | break; 60 | default: 61 | throw new IOException("Unsupported Serialized Version: " + version); 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/com/mchange/v2/c3p0/example/InitSqlConnectionCustomizer.java: -------------------------------------------------------------------------------- 1 | package com.mchange.v2.c3p0.example; 2 | 3 | import java.sql.*; 4 | import com.mchange.v2.log.*; 5 | import com.mchange.v2.c3p0.AbstractConnectionCustomizer; 6 | 7 | public class InitSqlConnectionCustomizer extends AbstractConnectionCustomizer 8 | { 9 | final static MLogger logger = MLog.getLogger( InitSqlConnectionCustomizer.class ); 10 | 11 | private String getInitSql( String parentDataSourceIdentityToken ) 12 | { return (String) extensionsForToken( parentDataSourceIdentityToken ).get ( "initSql" ); } 13 | 14 | public void onCheckOut( Connection c, String parentDataSourceIdentityToken ) throws Exception 15 | { 16 | String initSql = getInitSql( parentDataSourceIdentityToken ); 17 | if ( initSql != null ) 18 | { 19 | Statement stmt = null; 20 | try 21 | { 22 | stmt = c.createStatement(); 23 | int num = stmt.executeUpdate( initSql ); 24 | if ( logger.isLoggable( MLevel.FINEST ) ) 25 | logger.log( MLevel.FINEST, "Initialized checked-out Connection '" + c + "' with initSql '" + initSql + "'. Return value: " + num ); 26 | } 27 | finally 28 | { if ( stmt != null ) stmt.close(); } 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/com/mchange/v2/c3p0/example/IsValidOnlyConnectionTester30.java: -------------------------------------------------------------------------------- 1 | package com.mchange.v2.c3p0.example; 2 | 3 | import com.mchange.v2.c3p0.util.IsValidOnlyConnectionTester; 4 | 5 | public final class IsValidOnlyConnectionTester30 extends IsValidOnlyConnectionTester 6 | { 7 | protected int getIsValidTimeout() { return 30; } 8 | } 9 | -------------------------------------------------------------------------------- /src/com/mchange/v2/c3p0/filter/FilterDataSource.java: -------------------------------------------------------------------------------- 1 | package com.mchange.v2.c3p0.filter; 2 | 3 | import java.io.PrintWriter; 4 | import java.lang.String; 5 | import java.sql.Connection; 6 | import java.sql.SQLException; 7 | import javax.sql.DataSource; 8 | 9 | 10 | public abstract class FilterDataSource implements DataSource 11 | { 12 | protected DataSource inner; 13 | 14 | public FilterDataSource(DataSource inner) 15 | { 16 | this.inner = inner; 17 | } 18 | 19 | public Connection getConnection() throws SQLException 20 | { 21 | return inner.getConnection(); 22 | } 23 | 24 | public Connection getConnection(String a, String b) throws SQLException 25 | { 26 | return inner.getConnection(a, b); 27 | } 28 | 29 | public PrintWriter getLogWriter() throws SQLException 30 | { 31 | return inner.getLogWriter(); 32 | } 33 | 34 | public int getLoginTimeout() throws SQLException 35 | { 36 | return inner.getLoginTimeout(); 37 | } 38 | 39 | public void setLogWriter(PrintWriter a) throws SQLException 40 | { 41 | inner.setLogWriter(a); 42 | } 43 | 44 | public void setLoginTimeout(int a) throws SQLException 45 | { 46 | inner.setLoginTimeout(a); 47 | } 48 | 49 | } 50 | 51 | -------------------------------------------------------------------------------- /src/com/mchange/v2/c3p0/impl/AbstractC3P0PooledConnection.java: -------------------------------------------------------------------------------- 1 | package com.mchange.v2.c3p0.impl; 2 | 3 | import java.sql.Connection; 4 | import java.sql.SQLException; 5 | import javax.sql.PooledConnection; 6 | import java.util.concurrent.locks.ReentrantLock; 7 | import com.mchange.v2.c3p0.stmt.GooGooStatementCache; 8 | import com.mchange.v1.util.ClosableResource; 9 | 10 | abstract class AbstractC3P0PooledConnection implements PooledConnection, ClosableResource 11 | { 12 | // thread-safe post c'tor constant, accessed directly by C3P0PooledConnectionPool 13 | // since the StatementCache "in-use" marker doesn't nest, we have to ensure that 14 | // internal Connection tests don't overlap. (External use, due to checkout, 15 | // is no problem, no internal operation are performed on checked-out PooledConnections 16 | final ReentrantLock inInternalUseLock = new ReentrantLock(); 17 | 18 | abstract Connection getPhysicalConnection(); 19 | abstract void initStatementCache(GooGooStatementCache scache); 20 | abstract void closeMaybeCheckedOut( boolean checked_out ) throws SQLException; 21 | } 22 | -------------------------------------------------------------------------------- /src/com/mchange/v2/c3p0/impl/AbstractIdentityTokenized.java: -------------------------------------------------------------------------------- 1 | package com.mchange.v2.c3p0.impl; 2 | /* 3 | * It would be convenient to put the getter/setter methods 4 | * for the identity token here, but unfortunately we have no 5 | * way of setting up the for Referenceability in multiple 6 | * levels of a class hierarchy. So we leave the getters/setters, 7 | * and variable initialization to code-generators. 8 | */ 9 | public abstract class AbstractIdentityTokenized implements IdentityTokenized 10 | { 11 | public boolean equals(Object o) 12 | { 13 | if (this == o) 14 | return true; 15 | 16 | if (o instanceof IdentityTokenized) 17 | return this.getIdentityToken().equals( ((IdentityTokenized) o).getIdentityToken() ); 18 | else 19 | return false; 20 | } 21 | 22 | public int hashCode() 23 | { return ~this.getIdentityToken().hashCode(); } 24 | } 25 | -------------------------------------------------------------------------------- /src/com/mchange/v2/c3p0/impl/AuthMaskingProperties.java: -------------------------------------------------------------------------------- 1 | package com.mchange.v2.c3p0.impl; 2 | 3 | import java.util.Enumeration; 4 | import java.util.Properties; 5 | 6 | public class AuthMaskingProperties extends Properties 7 | { 8 | public AuthMaskingProperties() 9 | { super(); } 10 | 11 | public AuthMaskingProperties( Properties p ) 12 | { super( p ); } 13 | 14 | public static AuthMaskingProperties fromAnyProperties( Properties p ) 15 | { 16 | AuthMaskingProperties out = new AuthMaskingProperties(); 17 | for( Enumeration e = p.propertyNames(); e.hasMoreElements(); ) 18 | { 19 | String key = (String) e.nextElement(); 20 | out.setProperty( key, p.getProperty( key ) ); 21 | } 22 | return out; 23 | } 24 | 25 | private String normalToString() 26 | { return super.toString(); } 27 | 28 | public String toString() 29 | { 30 | boolean hasUser = (this.get("user") != null); 31 | boolean hasPassword = (this.get("password") != null); 32 | if ( hasUser || hasPassword ) 33 | { 34 | AuthMaskingProperties clone = (AuthMaskingProperties) this.clone(); 35 | if (hasUser) 36 | clone.put("user", "******"); 37 | if (hasPassword) 38 | clone.put("password", "******"); 39 | return clone.normalToString(); 40 | } 41 | else 42 | return this.normalToString(); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/com/mchange/v2/c3p0/impl/C3P0JavaBeanObjectFactory.java: -------------------------------------------------------------------------------- 1 | package com.mchange.v2.c3p0.impl; 2 | 3 | import java.lang.reflect.Constructor; 4 | import java.util.Map; 5 | import java.util.Set; 6 | import com.mchange.v2.c3p0.C3P0Registry; 7 | import com.mchange.v2.naming.JavaBeanObjectFactory; 8 | 9 | public class C3P0JavaBeanObjectFactory extends JavaBeanObjectFactory 10 | { 11 | private final static Class[] CTOR_ARG_TYPES = new Class[] { boolean.class }; 12 | private final static Object[] CTOR_ARGS = new Object[] { Boolean.FALSE }; 13 | 14 | protected Object createBlankInstance(Class beanClass) throws Exception 15 | { 16 | if ( IdentityTokenized.class.isAssignableFrom( beanClass ) ) 17 | { 18 | Constructor ctor = beanClass.getConstructor( CTOR_ARG_TYPES ); 19 | return ctor.newInstance( CTOR_ARGS ); 20 | } 21 | else 22 | return super.createBlankInstance( beanClass ); 23 | } 24 | 25 | protected Object findBean(Class beanClass, Map propertyMap, Set refProps ) throws Exception 26 | { 27 | Object out = super.findBean( beanClass, propertyMap, refProps ); 28 | if (out instanceof IdentityTokenized) 29 | out = C3P0Registry.reregister( (IdentityTokenized) out ); 30 | //System.err.println("--> findBean()"); 31 | //System.err.println(out); 32 | return out; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/com/mchange/v2/c3p0/impl/ConnectionTestPath.java: -------------------------------------------------------------------------------- 1 | package com.mchange.v2.c3p0.impl; 2 | 3 | import java.sql.Connection; 4 | import javax.sql.PooledConnection; 5 | 6 | interface ConnectionTestPath 7 | { 8 | // if proxyConn is provided, just test it. 9 | // if not, we have to get a proxy Connection from the PooledConnection, 10 | // then be sure to close() or detach the proxy 11 | public void testPooledConnection(PooledConnection pc, Connection proxyConn) throws Exception; 12 | } 13 | -------------------------------------------------------------------------------- /src/com/mchange/v2/c3p0/impl/DbAuth.java: -------------------------------------------------------------------------------- 1 | package com.mchange.v2.c3p0.impl; 2 | 3 | import java.io.*; 4 | import com.mchange.v2.lang.ObjectUtils; 5 | import com.mchange.v2.ser.UnsupportedVersionException; 6 | 7 | public final class DbAuth implements Serializable 8 | { 9 | transient String username; 10 | transient String password; 11 | 12 | public DbAuth(String username, String password) 13 | { 14 | this.username = username; 15 | this.password = password; 16 | } 17 | 18 | public String getUser() 19 | { return username; } 20 | 21 | public String getPassword() 22 | { return password; } 23 | 24 | public String getMaskedUserString() 25 | { return getMaskedUserString(2, 8); } 26 | 27 | private String getMaskedUserString( int chars_to_reveal, int total_chars ) 28 | { 29 | if ( username == null ) return "null"; 30 | else 31 | { 32 | StringBuffer sb = new StringBuffer(32); 33 | if ( username.length() >= chars_to_reveal ) 34 | { 35 | sb.append( username.substring(0, chars_to_reveal) ); 36 | for (int i = 0, len = total_chars - chars_to_reveal; i < len; ++i) 37 | sb.append('*'); 38 | } 39 | else 40 | sb.append( username ); 41 | return sb.toString(); 42 | } 43 | } 44 | 45 | public boolean equals(Object o) 46 | { 47 | if (this == o) 48 | return true; 49 | else if (o != null && this.getClass() == o.getClass()) 50 | { 51 | DbAuth other = (DbAuth) o; 52 | return 53 | ObjectUtils.eqOrBothNull(this.username, other.username) && 54 | ObjectUtils.eqOrBothNull(this.password, other.password); 55 | } 56 | else 57 | return false; 58 | } 59 | 60 | public int hashCode() 61 | { 62 | return 63 | ObjectUtils.hashOrZero(username) ^ 64 | ObjectUtils.hashOrZero(password); 65 | } 66 | 67 | //Serialization 68 | static final long serialVersionUID = 1; //override to take control of versioning 69 | private final static short VERSION = 0x0001; 70 | 71 | private void writeObject(ObjectOutputStream out) throws IOException 72 | { 73 | out.writeShort(VERSION); 74 | out.writeObject(username); //may be null 75 | out.writeObject(password); //may be null 76 | } 77 | 78 | private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException 79 | { 80 | short version = in.readShort(); 81 | switch (version) 82 | { 83 | case 0x0001: 84 | this.username = (String) in.readObject(); 85 | this.password = (String) in.readObject(); 86 | break; 87 | default: 88 | throw new UnsupportedVersionException(this, version); 89 | } 90 | } 91 | } 92 | 93 | 94 | 95 | 96 | 97 | -------------------------------------------------------------------------------- /src/com/mchange/v2/c3p0/impl/DefaultTaskRunnerFactory.java: -------------------------------------------------------------------------------- 1 | package com.mchange.v2.c3p0.impl; 2 | 3 | import java.util.Timer; 4 | import javax.sql.ConnectionPoolDataSource; 5 | import com.mchange.v2.async.*; 6 | import com.mchange.v2.c3p0.TaskRunnerFactory; 7 | 8 | public final class DefaultTaskRunnerFactory implements TaskRunnerFactory 9 | { 10 | public ThreadPoolReportingAsynchronousRunner createTaskRunner( 11 | final int num_threads, 12 | final int matt, // maxAdministrativeTaskTime, in seconds 13 | final String contextClassLoaderSource, 14 | final boolean privilege_spawned_threads, 15 | final String threadLabel, 16 | final ConnectionPoolDataSource cpds, 17 | final Timer timer 18 | ) 19 | { 20 | // we use the array as holder, because we need a final variable for the innner class 21 | final ThreadPoolAsynchronousRunner[] outHolder = new ThreadPoolAsynchronousRunner[1]; 22 | 23 | Runnable initializer = new Runnable() 24 | { 25 | public void run() 26 | { 27 | if ( matt > 0 ) 28 | { 29 | int matt_ms = matt * 1000; 30 | outHolder[0] = new ThreadPoolAsynchronousRunner( num_threads, 31 | true, // daemon thread 32 | matt_ms, // wait before interrupt() 33 | matt_ms * 3, // wait before deadlock declared if no tasks clear 34 | matt_ms * 6, // wait before deadlock tasks are interrupted (again) 35 | // after the hung thread has been cleared and replaced 36 | // (in hopes of getting the thread to terminate for 37 | // garbage collection) 38 | timer, 39 | threadLabel ); 40 | } 41 | else 42 | outHolder[0] = new ThreadPoolAsynchronousRunner( num_threads, true, timer, threadLabel ); 43 | } 44 | }; 45 | C3P0ImplUtils.runWithContextClassLoaderAndPrivileges( contextClassLoaderSource, privilege_spawned_threads, initializer ); 46 | 47 | return outHolder[0]; 48 | } 49 | 50 | public boolean equals( Object o ) { return this.getClass().equals( o.getClass() ); } 51 | public int hashCode() { return this.getClass().getName().hashCode(); } 52 | } 53 | -------------------------------------------------------------------------------- /src/com/mchange/v2/c3p0/impl/IdentityTokenResolvable.java: -------------------------------------------------------------------------------- 1 | package com.mchange.v2.c3p0.impl; 2 | 3 | import com.mchange.v2.c3p0.*; 4 | import java.io.ObjectStreamException; 5 | 6 | /** 7 | * This is a convenient base class for all classes 8 | * that wish to establish an initial identity which 9 | * will be the basis of a one-per vm identity: i.e. 10 | * in any vm there should only ever be a single object 11 | * with a given identity token (except transiently during 12 | * canonicalization) 13 | * 14 | * It would be convenient to put the getter/setter methods 15 | * for the identity token here, but unfortunately we have no 16 | * way of setting up the for Referenceability in multiple 17 | * levels of a class hierarchy. So we leave the getters/setters, 18 | * and variable initialization to code-generators. 19 | */ 20 | public abstract class IdentityTokenResolvable extends AbstractIdentityTokenized 21 | { 22 | public static Object doResolve(IdentityTokenized itd) 23 | { return C3P0Registry.reregister( itd ); } 24 | 25 | protected Object readResolve() throws ObjectStreamException 26 | { 27 | //System.err.println("READ RESOLVE!!!!"); 28 | Object out = doResolve( this ); 29 | verifyResolve( out ); 30 | //System.err.println("ORIG: " + this); 31 | //System.err.println("RSLV: " + out); 32 | return out; 33 | } 34 | 35 | protected void verifyResolve( Object o ) throws ObjectStreamException 36 | {} 37 | } 38 | -------------------------------------------------------------------------------- /src/com/mchange/v2/c3p0/impl/IdentityTokenized.java: -------------------------------------------------------------------------------- 1 | package com.mchange.v2.c3p0.impl; 2 | 3 | public interface IdentityTokenized 4 | { 5 | public String getIdentityToken(); 6 | public void setIdentityToken(String idToken); 7 | } 8 | -------------------------------------------------------------------------------- /src/com/mchange/v2/c3p0/impl/IdentityTokenizedCoalesceChecker.java: -------------------------------------------------------------------------------- 1 | package com.mchange.v2.c3p0.impl; 2 | 3 | import com.mchange.v2.coalesce.*; 4 | 5 | public final class IdentityTokenizedCoalesceChecker implements CoalesceChecker 6 | { 7 | public static IdentityTokenizedCoalesceChecker INSTANCE = new IdentityTokenizedCoalesceChecker(); 8 | 9 | public boolean checkCoalesce( Object a, Object b ) 10 | { 11 | IdentityTokenized aa = (IdentityTokenized) a; 12 | IdentityTokenized bb = (IdentityTokenized) b; 13 | 14 | String ta = aa.getIdentityToken(); 15 | String tb = bb.getIdentityToken(); 16 | 17 | if (ta == null || tb == null) 18 | throw new NullPointerException( "[c3p0 bug] An IdentityTokenized object has no identity token set?!?! " + (ta == null ? ta : tb) ); 19 | else 20 | return ta.equals(tb); 21 | } 22 | 23 | public int coalesceHash( Object a ) 24 | { 25 | String t = ((IdentityTokenized) a).getIdentityToken(); 26 | return (t != null ? t.hashCode() : 0); 27 | } 28 | 29 | private IdentityTokenizedCoalesceChecker() 30 | {} 31 | } 32 | -------------------------------------------------------------------------------- /src/com/mchange/v2/c3p0/impl/InternalPooledConnection.java: -------------------------------------------------------------------------------- 1 | package com.mchange.v2.c3p0.impl; 2 | 3 | import javax.sql.*; 4 | import com.mchange.v2.c3p0.stmt.*; 5 | 6 | interface InternalPooledConnection extends PooledConnection 7 | { 8 | public void initStatementCache( GooGooStatementCache scache ); 9 | public GooGooStatementCache getStatementCache(); 10 | public int getConnectionStatus(); 11 | } 12 | -------------------------------------------------------------------------------- /src/com/mchange/v2/c3p0/impl/IsValidSimplifiedConnectionTestPath.java: -------------------------------------------------------------------------------- 1 | package com.mchange.v2.c3p0.impl; 2 | 3 | import java.sql.Connection; 4 | import java.sql.SQLException; 5 | import javax.sql.PooledConnection; 6 | 7 | import com.mchange.v1.db.sql.ConnectionUtils; 8 | 9 | import com.mchange.v2.c3p0.*; 10 | import com.mchange.v2.log.*; 11 | import com.mchange.v2.resourcepool.*; 12 | 13 | 14 | final class IsValidSimplifiedConnectionTestPath implements ConnectionTestPath 15 | { 16 | private final static MLogger logger = MLog.getLogger( IsValidSimplifiedConnectionTestPath.class ); 17 | 18 | private final ResourcePool rp; 19 | private final int isValidTimeout; 20 | 21 | IsValidSimplifiedConnectionTestPath( ResourcePool rp, final int isValidTimeout ) 22 | { 23 | this.rp = rp; 24 | 25 | if (isValidTimeout < 0) 26 | { 27 | if (logger.isLoggable(MLevel.WARNING)) 28 | logger.log(MLevel.WARNING, "Negative values of connectionIsValidTimeout are not supported. Using default value of " + C3P0Defaults.connectionIsValidTimeout()); 29 | this.isValidTimeout = C3P0Defaults.connectionIsValidTimeout(); 30 | } 31 | else 32 | this.isValidTimeout = isValidTimeout; 33 | } 34 | 35 | public void testPooledConnection(PooledConnection pc, Connection proxyConn) throws Exception 36 | { 37 | if (proxyConn != null) 38 | doTestConnection( proxyConn ); 39 | else 40 | { 41 | Connection conn = null; 42 | try 43 | { 44 | conn = pc.getConnection(); 45 | doTestConnection( conn ); 46 | } 47 | finally 48 | { ConnectionUtils.attemptClose( conn ); } 49 | } 50 | } 51 | 52 | private void doTestConnection( Connection conn ) throws Exception 53 | { 54 | try 55 | { 56 | if (!conn.isValid( isValidTimeout )) 57 | throw new SQLException("Connection is invalid. (isValid returned false)."); 58 | } 59 | catch (SQLException e) 60 | { 61 | if ( DefaultConnectionTester.probableInvalidDb(e) ) 62 | rp.resetPool(); 63 | throw e; 64 | } 65 | catch (Exception e) // some unexpected Exception 66 | { 67 | // we might consider resetting the pool for entirely unexpected Exceptions. 68 | // It's arguable, but DefaultConnectionTester traditionally has not, we'll not upset 69 | // upgraders' expectations at least for now 70 | if ( logger.isLoggable( MLevel.FINER ) ) 71 | logger.log(MLevel.FINER, "An unexpected Exception occurred while testing a Connection.", e); 72 | throw e; 73 | } 74 | } 75 | 76 | public static int isValidTestConnectionForStatusOnly( Connection conn, int isValidTimeout ) 77 | { 78 | try 79 | { 80 | if (conn.isValid( isValidTimeout )) 81 | return ConnectionTester.CONNECTION_IS_OKAY; 82 | else 83 | return ConnectionTester.CONNECTION_IS_INVALID; 84 | } 85 | catch (SQLException e) 86 | { 87 | if ( DefaultConnectionTester.probableInvalidDb(e) ) 88 | return ConnectionTester.DATABASE_IS_INVALID; 89 | else 90 | return ConnectionTester.CONNECTION_IS_INVALID; 91 | } 92 | catch (Exception e) // some unexpected Exception 93 | { 94 | // we might consider resetting the pool for entirely unexpected Exceptions. 95 | // It's arguable, but DefaultConnectionTester traditionally has not, we'll not upset 96 | // upgraders expectations at least for now 97 | if ( logger.isLoggable( MLevel.FINER ) ) 98 | logger.log(MLevel.FINER, "An unexpected Exception occurred while testing a Connection.", e); 99 | return ConnectionTester.CONNECTION_IS_INVALID; 100 | } 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /src/com/mchange/v2/c3p0/impl/NullStatementSetManagedResultSet.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Created on Apr 6, 2004 3 | * 4 | * To change the template for this generated file go to 5 | * Window>Preferences>Java>Code Generation>Code and Comments 6 | */ 7 | package com.mchange.v2.c3p0.impl; 8 | 9 | import java.sql.ResultSet; 10 | import java.sql.Statement; 11 | import java.util.Set; 12 | 13 | 14 | final class NullStatementSetManagedResultSet extends SetManagedResultSet 15 | { 16 | NullStatementSetManagedResultSet(Set activeResultSets) 17 | { super( activeResultSets ); } 18 | 19 | NullStatementSetManagedResultSet(ResultSet inner, Set activeResultSets) 20 | { super( inner, activeResultSets); } 21 | 22 | public Statement getStatement() 23 | { return null; } 24 | } 25 | -------------------------------------------------------------------------------- /src/com/mchange/v2/c3p0/impl/SetManagedResultSet.java: -------------------------------------------------------------------------------- 1 | package com.mchange.v2.c3p0.impl; 2 | 3 | import java.sql.*; 4 | import java.util.Set; 5 | import com.mchange.v2.sql.filter.FilterResultSet; 6 | 7 | abstract class SetManagedResultSet extends FilterResultSet 8 | { 9 | Set activeResultSets; 10 | 11 | SetManagedResultSet(Set activeResultSets) 12 | { 13 | this.activeResultSets = activeResultSets; 14 | } 15 | 16 | SetManagedResultSet(ResultSet inner, Set activeResultSets) 17 | { 18 | super( inner ); 19 | this.activeResultSets = activeResultSets; 20 | } 21 | 22 | public synchronized void setInner(ResultSet inner) 23 | { 24 | this.inner = inner; 25 | activeResultSets.add( inner ); 26 | } 27 | 28 | public synchronized void close() throws SQLException 29 | { 30 | if ( inner != null ) 31 | { 32 | inner.close(); 33 | activeResultSets.remove( inner ); 34 | inner = null; 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/com/mchange/v2/c3p0/impl/SnatchFromSetResultSet.java: -------------------------------------------------------------------------------- 1 | package com.mchange.v2.c3p0.impl; 2 | 3 | import java.sql.*; 4 | import java.util.Set; 5 | import com.mchange.v2.sql.filter.FilterResultSet; 6 | 7 | final class SnatchFromSetResultSet extends FilterResultSet 8 | { 9 | Set activeResultSets; 10 | 11 | SnatchFromSetResultSet(Set activeResultSets) 12 | { this.activeResultSets = activeResultSets; } 13 | 14 | public synchronized void setInner(ResultSet inner) 15 | { 16 | this.inner = inner; 17 | activeResultSets.add( inner ); 18 | } 19 | 20 | public synchronized void close() throws SQLException 21 | { 22 | inner.close(); 23 | activeResultSets.remove( inner ); 24 | inner = null; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/com/mchange/v2/c3p0/management/C3P0RegistryManager.java: -------------------------------------------------------------------------------- 1 | package com.mchange.v2.c3p0.management; 2 | 3 | import java.util.*; 4 | import java.sql.SQLException; 5 | import com.mchange.v2.c3p0.C3P0Registry; 6 | import com.mchange.v2.c3p0.subst.C3P0Substitutions; 7 | 8 | public class C3P0RegistryManager implements C3P0RegistryManagerMBean 9 | { 10 | public String[] getAllIdentityTokens() 11 | { 12 | Set tokens = C3P0Registry.allIdentityTokens(); 13 | return (String[]) tokens.toArray( new String[ tokens.size() ] ); 14 | } 15 | 16 | public Set getAllIdentityTokenized() 17 | { return C3P0Registry.allIdentityTokenized(); } 18 | 19 | public Set getAllPooledDataSources() 20 | { return C3P0Registry.allPooledDataSources(); } 21 | 22 | public int getAllIdentityTokenCount() 23 | { return C3P0Registry.allIdentityTokens().size(); } 24 | 25 | public int getAllIdentityTokenizedCount() 26 | { return C3P0Registry.allIdentityTokenized().size(); } 27 | 28 | public int getAllPooledDataSourcesCount() 29 | { return C3P0Registry.allPooledDataSources().size(); } 30 | 31 | public String[] getAllIdentityTokenizedStringified() 32 | { return stringifySet( C3P0Registry.allIdentityTokenized() ); } 33 | 34 | public String[] getAllPooledDataSourcesStringified() 35 | { return stringifySet( C3P0Registry.allPooledDataSources() ); } 36 | 37 | public int getNumPooledDataSources() throws SQLException 38 | { return C3P0Registry.getNumPooledDataSources(); } 39 | 40 | public int getNumPoolsAllDataSources() throws SQLException 41 | { return C3P0Registry.getNumPoolsAllDataSources(); } 42 | 43 | public String getC3p0Version() 44 | { return C3P0Substitutions.VERSION ; } 45 | 46 | private String[] stringifySet(Set s) 47 | { 48 | String[] out = new String[ s.size() ]; 49 | int i = 0; 50 | for (Iterator ii = s.iterator(); ii.hasNext(); ) 51 | out[i++] = ii.next().toString(); 52 | return out; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/com/mchange/v2/c3p0/management/C3P0RegistryManagerMBean.java: -------------------------------------------------------------------------------- 1 | package com.mchange.v2.c3p0.management; 2 | 3 | import java.sql.SQLException; 4 | import java.util.Set; 5 | 6 | public interface C3P0RegistryManagerMBean 7 | { 8 | public String[] getAllIdentityTokens(); 9 | public Set getAllIdentityTokenized(); 10 | public Set getAllPooledDataSources(); 11 | 12 | public int getAllIdentityTokenCount(); 13 | public int getAllIdentityTokenizedCount(); 14 | public int getAllPooledDataSourcesCount(); 15 | 16 | public String[] getAllIdentityTokenizedStringified(); 17 | public String[] getAllPooledDataSourcesStringified(); 18 | 19 | public int getNumPooledDataSources() throws SQLException; 20 | public int getNumPoolsAllDataSources() throws SQLException; 21 | 22 | public String getC3p0Version(); 23 | } 24 | -------------------------------------------------------------------------------- /src/com/mchange/v2/c3p0/management/ManagementCoordinator.java: -------------------------------------------------------------------------------- 1 | package com.mchange.v2.c3p0.management; 2 | 3 | import com.mchange.v2.c3p0.PooledDataSource; 4 | 5 | public interface ManagementCoordinator 6 | { 7 | public void attemptManageC3P0Registry(); 8 | public void attemptUnmanageC3P0Registry(); 9 | public void attemptManagePooledDataSource(PooledDataSource pds); 10 | public void attemptUnmanagePooledDataSource( PooledDataSource pds ); 11 | } 12 | 13 | -------------------------------------------------------------------------------- /src/com/mchange/v2/c3p0/management/NullManagementCoordinator.java: -------------------------------------------------------------------------------- 1 | package com.mchange.v2.c3p0.management; 2 | 3 | import com.mchange.v2.c3p0.PooledDataSource; 4 | 5 | public class NullManagementCoordinator implements ManagementCoordinator 6 | { 7 | public void attemptManageC3P0Registry() 8 | {} 9 | 10 | public void attemptUnmanageC3P0Registry() 11 | {} 12 | 13 | public void attemptManagePooledDataSource(PooledDataSource pds) 14 | {} 15 | 16 | public void attemptUnmanagePooledDataSource( PooledDataSource pds ) 17 | {} 18 | } 19 | 20 | -------------------------------------------------------------------------------- /src/com/mchange/v2/c3p0/management/PooledDataSourceManagerMBean.java: -------------------------------------------------------------------------------- 1 | package com.mchange.v2.c3p0.management; 2 | 3 | import java.sql.SQLException; 4 | import java.util.Collection; 5 | 6 | public interface PooledDataSourceManagerMBean 7 | { 8 | public String getIdentityToken(); 9 | public String getDataSourceName(); 10 | public void setDataSourceName(String dataSourceName); 11 | public int getNumConnectionsDefaultUser() throws SQLException; 12 | public int getNumIdleConnectionsDefaultUser() throws SQLException; 13 | public int getNumBusyConnectionsDefaultUser() throws SQLException; 14 | public int getNumUnclosedOrphanedConnectionsDefaultUser() throws SQLException; 15 | public float getEffectivePropertyCycleDefaultUser() throws SQLException; 16 | public void softResetDefaultUser() throws SQLException; 17 | public int getNumConnections(String username, String password) throws SQLException; 18 | public int getNumIdleConnections(String username, String password) throws SQLException; 19 | public int getNumBusyConnections(String username, String password) throws SQLException; 20 | public int getNumUnclosedOrphanedConnections(String username, String password) throws SQLException; 21 | public float getEffectivePropertyCycle(String username, String password) throws SQLException; 22 | public void softReset(String username, String password) throws SQLException; 23 | public int getNumBusyConnectionsAllUsers() throws SQLException; 24 | public int getNumIdleConnectionsAllUsers() throws SQLException; 25 | public int getNumConnectionsAllUsers() throws SQLException; 26 | public int getNumUnclosedOrphanedConnectionsAllUsers() throws SQLException; 27 | public int getThreadPoolSize() throws SQLException; 28 | public int getThreadPoolNumActiveThreads() throws SQLException; 29 | public int getThreadPoolNumIdleThreads() throws SQLException; 30 | public int getThreadPoolNumTasksPending() throws SQLException; 31 | public String sampleThreadPoolStackTraces() throws SQLException; 32 | public String sampleThreadPoolStatus() throws SQLException; 33 | public void softResetAllUsers() throws SQLException; 34 | public int getNumUserPools() throws SQLException; 35 | public Collection getAllUsers() throws SQLException; 36 | public void hardReset() throws SQLException; 37 | public void close() throws SQLException; 38 | } 39 | -------------------------------------------------------------------------------- /src/com/mchange/v2/c3p0/stmt/DoubleMaxStatementCache.java: -------------------------------------------------------------------------------- 1 | package com.mchange.v2.c3p0.stmt; 2 | 3 | import java.sql.*; 4 | import com.mchange.v2.async.AsynchronousRunner; 5 | 6 | public final class DoubleMaxStatementCache extends GooGooStatementCache 7 | { 8 | //MT: protected by parent's mainLock 9 | int max_statements; 10 | Deathmarch globalDeathmarch = new Deathmarch(); 11 | 12 | int max_statements_per_connection; 13 | DeathmarchConnectionStatementManager dcsm; 14 | 15 | public DoubleMaxStatementCache( 16 | AsynchronousRunner blockingTaskAsyncRunner, 17 | AsynchronousRunner deferredStatementDestroyer, 18 | int max_statements, 19 | int max_statements_per_connection, 20 | boolean cancelAutomaticallyClosedStatements 21 | ) 22 | { 23 | super( blockingTaskAsyncRunner, deferredStatementDestroyer, cancelAutomaticallyClosedStatements ); 24 | this.max_statements = max_statements; 25 | this.max_statements_per_connection = max_statements_per_connection; 26 | } 27 | 28 | //called only in parent's constructor 29 | protected ConnectionStatementManager createConnectionStatementManager() 30 | { return (this.dcsm = new DeathmarchConnectionStatementManager()); } 31 | 32 | //all methods below called by parent only with parent's mainLock 33 | void addStatementToDeathmarches( Object pstmt, Connection physicalConnection ) 34 | { 35 | globalDeathmarch.deathmarchStatement( pstmt ); 36 | dcsm.getDeathmarch( physicalConnection ).deathmarchStatement( pstmt ); 37 | } 38 | 39 | void removeStatementFromDeathmarches( Object pstmt, Connection physicalConnection ) 40 | { 41 | globalDeathmarch.undeathmarchStatement( pstmt ); 42 | dcsm.getDeathmarch( physicalConnection ).undeathmarchStatement( pstmt ); 43 | } 44 | 45 | boolean prepareAssimilateNewStatement(Connection pcon) 46 | { 47 | int cxn_stmt_count = dcsm.getNumStatementsForConnection( pcon ); 48 | if (cxn_stmt_count < max_statements_per_connection) //okay... we can cache another for the connection, but how 'bout globally? 49 | { 50 | int global_size = this.countCachedStatements(); 51 | return ( global_size < max_statements || (global_size == max_statements && globalDeathmarch.cullNext()) ); 52 | } 53 | else //we can only cache if we can clear one from the Connection (which implies clearing one globally, so we needn't check max_statements) 54 | return (cxn_stmt_count == max_statements_per_connection && dcsm.getDeathmarch( pcon ).cullNext()); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/com/mchange/v2/c3p0/stmt/GlobalMaxOnlyStatementCache.java: -------------------------------------------------------------------------------- 1 | package com.mchange.v2.c3p0.stmt; 2 | 3 | import java.sql.*; 4 | import com.mchange.v2.async.AsynchronousRunner; 5 | 6 | public final class GlobalMaxOnlyStatementCache extends GooGooStatementCache 7 | { 8 | //MT: protected by parent's mainLock 9 | int max_statements; 10 | 11 | Deathmarch globalDeathmarch = new Deathmarch(); 12 | 13 | public GlobalMaxOnlyStatementCache(AsynchronousRunner blockingTaskAsyncRunner, AsynchronousRunner deferredStatementDestroyer, int max_statements, boolean cancelAutomaticallyClosedStatements ) 14 | { 15 | super( blockingTaskAsyncRunner, deferredStatementDestroyer, cancelAutomaticallyClosedStatements ); 16 | this.max_statements = max_statements; 17 | } 18 | 19 | //called only in parent's constructor 20 | protected ConnectionStatementManager createConnectionStatementManager() 21 | { return new SimpleConnectionStatementManager(); } 22 | 23 | //all below called by parent only with mainLock 24 | void addStatementToDeathmarches( Object pstmt, Connection physicalConnection ) 25 | { globalDeathmarch.deathmarchStatement( pstmt ); } 26 | 27 | void removeStatementFromDeathmarches( Object pstmt, Connection physicalConnection ) 28 | { globalDeathmarch.undeathmarchStatement( pstmt ); } 29 | 30 | boolean prepareAssimilateNewStatement(Connection pcon) 31 | { 32 | int global_size = this.countCachedStatements(); 33 | return ( global_size < max_statements || (global_size == max_statements && globalDeathmarch.cullNext()) ); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/com/mchange/v2/c3p0/stmt/PerConnectionMaxOnlyStatementCache.java: -------------------------------------------------------------------------------- 1 | package com.mchange.v2.c3p0.stmt; 2 | 3 | import java.sql.*; 4 | import com.mchange.v2.async.AsynchronousRunner; 5 | 6 | public final class PerConnectionMaxOnlyStatementCache extends GooGooStatementCache 7 | { 8 | //MT: protected by parent's mainLock 9 | int max_statements_per_connection; 10 | DeathmarchConnectionStatementManager dcsm; 11 | 12 | public PerConnectionMaxOnlyStatementCache ( 13 | AsynchronousRunner blockingTaskAsyncRunner, 14 | AsynchronousRunner deferredStatementDestroyer, 15 | int max_statements_per_connection, 16 | boolean cancelAutomaticallyClosedStatements 17 | ) 18 | { 19 | super( blockingTaskAsyncRunner, deferredStatementDestroyer, cancelAutomaticallyClosedStatements ); 20 | this.max_statements_per_connection = max_statements_per_connection; 21 | } 22 | 23 | //called only in parent's constructor 24 | protected ConnectionStatementManager createConnectionStatementManager() 25 | { return (this.dcsm = new DeathmarchConnectionStatementManager()); } 26 | 27 | //all below called by parent only with mainLock 28 | void addStatementToDeathmarches( Object pstmt, Connection physicalConnection ) 29 | { dcsm.getDeathmarch( physicalConnection ).deathmarchStatement( pstmt ); } 30 | 31 | void removeStatementFromDeathmarches( Object pstmt, Connection physicalConnection ) 32 | { dcsm.getDeathmarch( physicalConnection ).undeathmarchStatement( pstmt ); } 33 | 34 | boolean prepareAssimilateNewStatement(Connection pcon) 35 | { 36 | int cxn_stmt_count = dcsm.getNumStatementsForConnection( pcon ); 37 | return ( cxn_stmt_count < max_statements_per_connection || (cxn_stmt_count == max_statements_per_connection && dcsm.getDeathmarch( pcon ).cullNext()) ); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/com/mchange/v2/c3p0/stmt/StatementCache.java: -------------------------------------------------------------------------------- 1 | package com.mchange.v2.c3p0.stmt; 2 | 3 | import java.lang.reflect.*; 4 | import java.sql.*; 5 | import com.mchange.v1.util.ClosableResource; 6 | 7 | public interface StatementCache extends ClosableResource 8 | { 9 | public Object checkoutStatement( Connection physicalConnection, 10 | Method stmtProducingMethod, 11 | Object[] args ) 12 | throws SQLException; 13 | 14 | public void checkinStatement( Object pstmt ) 15 | throws SQLException; 16 | 17 | public void checkinAll( Connection pcon ) 18 | throws SQLException; 19 | 20 | public void closeAll( Connection pcon ) 21 | throws SQLException; 22 | 23 | public void close() 24 | throws SQLException; 25 | } 26 | 27 | -------------------------------------------------------------------------------- /src/com/mchange/v2/c3p0/util/CloseReportingConnectionWrapper.java: -------------------------------------------------------------------------------- 1 | package com.mchange.v2.c3p0.util; 2 | 3 | import java.sql.*; 4 | import com.mchange.v2.sql.filter.*; 5 | 6 | /** 7 | * @deprecated Please use com.mchange.v2.c3p0.debug.CloseLoggingConnectionWrapper 8 | */ 9 | public class CloseReportingConnectionWrapper extends FilterConnection 10 | { 11 | public CloseReportingConnectionWrapper( Connection conn ) 12 | { super( conn ); } 13 | 14 | public void close() throws SQLException 15 | { 16 | //System.err.print("ADRIAN -- "); 17 | new SQLWarning("Connection.close() called!").printStackTrace(); 18 | super.close(); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/com/mchange/v2/c3p0/util/ConnectionEventSupport.java: -------------------------------------------------------------------------------- 1 | package com.mchange.v2.c3p0.util; 2 | 3 | import java.util.*; 4 | import java.sql.*; 5 | import javax.sql.*; 6 | 7 | public class ConnectionEventSupport 8 | { 9 | private PooledConnection source; 10 | private HashSet mlisteners = new HashSet(); 11 | 12 | public ConnectionEventSupport(PooledConnection source) 13 | { this.source = source; } 14 | 15 | public synchronized void addConnectionEventListener(ConnectionEventListener mlistener) 16 | {mlisteners.add(mlistener);} 17 | 18 | public synchronized void removeConnectionEventListener(ConnectionEventListener mlistener) 19 | {mlisteners.remove(mlistener);} 20 | 21 | public synchronized void printListeners() 22 | { System.err.println( mlisteners ); } 23 | 24 | public synchronized int getListenerCount() 25 | { return mlisteners.size(); } 26 | 27 | public void fireConnectionClosed() 28 | { 29 | Set mlCopy; 30 | 31 | synchronized (this) 32 | { mlCopy = (Set) mlisteners.clone(); } 33 | 34 | ConnectionEvent evt = new ConnectionEvent(source); 35 | for (Iterator i = mlCopy.iterator(); i.hasNext();) 36 | { 37 | ConnectionEventListener cl = (ConnectionEventListener) i.next(); 38 | cl.connectionClosed(evt); 39 | } 40 | } 41 | 42 | public void fireConnectionErrorOccurred(SQLException error) 43 | { 44 | Set mlCopy; 45 | 46 | synchronized (this) 47 | { mlCopy = (Set) mlisteners.clone(); } 48 | 49 | ConnectionEvent evt = new ConnectionEvent(source, error); 50 | for (Iterator i = mlCopy.iterator(); i.hasNext();) 51 | { 52 | ConnectionEventListener cl = (ConnectionEventListener) i.next(); 53 | cl.connectionErrorOccurred(evt); 54 | } 55 | } 56 | } 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /src/com/mchange/v2/c3p0/util/StatementEventSupport.java: -------------------------------------------------------------------------------- 1 | package com.mchange.v2.c3p0.util; 2 | 3 | import java.util.*; 4 | import java.sql.*; 5 | import javax.sql.*; 6 | 7 | public class StatementEventSupport 8 | { 9 | PooledConnection source; 10 | HashSet mlisteners = new HashSet(); 11 | 12 | public StatementEventSupport(PooledConnection source) 13 | { this.source = source; } 14 | 15 | public synchronized void addStatementEventListener(StatementEventListener mlistener) 16 | {mlisteners.add(mlistener);} 17 | 18 | public synchronized void removeStatementEventListener(StatementEventListener mlistener) 19 | {mlisteners.remove(mlistener);} 20 | 21 | public synchronized void printListeners() 22 | { System.err.println( mlisteners ); } 23 | 24 | public synchronized int getListenerCount() 25 | { return mlisteners.size(); } 26 | 27 | public void fireStatementClosed(PreparedStatement ps) 28 | { 29 | Set mlCopy; 30 | 31 | synchronized (this) 32 | { mlCopy = (Set) mlisteners.clone(); } 33 | 34 | StatementEvent evt = new StatementEvent(source, ps); 35 | for (Iterator i = mlCopy.iterator(); i.hasNext();) 36 | { 37 | StatementEventListener cl = (StatementEventListener) i.next(); 38 | cl.statementClosed(evt); 39 | } 40 | } 41 | 42 | public void fireStatementErrorOccurred(PreparedStatement ps, SQLException error) 43 | { 44 | Set mlCopy; 45 | 46 | synchronized (this) 47 | { mlCopy = (Set) mlisteners.clone(); } 48 | 49 | StatementEvent evt = new StatementEvent(source, ps, error); 50 | for (Iterator i = mlCopy.iterator(); i.hasNext();) 51 | { 52 | StatementEventListener cl = (StatementEventListener) i.next(); 53 | cl.statementErrorOccurred(evt); 54 | } 55 | } 56 | } 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /src/com/mchange/v2/resourcepool/CannotAcquireResourceException.java: -------------------------------------------------------------------------------- 1 | package com.mchange.v2.resourcepool; 2 | 3 | public class CannotAcquireResourceException extends ResourcePoolException 4 | { 5 | public CannotAcquireResourceException(String msg, Throwable t) 6 | {super(msg, t);} 7 | 8 | public CannotAcquireResourceException(Throwable t) 9 | {super(t);} 10 | 11 | public CannotAcquireResourceException(String msg) 12 | {super(msg);} 13 | 14 | public CannotAcquireResourceException() 15 | {super();} 16 | } 17 | -------------------------------------------------------------------------------- /src/com/mchange/v2/resourcepool/EventSupportingResourcePool.java: -------------------------------------------------------------------------------- 1 | package com.mchange.v2.resourcepool; 2 | 3 | import com.mchange.v1.util.ClosableResource; 4 | 5 | public interface EventSupportingResourcePool extends ResourcePool 6 | { 7 | /** 8 | * Events may be fired asynchronously: listeners must not rely on 9 | * events to reflect the current state of the pool, but they will 10 | * accurately represent the state of the pool in the recent past 11 | * when the event-provoking incident occurred. 12 | */ 13 | public void addResourcePoolListener(ResourcePoolListener rpl) 14 | throws ResourcePoolException; 15 | 16 | public void removeResourcePoolListener(ResourcePoolListener rpl) 17 | throws ResourcePoolException; 18 | 19 | } 20 | -------------------------------------------------------------------------------- /src/com/mchange/v2/resourcepool/NoGoodResourcesException.java: -------------------------------------------------------------------------------- 1 | package com.mchange.v2.resourcepool; 2 | 3 | public class NoGoodResourcesException extends ResourcePoolException 4 | { 5 | public NoGoodResourcesException(String msg, Throwable t) 6 | {super(msg, t);} 7 | 8 | public NoGoodResourcesException(Throwable t) 9 | {super(t);} 10 | 11 | public NoGoodResourcesException(String msg) 12 | {super(msg);} 13 | 14 | public NoGoodResourcesException() 15 | {super();} 16 | } 17 | -------------------------------------------------------------------------------- /src/com/mchange/v2/resourcepool/ResourcePoolEvent.java: -------------------------------------------------------------------------------- 1 | package com.mchange.v2.resourcepool; 2 | 3 | import java.util.EventObject; 4 | 5 | public class ResourcePoolEvent extends EventObject 6 | { 7 | Object resc; 8 | boolean checked_out_resource; 9 | int pool_size; 10 | int available_size; 11 | int removed_but_unreturned_size; 12 | 13 | public ResourcePoolEvent( ResourcePool pool, 14 | Object resc, 15 | boolean checked_out_resource, 16 | int pool_size, 17 | int available_size, 18 | int removed_but_unreturned_size ) 19 | { 20 | super(pool); 21 | this.resc = resc; 22 | this.checked_out_resource = checked_out_resource; 23 | this.pool_size = pool_size; 24 | this.available_size = available_size; 25 | this.removed_but_unreturned_size = removed_but_unreturned_size; 26 | } 27 | 28 | public Object getResource() 29 | { return resc; } 30 | 31 | public boolean isCheckedOutResource() 32 | { return checked_out_resource; } 33 | 34 | public int getPoolSize() 35 | { return pool_size; } 36 | 37 | public int getAvailableSize() 38 | { return available_size; } 39 | 40 | public int getRemovedButUnreturnedSize() 41 | { return removed_but_unreturned_size; } 42 | } 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /src/com/mchange/v2/resourcepool/ResourcePoolEventSupport.java: -------------------------------------------------------------------------------- 1 | package com.mchange.v2.resourcepool; 2 | 3 | import java.util.*; 4 | 5 | public class ResourcePoolEventSupport 6 | { 7 | ResourcePool source; 8 | Set mlisteners = new HashSet(); 9 | 10 | public ResourcePoolEventSupport(ResourcePool source) 11 | { this.source = source; } 12 | 13 | public synchronized void addResourcePoolListener(ResourcePoolListener mlistener) 14 | {mlisteners.add(mlistener);} 15 | 16 | public synchronized void removeResourcePoolListener(ResourcePoolListener mlistener) 17 | {mlisteners.remove(mlistener);} 18 | 19 | public synchronized void fireResourceAcquired( Object resc, 20 | int pool_size, 21 | int available_size, 22 | int removed_but_unreturned_size ) 23 | { 24 | if (! mlisteners.isEmpty() ) 25 | { 26 | ResourcePoolEvent evt = new ResourcePoolEvent(source, 27 | resc, 28 | false, 29 | pool_size, 30 | available_size, 31 | removed_but_unreturned_size ); 32 | for (Iterator i = mlisteners.iterator(); i.hasNext();) 33 | { 34 | ResourcePoolListener rpl = (ResourcePoolListener) i.next(); 35 | rpl.resourceAcquired(evt); 36 | } 37 | } 38 | } 39 | 40 | public synchronized void fireResourceCheckedIn( Object resc, 41 | int pool_size, 42 | int available_size, 43 | int removed_but_unreturned_size ) 44 | { 45 | if (! mlisteners.isEmpty() ) 46 | { 47 | ResourcePoolEvent evt = new ResourcePoolEvent(source, 48 | resc, 49 | false, 50 | pool_size, 51 | available_size, 52 | removed_but_unreturned_size ); 53 | for (Iterator i = mlisteners.iterator(); i.hasNext();) 54 | { 55 | ResourcePoolListener rpl = (ResourcePoolListener) i.next(); 56 | rpl.resourceCheckedIn(evt); 57 | } 58 | } 59 | } 60 | 61 | public synchronized void fireResourceCheckedOut( Object resc, 62 | int pool_size, 63 | int available_size, 64 | int removed_but_unreturned_size ) 65 | { 66 | if (! mlisteners.isEmpty() ) 67 | { 68 | ResourcePoolEvent evt = new ResourcePoolEvent(source, 69 | resc, 70 | true, 71 | pool_size, 72 | available_size, 73 | removed_but_unreturned_size ); 74 | for (Iterator i = mlisteners.iterator(); i.hasNext();) 75 | { 76 | ResourcePoolListener rpl = (ResourcePoolListener) i.next(); 77 | rpl.resourceCheckedOut(evt); 78 | } 79 | } 80 | } 81 | 82 | public synchronized void fireResourceRemoved( Object resc, 83 | boolean checked_out_resource, 84 | int pool_size, 85 | int available_size, 86 | int removed_but_unreturned_size ) 87 | { 88 | if (! mlisteners.isEmpty() ) 89 | { 90 | ResourcePoolEvent evt = new ResourcePoolEvent(source, 91 | resc, 92 | checked_out_resource, 93 | pool_size, 94 | available_size, 95 | removed_but_unreturned_size ); 96 | for (Iterator i = mlisteners.iterator(); i.hasNext();) 97 | { 98 | ResourcePoolListener rpl = (ResourcePoolListener) i.next(); 99 | rpl.resourceRemoved(evt); 100 | } 101 | } 102 | } 103 | } 104 | 105 | 106 | 107 | -------------------------------------------------------------------------------- /src/com/mchange/v2/resourcepool/ResourcePoolException.java: -------------------------------------------------------------------------------- 1 | package com.mchange.v2.resourcepool; 2 | 3 | import com.mchange.lang.PotentiallySecondaryException; 4 | 5 | public class ResourcePoolException extends PotentiallySecondaryException 6 | { 7 | public ResourcePoolException(String msg, Throwable t) 8 | {super(msg, t);} 9 | 10 | public ResourcePoolException(Throwable t) 11 | {super(t);} 12 | 13 | public ResourcePoolException(String msg) 14 | {super(msg);} 15 | 16 | public ResourcePoolException() 17 | {super();} 18 | } 19 | -------------------------------------------------------------------------------- /src/com/mchange/v2/resourcepool/ResourcePoolListener.java: -------------------------------------------------------------------------------- 1 | package com.mchange.v2.resourcepool; 2 | 3 | import java.util.EventListener; 4 | 5 | public interface ResourcePoolListener extends EventListener 6 | { 7 | public void resourceAcquired(ResourcePoolEvent evt); 8 | 9 | public void resourceCheckedIn(ResourcePoolEvent evt); 10 | 11 | public void resourceCheckedOut(ResourcePoolEvent evt); 12 | 13 | public void resourceRemoved(ResourcePoolEvent evt); 14 | } 15 | -------------------------------------------------------------------------------- /src/com/mchange/v2/resourcepool/ResourcePoolUtils.java: -------------------------------------------------------------------------------- 1 | package com.mchange.v2.resourcepool; 2 | 3 | import com.mchange.v2.log.*; 4 | 5 | final class ResourcePoolUtils 6 | { 7 | final static MLogger logger = MLog.getLogger( ResourcePoolUtils.class ); 8 | 9 | final static ResourcePoolException convertThrowable( String msg, Throwable t ) 10 | { 11 | if (Debug.DEBUG) 12 | { 13 | //t.printStackTrace(); 14 | if (logger.isLoggable( MLevel.FINE ) ) 15 | logger.log( MLevel.FINE , "Converting throwable to ResourcePoolException..." , t ); 16 | } 17 | if ( t instanceof ResourcePoolException) 18 | return (ResourcePoolException) t; 19 | else 20 | return new ResourcePoolException( msg, t ); 21 | } 22 | 23 | final static ResourcePoolException convertThrowable( Throwable t ) 24 | { return convertThrowable("Ouch! " + t.toString(), t ); } 25 | } 26 | -------------------------------------------------------------------------------- /src/com/mchange/v2/resourcepool/TimeoutException.java: -------------------------------------------------------------------------------- 1 | package com.mchange.v2.resourcepool; 2 | 3 | public class TimeoutException extends ResourcePoolException 4 | { 5 | public TimeoutException(String msg, Throwable t) 6 | {super(msg, t);} 7 | 8 | public TimeoutException(Throwable t) 9 | {super(t);} 10 | 11 | public TimeoutException(String msg) 12 | {super(msg);} 13 | 14 | public TimeoutException() 15 | {super();} 16 | } 17 | -------------------------------------------------------------------------------- /test/conf-logging/logging.properties: -------------------------------------------------------------------------------- 1 | handlers=java.util.logging.ConsoleHandler 2 | .level=INFO 3 | #com.mchange.v2.resourcepool.level=FINER 4 | #.level=INFO 5 | com.mchange.v2.c3p0.impl.level=FINE 6 | #com.mchange.v2.c3p0.stmt.level=FINEST 7 | #com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool.level=FINEST 8 | #com.mchange.v2.c3p0.impl.NewPooledConnection.level=FINEST 9 | #com.mchange.v2.c3p0.stmt.GooGooStatementCache.level=FINEST 10 | java.util.logging.ConsoleHandler.level=FINEST 11 | java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter 12 | java.util.logging.SimpleFormatter.format=%1$tF@%1$tT [%4$s] [%3$s] %5$s %6$s%n 13 | -------------------------------------------------------------------------------- /test/resources-local-rough/c3p0.properties: -------------------------------------------------------------------------------- 1 | # 2 | # This file is detritus from various testing attempts 3 | # the values below may change, and often do not represent 4 | # reasonable values for the parameters. 5 | # 6 | 7 | c3p0.testConnectionOnCheckout=true 8 | c3p0.testConnectionOnCheckin=true 9 | #c3p0.dataSourceName=poop 10 | c3p0.minPoolSize=10 11 | c3p0.maxPoolSize=40 12 | c3p0.checkoutTimeout=2000 13 | c3p0.connectionIsValidTimeout=1 14 | #c3p0.idleConnectionTestPeriod=30 15 | c3p0.idleConnectionTestPeriod=1 16 | c3p0.maxConnectionAge=1 17 | c3p0.maxIdleTime=2 18 | c3p0.maxIdleTimeExcessConnections=1 19 | c3p0.propertyCycle=1 20 | c3p0.numHelperThreads=10 21 | c3p0.unreturnedConnectionTimeout=15 22 | c3p0.debugUnreturnedConnectionStackTraces=true 23 | c3p0.forceSynchronousCheckins=true 24 | c3p0.maxStatements=20 25 | c3p0.maxStatementsPerConnection=5 26 | c3p0.maxAdministrativeTaskTime=1 27 | c3p0.cancelAutomaticallyClosedStatements=true 28 | #c3p0.preferredTestQuery=SELECT 1 29 | #c3p0.preferredTestQuery=SXLECT 1 30 | #c3p0.preferredTestQuery=SELECT a FROM emptyyukyuk WHERE a = 5 31 | #c3p0.preferredTestQuery=SELECT a FROM testpbds WHERE a = 5 32 | c3p0.statementCacheNumDeferredCloseThreads=1 33 | #c3p0.automaticTestTable=PoopyTestTable 34 | c3p0.acquireIncrement=10 35 | #c3p0.acquireRetryDelay=1000 36 | #c3p0.acquireRetryAttempts=60 37 | #c3p0.connectionTesterClassName=com.mchange.v2.c3p0.test.AlwaysFailConnectionTester 38 | #c3p0.connectionTesterClassName=com.mchange.v2.c3p0.test.Percent80FailConnectionTester 39 | c3p0.connectionTesterClassName=com.mchange.v2.c3p0.test.Percent20FailConnectionTester 40 | c3p0.initialPoolSize=15 41 | c3p0.attemptResurrectOnCheckin=true 42 | 43 | #c3p0.jdbcUrl= 44 | #c3p0.driverClass= 45 | #c3p0.user= 46 | #c3p0.password= 47 | 48 | #com.mchange.v2.c3p0.impl.DefaultConnectionTester.isValidTimeout=1 49 | 50 | com.mchange.v2.log.MLog=com.mchange.v2.log.jdk14logging.Jdk14MLog 51 | #com.mchange.v2.log.MLog=com.mchange.v2.log.log4j.Log4jMLog 52 | #com.mchange.v2.log.MLog=com.mchange.v2.log.FallbackMLog 53 | #com.mchange.v2.log.NameTransformer=com.mchange.v2.log.PackageNames 54 | #com.mchange.v2.log.FallbackMLog.DEFAULT_CUTOFF_LEVEL=ALL 55 | 56 | #com.mchange.v2.c3p0.VMID=poop 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /test/src/com/mchange/v2/c3p0/test/AlwaysFailConnectionTester.java: -------------------------------------------------------------------------------- 1 | package com.mchange.v2.c3p0.test; 2 | 3 | import java.sql.Connection; 4 | import com.mchange.v2.c3p0.QueryConnectionTester; 5 | import com.mchange.v2.log.MLevel; 6 | import com.mchange.v2.log.MLog; 7 | import com.mchange.v2.log.MLogger; 8 | 9 | public final class AlwaysFailConnectionTester implements QueryConnectionTester 10 | { 11 | final static MLogger logger = MLog.getLogger( AlwaysFailConnectionTester.class ); 12 | 13 | { 14 | logger.log(MLevel.WARNING, "Instantiated: " + this, new Exception("Instantiation Stack Trace.") ); 15 | } 16 | 17 | public int activeCheckConnection(Connection c) 18 | { 19 | logger.warning(this + ": activeCheckConnection(Connection c)"); 20 | return CONNECTION_IS_INVALID; 21 | } 22 | 23 | public int statusOnException(Connection c, Throwable t) 24 | { 25 | logger.warning(this + ": statusOnException(Connection c, Throwable t)"); 26 | return CONNECTION_IS_INVALID; 27 | } 28 | 29 | public int activeCheckConnection(Connection c, String preferredTestQuery) 30 | { 31 | logger.warning(this + ": activeCheckConnection(Connection c, String preferredTestQuery)"); 32 | return CONNECTION_IS_INVALID; 33 | } 34 | 35 | public boolean equals( Object o ) { return this.getClass().equals( o.getClass() ); } 36 | public int hashCode() { return this.getClass().getName().hashCode(); } 37 | } 38 | 39 | -------------------------------------------------------------------------------- /test/src/com/mchange/v2/c3p0/test/AlwaysFailDataSource.java: -------------------------------------------------------------------------------- 1 | package com.mchange.v2.c3p0.test; 2 | 3 | import java.sql.*; 4 | import javax.sql.*; 5 | 6 | public final class AlwaysFailDataSource implements DataSource 7 | { 8 | private static String MESSAGE = "AlwaysFailDataSource always fails."; 9 | 10 | private static SQLException failure() { return new SQLException( MESSAGE ); } 11 | public Connection getConnection() throws SQLException { throw failure(); } 12 | public Connection getConnection( String user, String password ) throws SQLException { throw failure(); } 13 | public java.io.PrintWriter getLogWriter() throws SQLException { throw failure(); } 14 | public void setLogWriter(java.io.PrintWriter pw) throws SQLException { throw failure(); } 15 | public void setLoginTimeout(int i) throws SQLException { throw failure(); } 16 | public int getLoginTimeout() throws SQLException { throw failure(); } 17 | public java.util.logging.Logger getParentLogger() throws SQLFeatureNotSupportedException 18 | { throw new SQLFeatureNotSupportedException( MESSAGE ); } 19 | public