@ -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 ;
}
}