master
Zoran Zaric 7 years ago
parent a08c71926f
commit 20d6827d0a

@ -11,9 +11,9 @@ import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor
@AllArgsConstructor
public class SqlExecutionException extends Exception {
private static final long serialVersionUID = 3684929762067312606L;
private static final long serialVersionUID = 3684929762067312606L;
private final String message;
private final List<UserError> userErrors;
private Throwable cause;
private final String message;
private final List<UserError> userErrors;
private Throwable cause;
}

@ -36,200 +36,197 @@ import lombok.extern.log4j.Log4j;
@Log4j
public class SqlExecutor {
public static Result execute(Connection conn, String sql) throws SQLException, JsonProcessingException {
log.trace("SQL: " + sql.trim());
@Cleanup
Statement stmt = conn.createStatement();
stmt.execute(sql.trim());
log.info("Executed");
ResultBuilder resultBuilder = Result.builder();
try {
handleUserErrors(conn, sql, stmt);
} catch (SqlExecutionException e) {
log.error(e.getMessage(), e);
resultBuilder.userErrors(e.getUserErrors());
}
return resultBuilder.build();
}
public static QueryResult executeJsonQuery(Connection conn, String json)
throws SQLException, JsonParseException, JsonMappingException, IOException {
log.debug("Parsing JSON: " + json);
ObjectMapper mapper = new ObjectMapper();
QueryParameter queryParameter = mapper.readValue(json, QueryParameter.class);
log.debug("Parsed QueryParamter: " + queryParameter.toString());
return executeQuery(conn, queryParameter);
}
public static QueryResult executeQuery(Connection conn, QueryParameter parameters) throws SQLException {
if (parameters == null || parameters.getParameters() == null) {
return executeQuery(conn, parameters.getSql());
} else {
return executeQuery(conn, parameters.getSql(), parameters.getParameters().toArray());
}
}
public static QueryResult executeQuery(Connection conn, String sql, Object... parameters) throws SQLException {
log.trace("SQL: " + sql.trim());
@Cleanup
PreparedStatement stmt = conn.prepareStatement(sql);
if (parameters != null) {
int parameterIndex = 1;
for (Object object : parameters) {
if (object != null) {
if (object instanceof String) {
stmt.setString(parameterIndex, (String) object);
} else if (object instanceof Integer) {
stmt.setInt(parameterIndex, (Integer) object);
} else if (object instanceof Long) {
stmt.setLong(parameterIndex, (Long) object);
} else {
stmt.setString(parameterIndex, (String) object);
String message = String.format("Unhandled paramter type <%s>. Defaulting to String",
object.getClass().getName());
log.warn(message);
}
} else {
log.warn("parameter is null");
}
parameterIndex++;
}
}
@Cleanup
ResultSet rs = null;
QueryResultBuilder queryResultBuilder = QueryResult.builder();
try {
rs = stmt.executeQuery();
} catch (SQLException e) {
return queryResultBuilder //
.exception(e.getClass().getName()) //
.exceptionMessage(e.getMessage()) //
.build();
}
try {
handleUserErrors(conn, sql, stmt);
} catch (SqlExecutionException e) {
log.error(e.getMessage(), e);
return queryResultBuilder.userErrors(e.getUserErrors()).build();
}
List<Row> rows = new Vector<Row>();
while (rs.next()) {
ResultSetMetaData metaData = rs.getMetaData();
if (rs.isFirst()) {
queryResultBuilder.columnDefinitions(getColumnDefinitions(metaData));
}
RowBuilder rowBuilder = Row.builder();
List<Column> columns = new Vector<Column>();
int columnCount = metaData.getColumnCount();
for (int columnIndex = 1; columnIndex <= columnCount; columnIndex++) {
ColumnBuilder columnBuilder = Column.builder();
int columnType = metaData.getColumnType(columnIndex);
if (columnType == Types.VARCHAR) {
columnBuilder.value(rs.getString(columnIndex));
} else if (columnType == Types.NUMERIC) {
columnBuilder.value(rs.getLong(columnIndex));
} else {
String message = String.format("Unhandled column type <%s>. Defaulting to String", rs.getMetaData().getColumnTypeName(columnIndex));
log.warn(message);
}
columns.add(columnBuilder.build());
}
rowBuilder.columns(columns);
rows.add(rowBuilder.build());
}
return queryResultBuilder.rows(rows).build();
}
private static Vector<ColumnDefinition> getColumnDefinitions(ResultSetMetaData metaData) throws SQLException {
Vector<ColumnDefinition> columnDefinitions = new Vector<ColumnDefinition>();
int columnCount = metaData.getColumnCount();
for (int columnIndex = 1; columnIndex <= columnCount; columnIndex++) {
columnDefinitions.add(ColumnDefinition.builder() //
.index(columnIndex) //
.name(metaData.getColumnLabel(columnIndex)) //
.type(metaData.getColumnTypeName(columnIndex)) //
.build());
}
return columnDefinitions;
}
private static void handleUserErrors(Connection conn, String sql, Statement stmt)
throws SQLException, SqlExecutionException {
SQLWarning warnings = stmt.getWarnings();
List<UserError> userErrors = new Vector<UserError>();
if (warnings != null) {
userErrors = parseUserErrors(conn);
String message = String.format("Errors while executing SQL \"%s\"", sql);
throw new SqlExecutionException(message, userErrors);
}
}
private static List<UserError> parseUserErrors(Connection conn) throws SQLException {
log.debug("Retrieving user errors");
String userErrorsSql = "select name, type, sequence, line, position, text, attribute, message_number from user_errors where type <> 'JAVA CLASS' order by sequence";
boolean first = true;
Vector<UserError> userErrors = new Vector<UserError>();
Vector<MessageLine> lines = new Vector<UserError.MessageLine>();
UserErrorBuilder builder = UserError.builder();
@Cleanup
PreparedStatement userErrorsStmt = conn.prepareStatement(userErrorsSql);
@Cleanup
ResultSet userErrorsRs = userErrorsStmt.executeQuery();
while (userErrorsRs.next()) {
long messageNumber = userErrorsRs.getLong("message_number");
if (messageNumber != 0) {
if (!first) {
builder.lines(lines);
userErrors.add(builder.build());
first = false;
builder = UserError.builder();
lines = new Vector<UserError.MessageLine>();
}
builder.name(userErrorsRs.getString("name"));
builder.type(userErrorsRs.getString("type"));
}
lines.add(UserError.MessageLine.builder() //
.sequence(userErrorsRs.getLong("sequence")) //
.line(userErrorsRs.getLong("line")) //
.position(userErrorsRs.getLong("position")) //
.text(userErrorsRs.getString("text")) //
.attribute(userErrorsRs.getString("attribute")) //
.messageNumber(userErrorsRs.getLong("message_number")) //
.build());
}
builder.lines(lines);
userErrors.add(builder.build());
return userErrors;
}
public static Result execute(Connection conn, String sql) throws SQLException, JsonProcessingException {
log.trace("SQL: " + sql.trim());
@Cleanup
Statement stmt = conn.createStatement();
stmt.execute(sql.trim());
log.info("Executed");
ResultBuilder resultBuilder = Result.builder();
try {
handleUserErrors(conn, sql, stmt);
} catch (SqlExecutionException e) {
log.error(e.getMessage(), e);
resultBuilder.userErrors(e.getUserErrors());
}
return resultBuilder.build();
}
public static QueryResult executeJsonQuery(Connection conn, String json) throws SQLException, JsonParseException, JsonMappingException, IOException {
log.debug("Parsing JSON: " + json);
ObjectMapper mapper = new ObjectMapper();
QueryParameter queryParameter = mapper.readValue(json, QueryParameter.class);
log.debug("Parsed QueryParamter: " + queryParameter.toString());
return executeQuery(conn, queryParameter);
}
public static QueryResult executeQuery(Connection conn, QueryParameter parameters) throws SQLException {
if (parameters == null || parameters.getParameters() == null) {
return executeQuery(conn, parameters.getSql());
} else {
return executeQuery(conn, parameters.getSql(), parameters.getParameters().toArray());
}
}
public static QueryResult executeQuery(Connection conn, String sql, Object... parameters) throws SQLException {
log.trace("SQL: " + sql.trim());
@Cleanup
PreparedStatement stmt = conn.prepareStatement(sql);
if (parameters != null) {
int parameterIndex = 1;
for (Object object : parameters) {
if (object != null) {
if (object instanceof String) {
stmt.setString(parameterIndex, (String) object);
} else if (object instanceof Integer) {
stmt.setInt(parameterIndex, (Integer) object);
} else if (object instanceof Long) {
stmt.setLong(parameterIndex, (Long) object);
} else {
stmt.setString(parameterIndex, (String) object);
String message = String.format("Unhandled paramter type <%s>. Defaulting to String", object.getClass().getName());
log.warn(message);
}
} else {
log.warn("parameter is null");
}
parameterIndex++;
}
}
@Cleanup
ResultSet rs = null;
QueryResultBuilder queryResultBuilder = QueryResult.builder();
try {
rs = stmt.executeQuery();
} catch (SQLException e) {
return queryResultBuilder //
.exception(e.getClass().getName()) //
.exceptionMessage(e.getMessage()) //
.build();
}
try {
handleUserErrors(conn, sql, stmt);
} catch (SqlExecutionException e) {
log.error(e.getMessage(), e);
return queryResultBuilder.userErrors(e.getUserErrors()).build();
}
List<Row> rows = new Vector<Row>();
while (rs.next()) {
ResultSetMetaData metaData = rs.getMetaData();
if (rs.isFirst()) {
queryResultBuilder.columnDefinitions(getColumnDefinitions(metaData));
}
RowBuilder rowBuilder = Row.builder();
List<Column> columns = new Vector<Column>();
int columnCount = metaData.getColumnCount();
for (int columnIndex = 1; columnIndex <= columnCount; columnIndex++) {
ColumnBuilder columnBuilder = Column.builder();
int columnType = metaData.getColumnType(columnIndex);
if (columnType == Types.VARCHAR) {
columnBuilder.value(rs.getString(columnIndex));
} else if (columnType == Types.NUMERIC) {
columnBuilder.value(rs.getLong(columnIndex));
} else {
String message = String.format("Unhandled column type <%s>. Defaulting to String", rs.getMetaData().getColumnTypeName(columnIndex));
log.warn(message);
}
columns.add(columnBuilder.build());
}
rowBuilder.columns(columns);
rows.add(rowBuilder.build());
}
return queryResultBuilder.rows(rows).build();
}
private static Vector<ColumnDefinition> getColumnDefinitions(ResultSetMetaData metaData) throws SQLException {
Vector<ColumnDefinition> columnDefinitions = new Vector<ColumnDefinition>();
int columnCount = metaData.getColumnCount();
for (int columnIndex = 1; columnIndex <= columnCount; columnIndex++) {
columnDefinitions.add(ColumnDefinition.builder() //
.index(columnIndex) //
.name(metaData.getColumnLabel(columnIndex)) //
.type(metaData.getColumnTypeName(columnIndex)) //
.build());
}
return columnDefinitions;
}
private static void handleUserErrors(Connection conn, String sql, Statement stmt) throws SQLException, SqlExecutionException {
SQLWarning warnings = stmt.getWarnings();
List<UserError> userErrors = new Vector<UserError>();
if (warnings != null) {
userErrors = parseUserErrors(conn);
String message = String.format("Errors while executing SQL \"%s\"", sql);
throw new SqlExecutionException(message, userErrors);
}
}
private static List<UserError> parseUserErrors(Connection conn) throws SQLException {
log.debug("Retrieving user errors");
String userErrorsSql = "select name, type, sequence, line, position, text, attribute, message_number from user_errors where type <> 'JAVA CLASS' order by sequence";
boolean first = true;
Vector<UserError> userErrors = new Vector<UserError>();
Vector<MessageLine> lines = new Vector<UserError.MessageLine>();
UserErrorBuilder builder = UserError.builder();
@Cleanup
PreparedStatement userErrorsStmt = conn.prepareStatement(userErrorsSql);
@Cleanup
ResultSet userErrorsRs = userErrorsStmt.executeQuery();
while (userErrorsRs.next()) {
long messageNumber = userErrorsRs.getLong("message_number");
if (messageNumber != 0) {
if (!first) {
builder.lines(lines);
userErrors.add(builder.build());
first = false;
builder = UserError.builder();
lines = new Vector<UserError.MessageLine>();
}
builder.name(userErrorsRs.getString("name"));
builder.type(userErrorsRs.getString("type"));
}
lines.add(UserError.MessageLine.builder() //
.sequence(userErrorsRs.getLong("sequence")) //
.line(userErrorsRs.getLong("line")) //
.position(userErrorsRs.getLong("position")) //
.text(userErrorsRs.getString("text")) //
.attribute(userErrorsRs.getString("attribute")) //
.messageNumber(userErrorsRs.getLong("message_number")) //
.build());
}
builder.lines(lines);
userErrors.add(builder.build());
return userErrors;
}
}

@ -14,8 +14,8 @@ import lombok.ToString;
@ToString
@JsonInclude(JsonInclude.Include.NON_NULL)
public class QueryParameter {
@JsonProperty("sql")
private String sql;
@JsonProperty("parameters")
private List<Object> parameters;
@JsonProperty("sql")
private String sql;
@JsonProperty("parameters")
private List<Object> parameters;
}

@ -14,44 +14,44 @@ import lombok.ToString;
@ToString
@JsonInclude(JsonInclude.Include.NON_NULL)
public class QueryResult {
@Getter
@Builder
@ToString
@JsonInclude(JsonInclude.Include.NON_NULL)
public static class ColumnDefinition {
@JsonProperty("index")
private int index;
@JsonProperty("name")
private String name;
@JsonProperty("type")
private String type;
}
@Getter
@Builder
@ToString
@JsonInclude(JsonInclude.Include.NON_NULL)
public static class ColumnDefinition {
@JsonProperty("index")
private int index;
@JsonProperty("name")
private String name;
@JsonProperty("type")
private String type;
}
@Getter
@Builder
@ToString
@JsonInclude(JsonInclude.Include.NON_NULL)
public static class Row {
@Getter
@Builder
@ToString
@JsonInclude(JsonInclude.Include.NON_NULL)
public static class Column {
@JsonProperty("value")
private Object value;
}
@Getter
@Builder
@ToString
@JsonInclude(JsonInclude.Include.NON_NULL)
public static class Row {
@Getter
@Builder
@ToString
@JsonInclude(JsonInclude.Include.NON_NULL)
public static class Column {
@JsonProperty("value")
private Object value;
}
@JsonProperty("columns")
private List<Column> columns;
}
@JsonProperty("columns")
private List<Column> columns;
}
private List<ColumnDefinition> columnDefinitions;
@JsonProperty("rows")
private List<Row> rows;
@JsonProperty("userErrors")
private List<UserError> userErrors;
@JsonProperty("exception")
private String exception;
@JsonProperty("exceptionMessage")
private String exceptionMessage;
private List<ColumnDefinition> columnDefinitions;
@JsonProperty("rows")
private List<Row> rows;
@JsonProperty("userErrors")
private List<UserError> userErrors;
@JsonProperty("exception")
private String exception;
@JsonProperty("exceptionMessage")
private String exceptionMessage;
}

@ -10,5 +10,5 @@ import lombok.ToString;
@Getter
@ToString
public class Result {
private List<UserError> userErrors;
private List<UserError> userErrors;
}

@ -14,28 +14,28 @@ import lombok.ToString;
@ToString
@JsonInclude(JsonInclude.Include.NON_NULL)
public class UserError {
@Getter
@Builder
@ToString
@JsonInclude(JsonInclude.Include.NON_NULL)
public static class MessageLine {
private Long sequence;
@JsonProperty("line")
private Long line;
@JsonProperty("position")
private Long position;
@JsonProperty("text")
private String text;
@JsonProperty("attribute")
private String attribute;
private Long messageNumber;
}
@Getter
@Builder
@ToString
@JsonInclude(JsonInclude.Include.NON_NULL)
public static class MessageLine {
private Long sequence;
@JsonProperty("line")
private Long line;
@JsonProperty("position")
private Long position;
@JsonProperty("text")
private String text;
@JsonProperty("attribute")
private String attribute;
private Long messageNumber;
}
@JsonProperty("name")
private String name;
@JsonProperty("type")
private String type;
@JsonProperty("lines")
private List<MessageLine> lines;
@JsonProperty("name")
private String name;
@JsonProperty("type")
private String type;
@JsonProperty("lines")
private List<MessageLine> lines;
}

Loading…
Cancel
Save