package ch.rgw.tools;
import static ch.rgw.tools.JdbcLink.DBFLAVOR_H2;
import static ch.rgw.tools.JdbcLink.DBFLAVOR_MYSQL;
import static ch.rgw.tools.JdbcLink.DBFLAVOR_POSTGRESQL;
import java.sql.SQLException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Natively handles SQL Exceptions if possible. E.g. if we try to update a database sometimes a
* "column already available" exception might occur constantly preventing us from finishing the
* update - although not necessary. This class provides advise to the question whether an exception
* is really necessary to be thrown.
*/
public class DatabaseNativeExceptionHandler {
private static Logger log = LoggerFactory.getLogger(DatabaseNativeExceptionHandler.class);
/**
* Try to handle the thrown Exception considering the native Database implementation
*
* @param dBFlavor
* @param e
* @return <code>true</code> if we can not mitigate the problem and an exception should be
* thrown, else <code>false</code>
*/
public static boolean handleException(String dBFlavor, SQLException e){
switch (dBFlavor) {
case DBFLAVOR_MYSQL:
return handleMysqlException(e);
case DBFLAVOR_POSTGRESQL:
return handlePostgresException(e);
case DBFLAVOR_H2:
return handleH2Exception(e);
default:
log.error("Unknown database flavor: " + dBFlavor);
break;
}
return true;
}
// ----------- H2
private static boolean handleH2Exception(SQLException e){
return true;
}
// ----------- MYSQL
public static final String MYSQL_ERRORCODE_TABLE_EXISTS = "42S01";
public static final String MYSQL_ERRORCODE_DUPLICATE_COLUMN = "42S21";
public static final String MYSQL_ERRORCODE_DUPLICATE_KEY_NAME = "42000";
/**
*
* @param e
* @return
* @see https://dev.mysql.com/doc/refman/5.5/en/error-messages-server.html
*/
private static boolean handleMysqlException(SQLException e){
String sqlState = e.getSQLState();
switch (sqlState) {
case MYSQL_ERRORCODE_TABLE_EXISTS:
log.info("Found table exists, mitigating error code " + sqlState + ": "
+ e.getMessage());
return false;
case MYSQL_ERRORCODE_DUPLICATE_COLUMN:
log.info("Found duplicate column, mitigating error code " + sqlState + ": "
+ e.getMessage());
return false;
case MYSQL_ERRORCODE_DUPLICATE_KEY_NAME:
log.info("Found duplicate key name, mitigating error code " + sqlState + ": "
+ e.getMessage());
return false;
default:
}
return true;
}
// ----------- POSTGRES
public static final String POSTGRES_ERRORCODE_DUPLICATE_COLUMN = "42701";
public static final String POSTGRES_ERRORCODE_DUPLICATE_TABLE = "42P07";
/**
* @param e
* @return
* @see http://www.postgresql.org/docs/9.1/static/errcodes-appendix.html
*/
private static boolean handlePostgresException(SQLException e){
String sqlState = e.getSQLState();
switch (sqlState) {
case POSTGRES_ERRORCODE_DUPLICATE_TABLE:
case POSTGRES_ERRORCODE_DUPLICATE_COLUMN:
log.info("Found duplicate element, mitigating error code " + sqlState + ": "
+ e.getMessage());
return false;
default:
}
return true;
}
}