JdbcFailSafeConnection.java
package eu.javaexperience.database.failsafe;
import static eu.javaexperience.log.LogLevel.DEBUG;
import static eu.javaexperience.log.LoggingTools.*;
import java.sql.Array;
import java.sql.Blob;
import java.sql.CallableStatement;
import java.sql.Clob;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.NClob;
import java.sql.PreparedStatement;
import java.sql.SQLClientInfoException;
import java.sql.SQLException;
import java.sql.SQLWarning;
import java.sql.SQLXML;
import java.sql.Savepoint;
import java.sql.Statement;
import java.sql.Struct;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.Executor;
import eu.javaexperience.database.ConnectionBuilder;
import eu.javaexperience.database.ConnectionCreator;
import eu.javaexperience.io.IOTools;
import eu.javaexperience.log.JavaExperienceLoggingFacility;
import eu.javaexperience.log.LogLevel;
import eu.javaexperience.log.Loggable;
import eu.javaexperience.log.Logger;
public class JdbcFailSafeConnection implements Connection
{
public static Logger LOG = JavaExperienceLoggingFacility.getLogger(new Loggable("SQLDB"));
protected final ConnectionCreator cc;
protected Connection conn;
protected int att;
protected LinkedList<AutoCloseable> openedz;//= new LinkedList<>();
public JdbcFailSafeConnection(ConnectionBuilder cb,String host, int port, String user, String password, String db, int attempt) throws SQLException
{
this(ConnectionCreator.fromConnectionBuilder(cb, host, port, user, password, db), attempt);
}
public JdbcFailSafeConnection(ConnectionCreator cc, int attempt) throws SQLException
{
this.cc = cc;
reconnect(null);
this.att = attempt;
}
protected void reconnect(Throwable t) throws SQLException
{
if(null != t)
{
tryLogFormatException(JdbcFailSafeConnection.LOG, LogLevel.WARNING, t, "void JdbcFailSafeConnection.reconnect()");
}
IOTools.silentClose(conn);
conn = createNewConnection();
}
protected Connection createNewConnection() throws SQLException
{
return cc.get();
}
/**
* TODO enable collecton again only if we release resource after it's closed
* and properly tested.
* */
<T extends AutoCloseable> T publishClosable(T p)
{
if(null != openedz)
{
openedz.add(p);
}
return p;
}
@Override
public Statement createStatement() throws SQLException
{
try
{
return publishClosable(new FailSafeStatement(this));
}
catch(SQLException e)
{
for(int i=1;i!=att;i++)
{
reconnect(e);
try
{
return publishClosable(new FailSafeStatement(this));
}
catch(SQLException e2)
{
continue;
}
}
throw e;
}
}
@Override
public DatabaseMetaData getMetaData() throws SQLException
{
try
{
return new FailSafeDatabaseMetadata(this);
}
catch(SQLException e)
{
for(int i=1;i!=att;i++)
{
reconnect(e);
try
{
return new FailSafeDatabaseMetadata(this);
}
catch(SQLException e2)
{
continue;
}
}
throw e;
}
}
/**************************************************************************/
@Override
public void abort(Executor a) throws SQLException
{
try
{
conn.abort(a);
return;
}
catch(SQLException e)
{
for(int i=1;i<att;i++)
{
reconnect(e);
try
{
conn.abort(a);
return;
}
catch(SQLException e2)
{
continue;
}
}
throw e;
}
}
@Override
public Statement createStatement(int a, int b, int c) throws SQLException
{
try
{
return publishClosable(conn.createStatement(a, b, c));
}
catch(SQLException e)
{
for(int i=1;i<att;i++)
{
reconnect(e);
try
{
return publishClosable(conn.createStatement(a, b, c));
}
catch(SQLException e2)
{
continue;
}
}
throw e;
}
}
@Override
public Statement createStatement(int a, int b) throws SQLException
{
try
{
return publishClosable(conn.createStatement(a, b));
}
catch(SQLException e)
{
for(int i=1;i<att;i++)
{
reconnect(e);
try
{
return publishClosable(conn.createStatement(a, b));
}
catch(SQLException e2)
{
continue;
}
}
throw e;
}
}
@Override
public PreparedStatement prepareStatement(String a, String[] b) throws SQLException
{
try
{
return publishClosable(FailSafePreparedStatement.create(this, a, b));
}
catch(SQLException e)
{
for(int i=1;i<att;i++)
{
reconnect(e);
try
{
return publishClosable(FailSafePreparedStatement.create(this, a, b));
}
catch(SQLException e2)
{
continue;
}
}
throw e;
}
}
@Override
public PreparedStatement prepareStatement(String a) throws SQLException
{
try
{
return publishClosable(FailSafePreparedStatement.create(this, a));
}
catch(SQLException e)
{
for(int i=1;i<att;i++)
{
reconnect(e);
try
{
return publishClosable(FailSafePreparedStatement.create(this, a));
}
catch(SQLException e2)
{
continue;
}
}
throw e;
}
}
@Override
public PreparedStatement prepareStatement(String a, int b, int c, int d) throws SQLException
{
try
{
return publishClosable(FailSafePreparedStatement.create(this, a, b, c, d));
}
catch(SQLException e)
{
for(int i=1;i<att;i++)
{
reconnect(e);
try
{
return publishClosable(FailSafePreparedStatement.create(this, a, b, c, d));
}
catch(SQLException e2)
{
continue;
}
}
throw e;
}
}
@Override
public PreparedStatement prepareStatement(String a, int b) throws SQLException
{
try
{
return publishClosable(FailSafePreparedStatement.create(this, a, b));
}
catch(SQLException e)
{
for(int i=1;i<att;i++)
{
reconnect(e);
try
{
return publishClosable(FailSafePreparedStatement.create(this, a, b));
}
catch(SQLException e2)
{
continue;
}
}
throw e;
}
}
@Override
public PreparedStatement prepareStatement(String a, int b, int c) throws SQLException
{
try
{
return publishClosable(FailSafePreparedStatement.create(this, a, b, c));
}
catch(SQLException e)
{
for(int i=1;i<att;i++)
{
reconnect(e);
try
{
return publishClosable(FailSafePreparedStatement.create(this, a, b, c));
}
catch(SQLException e2)
{
continue;
}
}
throw e;
}
}
@Override
public PreparedStatement prepareStatement(String a, int[] b) throws SQLException
{
try
{
return publishClosable(FailSafePreparedStatement.create(this, a, b));
}
catch(SQLException e)
{
for(int i=1;i<att;i++)
{
reconnect(e);
try
{
return publishClosable(FailSafePreparedStatement.create(this, a, b));
}
catch(SQLException e2)
{
continue;
}
}
throw e;
}
}
@Override
public CallableStatement prepareCall(String a, int b, int c) throws SQLException
{
try
{
return publishClosable(conn.prepareCall(a, b, c));
}
catch(SQLException e)
{
for(int i=1;i<att;i++)
{
reconnect(e);
try
{
return publishClosable(conn.prepareCall(a, b, c));
}
catch(SQLException e2)
{
continue;
}
}
throw e;
}
}
@Override
public CallableStatement prepareCall(String a, int b, int c, int d) throws SQLException
{
try
{
return publishClosable(conn.prepareCall(a, b, c, d));
}
catch(SQLException e)
{
for(int i=1;i<att;i++)
{
reconnect(e);
try
{
return publishClosable(conn.prepareCall(a, b, c, d));
}
catch(SQLException e2)
{
continue;
}
}
throw e;
}
}
@Override
public CallableStatement prepareCall(String a) throws SQLException
{
try
{
return publishClosable(conn.prepareCall(a));
}
catch(SQLException e)
{
for(int i=1;i<att;i++)
{
reconnect(e);
try
{
return publishClosable(conn.prepareCall(a));
}
catch(SQLException e2)
{
continue;
}
}
throw e;
}
}
@Override
public String nativeSQL(String a) throws SQLException
{
try
{
return conn.nativeSQL(a);
}
catch(SQLException e)
{
for(int i=1;i<att;i++)
{
reconnect(e);
try
{
return conn.nativeSQL(a);
}
catch(SQLException e2)
{
continue;
}
}
throw e;
}
}
@Override
public void setAutoCommit(boolean a) throws SQLException
{
tryLogFormat(JdbcFailSafeConnection.LOG, DEBUG, "%s void setAutoCommit(%s)", conn.hashCode(), a);
try
{
conn.setAutoCommit(a);
return;
}
catch(SQLException e)
{
for(int i=1;i<att;i++)
{
reconnect(e);
try
{
conn.setAutoCommit(a);
return;
}
catch(SQLException e2)
{
continue;
}
}
throw e;
}
}
@Override
public boolean getAutoCommit() throws SQLException
{
try
{
return conn.getAutoCommit();
}
catch(SQLException e)
{
for(int i=1;i<att;i++)
{
reconnect(e);
try
{
return conn.getAutoCommit();
}
catch(SQLException e2)
{
continue;
}
}
throw e;
}
}
@Override
public void commit() throws SQLException
{
tryLogFormat(JdbcFailSafeConnection.LOG, DEBUG, "%s void commit()", conn.hashCode());
try
{
conn.commit();
return;
}
catch(SQLException e)
{
for(int i=1;i<att;i++)
{
reconnect(e);
try
{
conn.commit();
return;
}
catch(SQLException e2)
{
continue;
}
}
throw e;
}
}
@Override
public void rollback() throws SQLException
{
tryLogFormat(JdbcFailSafeConnection.LOG, DEBUG, "%s void rollback()", conn.hashCode());
try
{
conn.rollback();
return;
}
catch(SQLException e)
{
for(int i=1;i<att;i++)
{
reconnect(e);
try
{
conn.rollback();
return;
}
catch(SQLException e2)
{
continue;
}
}
throw e;
}
}
@Override
public void rollback(Savepoint a) throws SQLException
{
try
{
conn.rollback(a);
return;
}
catch(SQLException e)
{
for(int i=1;i<att;i++)
{
reconnect(e);
try
{
conn.rollback(a);
return;
}
catch(SQLException e2)
{
continue;
}
}
throw e;
}
}
@Override
public boolean isClosed() throws SQLException
{
try
{
return conn.isClosed();
}
catch(SQLException e)
{
for(int i=1;i<att;i++)
{
reconnect(e);
try
{
return conn.isClosed();
}
catch(SQLException e2)
{
continue;
}
}
throw e;
}
}
@Override
public void setCatalog(String a) throws SQLException
{
try
{
conn.setCatalog(a);
return;
}
catch(SQLException e)
{
for(int i=1;i<att;i++)
{
reconnect(e);
try
{
conn.setCatalog(a);
return;
}
catch(SQLException e2)
{
continue;
}
}
throw e;
}
}
@Override
public String getCatalog() throws SQLException
{
try
{
return conn.getCatalog();
}
catch(SQLException e)
{
for(int i=1;i<att;i++)
{
reconnect(e);
try
{
return conn.getCatalog();
}
catch(SQLException e2)
{
continue;
}
}
throw e;
}
}
@Override
public void setTransactionIsolation(int a) throws SQLException
{
tryLogFormat(JdbcFailSafeConnection.LOG, DEBUG, "%s void setTransactionIsolation(%s)", conn.hashCode(), a);
try
{
conn.setTransactionIsolation(a);
return;
}
catch(SQLException e)
{
for(int i=1;i<att;i++)
{
reconnect(e);
try
{
conn.setTransactionIsolation(a);
return;
}
catch(SQLException e2)
{
continue;
}
}
throw e;
}
}
@Override
public int getTransactionIsolation() throws SQLException
{
try
{
return conn.getTransactionIsolation();
}
catch(SQLException e)
{
for(int i=1;i<att;i++)
{
reconnect(e);
try
{
return conn.getTransactionIsolation();
}
catch(SQLException e2)
{
continue;
}
}
throw e;
}
}
@Override
public SQLWarning getWarnings() throws SQLException
{
try
{
return conn.getWarnings();
}
catch(SQLException e)
{
for(int i=1;i<att;i++)
{
reconnect(e);
try
{
return conn.getWarnings();
}
catch(SQLException e2)
{
continue;
}
}
throw e;
}
}
@Override
public void clearWarnings() throws SQLException
{
try
{
conn.clearWarnings();
return;
}
catch(SQLException e)
{
for(int i=1;i<att;i++)
{
reconnect(e);
try
{
conn.clearWarnings();
return;
}
catch(SQLException e2)
{
continue;
}
}
throw e;
}
}
@Override
public Map getTypeMap() throws SQLException
{
try
{
return conn.getTypeMap();
}
catch(SQLException e)
{
for(int i=1;i<att;i++)
{
reconnect(e);
try
{
return conn.getTypeMap();
}
catch(SQLException e2)
{
continue;
}
}
throw e;
}
}
@Override
public void setTypeMap(Map a) throws SQLException
{
try
{
conn.setTypeMap(a);
return;
}
catch(SQLException e)
{
for(int i=1;i<att;i++)
{
reconnect(e);
try
{
conn.setTypeMap(a);
return;
}
catch(SQLException e2)
{
continue;
}
}
throw e;
}
}
@Override
public void setHoldability(int a) throws SQLException
{
try
{
conn.setHoldability(a);
return;
}
catch(SQLException e)
{
for(int i=1;i<att;i++)
{
reconnect(e);
try
{
conn.setHoldability(a);
return;
}
catch(SQLException e2)
{
continue;
}
}
throw e;
}
}
@Override
public int getHoldability() throws SQLException
{
try
{
return conn.getHoldability();
}
catch(SQLException e)
{
for(int i=1;i<att;i++)
{
reconnect(e);
try
{
return conn.getHoldability();
}
catch(SQLException e2)
{
continue;
}
}
throw e;
}
}
@Override
public Savepoint setSavepoint() throws SQLException
{
try
{
return conn.setSavepoint();
}
catch(SQLException e)
{
for(int i=1;i<att;i++)
{
reconnect(e);
try
{
return conn.setSavepoint();
}
catch(SQLException e2)
{
continue;
}
}
throw e;
}
}
@Override
public Savepoint setSavepoint(String a) throws SQLException
{
try
{
return conn.setSavepoint(a);
}
catch(SQLException e)
{
for(int i=1;i<att;i++)
{
reconnect(e);
try
{
return conn.setSavepoint(a);
}
catch(SQLException e2)
{
continue;
}
}
throw e;
}
}
@Override
public void releaseSavepoint(Savepoint a) throws SQLException
{
try
{
conn.releaseSavepoint(a);
return;
}
catch(SQLException e)
{
for(int i=1;i<att;i++)
{
reconnect(e);
try
{
conn.releaseSavepoint(a);
return;
}
catch(SQLException e2)
{
continue;
}
}
throw e;
}
}
@Override
public Clob createClob() throws SQLException
{
try
{
return conn.createClob();
}
catch(SQLException e)
{
for(int i=1;i<att;i++)
{
reconnect(e);
try
{
return conn.createClob();
}
catch(SQLException e2)
{
continue;
}
}
throw e;
}
}
@Override
public Blob createBlob() throws SQLException
{
try
{
return conn.createBlob();
}
catch(SQLException e)
{
for(int i=1;i<att;i++)
{
reconnect(e);
try
{
return conn.createBlob();
}
catch(SQLException e2)
{
continue;
}
}
throw e;
}
}
@Override
public NClob createNClob() throws SQLException
{
try
{
return conn.createNClob();
}
catch(SQLException e)
{
for(int i=1;i<att;i++)
{
reconnect(e);
try
{
return conn.createNClob();
}
catch(SQLException e2)
{
continue;
}
}
throw e;
}
}
@Override
public SQLXML createSQLXML() throws SQLException
{
try
{
return conn.createSQLXML();
}
catch(SQLException e)
{
for(int i=1;i<att;i++)
{
reconnect(e);
try
{
return conn.createSQLXML();
}
catch(SQLException e2)
{
continue;
}
}
throw e;
}
}
@Override
public boolean isValid(int a) throws SQLException
{
try
{
return conn.isValid(a);
}
catch(SQLException e)
{
for(int i=1;i<att;i++)
{
reconnect(e);
try
{
return conn.isValid(a);
}
catch(SQLException e2)
{
continue;
}
}
throw e;
}
}
@Override
public void setClientInfo(Properties a) throws SQLClientInfoException
{
conn.setClientInfo(a);
}
@Override
public void setClientInfo(String a, String b) throws SQLClientInfoException
{
conn.setClientInfo(a, b);
}
@Override
public String getClientInfo(String a) throws SQLException
{
try
{
return conn.getClientInfo(a);
}
catch(SQLException e)
{
for(int i=1;i<att;i++)
{
reconnect(e);
try
{
return conn.getClientInfo(a);
}
catch(SQLException e2)
{
continue;
}
}
throw e;
}
}
@Override
public Properties getClientInfo() throws SQLException
{
try
{
return conn.getClientInfo();
}
catch(SQLException e)
{
for(int i=1;i<att;i++)
{
reconnect(e);
try
{
return conn.getClientInfo();
}
catch(SQLException e2)
{
continue;
}
}
throw e;
}
}
@Override
public Array createArrayOf(String a, Object[] b) throws SQLException
{
try
{
return conn.createArrayOf(a, b);
}
catch(SQLException e)
{
for(int i=1;i<att;i++)
{
reconnect(e);
try
{
return conn.createArrayOf(a, b);
}
catch(SQLException e2)
{
continue;
}
}
throw e;
}
}
@Override
public Struct createStruct(String a, Object[] b) throws SQLException
{
try
{
return conn.createStruct(a, b);
}
catch(SQLException e)
{
for(int i=1;i<att;i++)
{
reconnect(e);
try
{
return conn.createStruct(a, b);
}
catch(SQLException e2)
{
continue;
}
}
throw e;
}
}
@Override
public void setSchema(String a) throws SQLException
{
try
{
conn.setSchema(a);
return;
}
catch(SQLException e)
{
for(int i=1;i<att;i++)
{
reconnect(e);
try
{
conn.setSchema(a);
return;
}
catch(SQLException e2)
{
continue;
}
}
throw e;
}
}
@Override
public String getSchema() throws SQLException
{
try
{
return conn.getSchema();
}
catch(SQLException e)
{
for(int i=1;i<att;i++)
{
reconnect(e);
try
{
return conn.getSchema();
}
catch(SQLException e2)
{
continue;
}
}
throw e;
}
}
@Override
public void setNetworkTimeout(Executor a, int b) throws SQLException
{
try
{
conn.setNetworkTimeout(a, b);
return;
}
catch(SQLException e)
{
for(int i=1;i<att;i++)
{
reconnect(e);
try
{
conn.setNetworkTimeout(a, b);
return;
}
catch(SQLException e2)
{
continue;
}
}
throw e;
}
}
@Override
public int getNetworkTimeout() throws SQLException
{
try
{
return conn.getNetworkTimeout();
}
catch(SQLException e)
{
for(int i=1;i<att;i++)
{
reconnect(e);
try
{
return conn.getNetworkTimeout();
}
catch(SQLException e2)
{
continue;
}
}
throw e;
}
}
@Override
public void setReadOnly(boolean a) throws SQLException
{
try
{
conn.setReadOnly(a);
return;
}
catch(SQLException e)
{
for(int i=1;i<att;i++)
{
reconnect(e);
try
{
conn.setReadOnly(a);
return;
}
catch(SQLException e2)
{
continue;
}
}
throw e;
}
}
@Override
public void close() throws SQLException
{
try
{
conn.close();
return;
}
catch(SQLException e)
{
for(int i=1;i<att;i++)
{
reconnect(e);
try
{
conn.close();
return;
}
catch(SQLException e2)
{
continue;
}
}
throw e;
}
}
@Override
public boolean isReadOnly() throws SQLException
{
try
{
return conn.isReadOnly();
}
catch(SQLException e)
{
for(int i=1;i<att;i++)
{
reconnect(e);
try
{
return conn.isReadOnly();
}
catch(SQLException e2)
{
continue;
}
}
throw e;
}
}
@Override
public boolean isWrapperFor(Class a) throws SQLException
{
try
{
return conn.isWrapperFor(a);
}
catch(SQLException e)
{
for(int i=1;i<att;i++)
{
reconnect(e);
try
{
return conn.isWrapperFor(a);
}
catch(SQLException e2)
{
continue;
}
}
throw e;
}
}
@Override
public Object unwrap(Class a) throws SQLException
{
try
{
return conn.unwrap(a);
}
catch(SQLException e)
{
for(int i=1;i<att;i++)
{
reconnect(e);
try
{
return conn.unwrap(a);
}
catch(SQLException e2)
{
continue;
}
}
throw e;
}
}
public void closeOpenedResources() throws Exception
{
for(Iterator<AutoCloseable> it = openedz.iterator();it.hasNext();)
{
it.next().close();
it.remove();
}
}
public void closeOpenedResourcesSilent()
{
for(Iterator<AutoCloseable> it = openedz.iterator();it.hasNext();)
{
try
{
it.next().close();
}
catch (Exception e)
{
e.printStackTrace();
}
it.remove();
}
}
}