package dbfit.fixture;
import java.sql.*;
public class StatementExecution implements AutoCloseable {
protected PreparedStatement statement;
public StatementExecution(PreparedStatement statement) {
this.statement = statement;
}
public void run() throws SQLException {
statement.execute();
}
public void registerOutParameter(int index, int sqlType, boolean isReturnValue) throws SQLException {
convertStatementToCallable().registerOutParameter(index, sqlType);
}
public void setObject(int index, Object value, int sqlType, String userDefinedTypeName) throws SQLException {
if (value == null) {
statement.setNull(index, sqlType, userDefinedTypeName);
} else {
// Don't use the variant that takes sqlType.
// Derby (at least) assumes no decimal places for Types.DECIMAL and truncates the source data.
statement.setObject(index, value);
}
}
public Object getObject(int index) throws SQLException {
return convertStatementToCallable().getObject(index);
}
//really ugly, but a hack to support mysql, because it will not execute inserts with a callable statement
protected CallableStatement convertStatementToCallable() throws SQLException {
if (statement instanceof CallableStatement) return (CallableStatement) statement;
throw new SQLException("This operation requires a callable statement instead of "+ statement.getClass().getName());
}
public Object getGeneratedKey(Class<?> type) throws SQLException, IllegalAccessException {
ResultSet rs = statement.getGeneratedKeys();
if (rs.next()) {//todo: first try to find by name (mysql does not support name-based return keys)
Object value;
if (type == Integer.class) {
value = rs.getInt(1);
} else if (type == Long.class) {
value = rs.getLong(1);
} else {
value = rs.getObject(1);
}
return value;
}
throw new IllegalAccessException("statement has not generated any keys");
}
@Override
public void close() throws SQLException {
statement.close();
}
}