From a31b0c92864315ceab72eaccb827ff0d7a579a3c Mon Sep 17 00:00:00 2001 From: Zoran Zaric Date: Wed, 1 Nov 2017 13:32:22 +0100 Subject: [PATCH] Refactor connection handling improve db output --- .../tools/sql/ConnectionParameters.java | 17 +++++ .../at/compax/tools/sql/FrogConnection.java | 23 +++++++ .../java/at/compax/tools/sql/SqlExecutor.java | 52 +++++++++++--- .../java/at/compax/tools/sql/main/Main.java | 69 ++++++++++++++----- .../tools/sql/model/ExecutionParameter.java | 16 +++++ 5 files changed, 150 insertions(+), 27 deletions(-) create mode 100644 src/main/java/at/compax/tools/sql/ConnectionParameters.java create mode 100644 src/main/java/at/compax/tools/sql/FrogConnection.java create mode 100644 src/main/java/at/compax/tools/sql/model/ExecutionParameter.java diff --git a/src/main/java/at/compax/tools/sql/ConnectionParameters.java b/src/main/java/at/compax/tools/sql/ConnectionParameters.java new file mode 100644 index 0000000..9f4072f --- /dev/null +++ b/src/main/java/at/compax/tools/sql/ConnectionParameters.java @@ -0,0 +1,17 @@ +package at.compax.tools.sql; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; + +@Builder +@Getter +@AllArgsConstructor +public class ConnectionParameters { + private String dbIp; + private long port; + private String sid; + private String username; + private String password; + private boolean enableDbOutput; +} \ No newline at end of file diff --git a/src/main/java/at/compax/tools/sql/FrogConnection.java b/src/main/java/at/compax/tools/sql/FrogConnection.java new file mode 100644 index 0000000..8b40b34 --- /dev/null +++ b/src/main/java/at/compax/tools/sql/FrogConnection.java @@ -0,0 +1,23 @@ +package at.compax.tools.sql; + +import java.sql.Connection; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import lombok.Setter; +import lombok.experimental.Delegate; + +@Builder +@Getter +@RequiredArgsConstructor +@AllArgsConstructor +public class FrogConnection implements Connection { + + @Delegate(types=Connection.class) + private final Connection conn; + + @Setter + private Boolean dbOutputEnabled; +} diff --git a/src/main/java/at/compax/tools/sql/SqlExecutor.java b/src/main/java/at/compax/tools/sql/SqlExecutor.java index 9fda7dc..583765b 100644 --- a/src/main/java/at/compax/tools/sql/SqlExecutor.java +++ b/src/main/java/at/compax/tools/sql/SqlExecutor.java @@ -3,7 +3,6 @@ package at.compax.tools.sql; import java.io.IOException; import java.sql.CallableStatement; import java.sql.Clob; -import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.ResultSetMetaData; @@ -19,6 +18,7 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.ObjectMapper; +import at.compax.tools.sql.model.ExecutionParameter; import at.compax.tools.sql.model.QueryParameter; import at.compax.tools.sql.model.QueryResult; import at.compax.tools.sql.model.QueryResult.ColumnDefinition; @@ -39,9 +39,27 @@ import lombok.extern.log4j.Log4j; public class SqlExecutor { private static final long MAX_ROWS = 10L; - public static Result execute(Connection conn, String sql) throws SQLException, JsonProcessingException { - enableDbOutput(conn); + public static Result executeJson(FrogConnection conn, String json) throws SQLException, JsonParseException, JsonMappingException, IOException { + log.debug("Parsing JSON: " + json); + + ObjectMapper mapper = new ObjectMapper(); + ExecutionParameter executionParameter = mapper.readValue(json, ExecutionParameter.class); + + boolean isDbOutputOverridden = executionParameter.isEnableDbOutput() && !conn.getDbOutputEnabled(); + if (isDbOutputOverridden) { + enableDbOutput(conn); + } + Result result = execute(conn, executionParameter.getSql()); + + if (isDbOutputOverridden) { + disableDbOutput(conn); + } + + return result; + } + + public static Result execute(FrogConnection conn, String sql) throws SQLException, JsonProcessingException { log.trace("SQL: " + sql.trim()); @Cleanup @@ -71,7 +89,7 @@ public class SqlExecutor { return resultBuilder.build(); } - public static QueryResult executeJsonQuery(Connection conn, Long maxRows, String json) throws SQLException, JsonParseException, JsonMappingException, IOException { + public static QueryResult executeJsonQuery(FrogConnection conn, Long maxRows, String json) throws SQLException, JsonParseException, JsonMappingException, IOException { log.debug("Parsing JSON: " + json); ObjectMapper mapper = new ObjectMapper(); @@ -81,7 +99,7 @@ public class SqlExecutor { return executeQuery(conn, maxRows, queryParameter); } - public static QueryResult executeQuery(Connection conn, Long maxRows, QueryParameter parameters) throws SQLException { + public static QueryResult executeQuery(FrogConnection conn, Long maxRows, QueryParameter parameters) throws SQLException { if (parameters == null || parameters.getParameters() == null) { return executeQuery(conn, parameters.getSql(), maxRows); } else { @@ -89,7 +107,7 @@ public class SqlExecutor { } } - public static QueryResult executeQuery(Connection conn, String sql, Long maxRows, Object... parameters) throws SQLException { + public static QueryResult executeQuery(FrogConnection conn, String sql, Long maxRows, Object... parameters) throws SQLException { log.trace("SQL: " + sql.trim()); if (maxRows == null) { maxRows = MAX_ROWS; @@ -191,7 +209,7 @@ public class SqlExecutor { return queryResultBuilder.rows(rows).build(); } - public static QueryResult executeUpdate(Connection conn, String sql, Object... parameters) throws SQLException { + public static QueryResult executeUpdate(FrogConnection conn, String sql, Object... parameters) throws SQLException { log.trace("SQL: " + sql.trim()); String updateQuery = sql.replaceAll(";$", "").trim(); @@ -257,7 +275,7 @@ public class SqlExecutor { return columnDefinitions; } - private static void handleUserErrors(Connection conn, String sql, Statement stmt) throws SQLException, SqlExecutionException { + private static void handleUserErrors(FrogConnection conn, String sql, Statement stmt) throws SQLException, SqlExecutionException { SQLWarning warnings = stmt.getWarnings(); List userErrors = new Vector(); if (warnings != null) { @@ -267,7 +285,7 @@ public class SqlExecutor { } } - private static List parseUserErrors(Connection conn) throws SQLException { + private static List parseUserErrors(FrogConnection 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; @@ -314,8 +332,11 @@ public class SqlExecutor { return userErrors; } - private static List parseDbOutput(Connection conn) throws SQLException { + private static List parseDbOutput(FrogConnection conn) throws SQLException { List result = new Vector<>(); + if (conn.getDbOutputEnabled() == null || !conn.getDbOutputEnabled()) { + return result; + } @Cleanup CallableStatement call = conn.prepareCall("{call DBMS_OUTPUT.GET_LINE(?, ?)}"); @@ -340,8 +361,17 @@ public class SqlExecutor { } - private static void enableDbOutput(Connection conn) throws SQLException { + public static void enableDbOutput(FrogConnection conn) throws SQLException { conn.createStatement() // .execute("BEGIN DBMS_OUTPUT.ENABLE; END;"); + + conn.setDbOutputEnabled(true); + } + + public static void disableDbOutput(FrogConnection conn) throws SQLException { + conn.createStatement() // + .execute("BEGIN DBMS_OUTPUT.DISABLE; END;"); + + conn.setDbOutputEnabled(false); } } diff --git a/src/main/java/at/compax/tools/sql/main/Main.java b/src/main/java/at/compax/tools/sql/main/Main.java index 3c4c2d0..4bfbc20 100644 --- a/src/main/java/at/compax/tools/sql/main/Main.java +++ b/src/main/java/at/compax/tools/sql/main/Main.java @@ -15,6 +15,8 @@ import org.apache.log4j.LogManager; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; +import at.compax.tools.sql.ConnectionParameters; +import at.compax.tools.sql.FrogConnection; import at.compax.tools.sql.SqlExecutionException; import at.compax.tools.sql.SqlExecutor; import at.compax.tools.sql.model.QueryResult; @@ -38,20 +40,38 @@ public class Main { private static ExecutionMode executionMode = ExecutionMode.PLUGIN_BACKEND; - private static Connection getConnection(String dbIp, long port, String sid, String username, String password) throws SQLException { + private static FrogConnection getConnection(ConnectionParameters connectionParameters) throws SQLException { log.debug("Establishing conneciton..."); - Connection conn = null; - String jdbcConnection = String.format("jdbc:oracle:thin:@%s:%d:%s", dbIp, port, sid); + String jdbcConnection = String.format("jdbc:oracle:thin:@%s:%d:%s", connectionParameters.getDbIp(), connectionParameters.getPort(), connectionParameters.getSid()); - conn = DriverManager.getConnection(jdbcConnection, username, password); - conn.setAutoCommit(false); + Connection sqlConn = DriverManager.getConnection(jdbcConnection, // + connectionParameters.getUsername(), // + connectionParameters.getPassword()); + sqlConn.setAutoCommit(false); + + FrogConnection conn = FrogConnection.builder() // + .conn(sqlConn) // + .build(); log.debug("Established conneciton!"); + + if (connectionParameters.isEnableDbOutput()) { + log.info("Enabling db output..."); + try { + SqlExecutor.enableDbOutput(conn); + } catch (SQLException e) { + log.error("Could not enable db output: " + e.getMessage(), e); + conn.setDbOutputEnabled(false); + } + } else { + conn.setDbOutputEnabled(false); + } + return conn; } - private static void closeConnection(Connection conn) { + private static void closeConnection(FrogConnection conn) { if (conn != null) { try { conn.close(); @@ -61,28 +81,28 @@ public class Main { } } - private static QueryResult executeExampleQueryWithException(Connection conn) throws SQLException, JsonProcessingException { + private static QueryResult executeExampleQueryWithException(FrogConnection conn) throws SQLException, JsonProcessingException { String sql = "SELECT id, version, workspac FROM s_settings"; return SqlExecutor.executeQuery(conn, sql, 10L); } - private static QueryResult executeExampleQueryWithoutParameter(Connection conn) throws SQLException, JsonProcessingException { + private static QueryResult executeExampleQueryWithoutParameter(FrogConnection conn) throws SQLException, JsonProcessingException { String sql = "SELECT id, version, workspace FROM s_settings"; return SqlExecutor.executeQuery(conn, sql, 10L); } - private static QueryResult executeExampleQueryWithParameter(Connection conn) throws SQLException, JsonProcessingException { + private static QueryResult executeExampleQueryWithParameter(FrogConnection conn) throws SQLException, JsonProcessingException { String sql = "select client from k_clients where id = ?"; return SqlExecutor.executeQuery(conn, sql, 1L); } - private static Result compileExampleSpec(Connection conn) throws SQLException, JsonProcessingException { + private static Result compileExampleSpec(FrogConnection conn) throws SQLException, JsonProcessingException { String specSql = "CREATE OR REPLACE PACKAGE aax2_wedel\n" + "AS\n" + " PROCEDURE create_cli_migration_workflow(p_customer d_customers.id%type, p_migration_date date);\n" + "END aax2_wedel;"; return SqlExecutor.execute(conn, specSql); } - private static Result compileExampleSpecWithErrors(Connection conn) throws SQLException, JsonProcessingException { + private static Result compileExampleSpecWithErrors(FrogConnection conn) throws SQLException, JsonProcessingException { String specSql = "CREATE OR REPLACE PACKAGE aax2_wedel\n" + "AS\n" + " PROCEDURE create_cli_migration_workflow(p_customer d_customers.id%typ, p_migration_date date);\n" + "END aax2_wedel;"; return SqlExecutor.execute(conn, specSql); @@ -111,7 +131,13 @@ public class Main { // String stdInSql = readFromStdIn(); @Cleanup - Connection conn = getConnection("172.19.13.66", 1521L, "aax2qc", "aax2qc", "aax2qc"); + FrogConnection conn = getConnection(ConnectionParameters.builder() // + .dbIp("172.19.13.66") // + .port(1521L) // + .sid("aax2qc") // + .username("aax2qc") // + .password("aax2qc") // + .build()); System.out.println(formatJsonObject(SqlExecutor.executeJsonQuery(conn, 10L, "{ \"sql\": \"select customer_id from d_customers\"}"))); System.out.println(formatJsonObject(compileExampleSpec(conn))); @@ -119,6 +145,10 @@ public class Main { System.out.println(formatJsonObject(executeExampleQueryWithException(conn))); System.out.println(formatJsonObject(executeExampleQueryWithoutParameter(conn))); System.out.println(formatJsonObject(executeExampleQueryWithParameter(conn))); + + System.out.println(formatJsonObject(SqlExecutor.executeJson(conn, "{ \"sql\": \"begin dbms_output.put_line('should not be seen'); end;\"}"))); + System.out.println(formatJsonObject(SqlExecutor.executeJson(conn, "{ \"enableDbOutput\": true, \"sql\": \"begin dbms_output.put_line('should be seen'); end;\"}"))); + System.out.println(formatJsonObject(SqlExecutor.executeJson(conn, "{ \"sql\": \"begin dbms_output.put_line('should not be seen'); end;\"}"))); } catch (Exception e) { e.printStackTrace(); } @@ -133,16 +163,17 @@ public class Main { } } - private static void serveForever(String host, long port, String sid, String username, String password) { - Connection conn = null; + private static void serveForever(ConnectionParameters connectionParameters) { + FrogConnection conn = null; try { try { - conn = getConnection(host, port, sid, username, password); + conn = getConnection(connectionParameters); } catch (SQLException e) { log.error(e.getMessage(), e); System.err.println("Could not connect to Database: " + e.getMessage()); System.exit(1); } + log.info("Waiting for input..."); BufferedReader br = new BufferedReader(new InputStreamReader(System.in, Charset.forName("UTF-8"))); @@ -201,8 +232,14 @@ public class Main { String sid = args[2]; String username = args[3]; String password = args[4]; + serveForever(ConnectionParameters.builder() // + .dbIp(host) // + .port(port) // + .sid(sid) // + .username(username) // + .password(password) // + .build()); - serveForever(host, port, sid, username, password); } } diff --git a/src/main/java/at/compax/tools/sql/model/ExecutionParameter.java b/src/main/java/at/compax/tools/sql/model/ExecutionParameter.java new file mode 100644 index 0000000..07a93c8 --- /dev/null +++ b/src/main/java/at/compax/tools/sql/model/ExecutionParameter.java @@ -0,0 +1,16 @@ +package at.compax.tools.sql.model; + +import com.fasterxml.jackson.annotation.JsonInclude; + +import lombok.Builder; +import lombok.Getter; +import lombok.ToString; + +@Builder +@Getter +@ToString +@JsonInclude(JsonInclude.Include.NON_NULL) +public class ExecutionParameter { + private String sql; + private boolean enableDbOutput; +}