master
Zoran Zaric 7 years ago
parent a08c71926f
commit 20d6827d0a

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

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

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

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

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

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

Loading…
Cancel
Save