diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml new file mode 100644 index 0000000..b556301 --- /dev/null +++ b/.github/workflows/maven.yml @@ -0,0 +1,46 @@ +# This workflow will build a Java project with Maven +# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven + +name: Java CI with Maven + +on: + push: + branches: ['**'] + pull_request: + branches: [ master ] + +jobs: + build: + runs-on: ubuntu-latest + + services: + # Label used to access the service container + postgres: + # Docker Hub image + image: postgres + # Provide the password for postgres + env: + POSTGRES_PASSWORD: postgres + # Set health checks to wait until postgres has started + options: >- + --health-cmd pg_isready + --health-interval 10s + --health-timeout 5s + --health-retries 5 + ports: + # Maps tcp port 5432 on service container to the host + - 5432:5432 + + steps: + - uses: actions/checkout@v2 + - name: Set up JDK 1.8 + uses: actions/setup-java@v1 + with: + java-version: 1.8 + - name: Build with Maven + run: mvn -DPOSTGRES_HOST=$POSTGRES_HOST -DPOSTGRES_PORT=$POSTGRES_PORT -B package --file pom.xml + env: + # The hostname used to communicate with the PostgreSQL service container + POSTGRES_HOST: localhost + # The default PostgreSQL port + POSTGRES_PORT: 5432 diff --git a/pom.xml b/pom.xml index 0567040..932949c 100644 --- a/pom.xml +++ b/pom.xml @@ -8,6 +8,9 @@ cimt AG Job Instance Components library + + UTF-8 + org.slf4j @@ -43,6 +46,7 @@ org.apache.maven.plugins maven-compiler-plugin + 3.1 1.7 1.7 @@ -55,7 +59,7 @@ ${project.basedir}/talend_component ${project.basedir}/talend_component - /Data/Talend/Studio/talend_user_components + diff --git a/src/main/resources/.com.apple.backupd.mdmv56989144 b/src/main/resources/.com.apple.backupd.mdmv56989144 deleted file mode 100644 index 3f79d40..0000000 --- a/src/main/resources/.com.apple.backupd.mdmv56989144 +++ /dev/null @@ -1,16 +0,0 @@ - - - - - DateStarted - 2016-08-12T22:19:56Z - FileID - 56989144 - NameSpaceID - 627488955 - NewPath - Talend/workspace_talend_comp/talendcomp_tJobInstance/src/main/resources/configuration - SourcePath - Talend/workspace_talend_comp/talendcomp_tJobInstance/configuration - - diff --git a/src/main/resources/create_table_pgsql.sql b/src/main/resources/create_table_pgsql.sql index 9e6a3c6..915dcec 100644 --- a/src/main/resources/create_table_pgsql.sql +++ b/src/main/resources/create_table_pgsql.sql @@ -1,3 +1,5 @@ +CREATE SCHEMA IF NOT EXISTS dwh_manage; + --drop table dwh_manage.job_instances; create table dwh_manage.job_instance_status ( job_instance_id bigint not null, diff --git a/src/test/java/com/github/benoitduffez/ScriptRunner.java b/src/test/java/com/github/benoitduffez/ScriptRunner.java new file mode 100644 index 0000000..2e5944f --- /dev/null +++ b/src/test/java/com/github/benoitduffez/ScriptRunner.java @@ -0,0 +1,319 @@ +package com.github.benoitduffez; + +/* + * Slightly modified version of the com.ibatis.common.jdbc.com.github.benoitduffez.ScriptRunner class + * from the iBATIS Apache project. Only removed dependency on Resource class + * and a constructor + * GPSHansl, 06.08.2015: regex for delimiter, rearrange comment/delimiter detection, remove some ide warnings. + */ + +/* + * Copyright 2004 Clinton Begin + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import java.io.*; +import java.sql.*; +import java.text.SimpleDateFormat; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Tool to run database scripts + */ +public class ScriptRunner { + + private static final String DEFAULT_DELIMITER = ";"; + private static final Pattern SOURCE_COMMAND = Pattern.compile("^\\s*SOURCE\\s+(.*?)\\s*$", Pattern.CASE_INSENSITIVE); + + /** + * regex to detect delimiter. + * ignores spaces, allows delimiter in comment, allows an equals-sign + */ + public static final Pattern delimP = Pattern.compile("^\\s*(--)?\\s*delimiter\\s*=?\\s*([^\\s]+)+\\s*.*$", Pattern.CASE_INSENSITIVE); + + private final Connection connection; + + private final boolean stopOnError; + private final boolean autoCommit; + + @SuppressWarnings("UseOfSystemOutOrSystemErr") + private PrintWriter logWriter = null; + @SuppressWarnings("UseOfSystemOutOrSystemErr") + private PrintWriter errorLogWriter = null; + + private String delimiter = DEFAULT_DELIMITER; + private boolean fullLineDelimiter = false; + + private String userDirectory = System.getProperty("user.dir"); + + /** + * Default constructor + */ + public ScriptRunner(Connection connection, boolean autoCommit, + boolean stopOnError) { + this.connection = connection; + this.autoCommit = autoCommit; + this.stopOnError = stopOnError; + File logFile = new File("create_db.log"); + File errorLogFile = new File("create_db_error.log"); + try { + if (logFile.exists()) { + logWriter = new PrintWriter(new FileWriter(logFile, true)); + } else { + logWriter = new PrintWriter(new FileWriter(logFile, false)); + } + } catch(IOException e){ + System.err.println("Unable to access or create the db_create log"); + } + try { + if (errorLogFile.exists()) { + errorLogWriter = new PrintWriter(new FileWriter(errorLogFile, true)); + } else { + errorLogWriter = new PrintWriter(new FileWriter(errorLogFile, false)); + } + } catch(IOException e){ + System.err.println("Unable to access or create the db_create error log"); + } + String timeStamp = new SimpleDateFormat("dd/mm/yyyy HH:mm:ss").format(new java.util.Date()); + println("\n-------\n" + timeStamp + "\n-------\n"); + printlnError("\n-------\n" + timeStamp + "\n-------\n"); + } + + public void setDelimiter(String delimiter, boolean fullLineDelimiter) { + this.delimiter = delimiter; + this.fullLineDelimiter = fullLineDelimiter; + } + + /** + * Setter for logWriter property + * + * @param logWriter - the new value of the logWriter property + */ + public void setLogWriter(PrintWriter logWriter) { + this.logWriter = logWriter; + } + + /** + * Setter for errorLogWriter property + * + * @param errorLogWriter - the new value of the errorLogWriter property + */ + public void setErrorLogWriter(PrintWriter errorLogWriter) { + this.errorLogWriter = errorLogWriter; + } + + /** + * Set the current working directory. Source commands will be relative to this. + */ + public void setUserDirectory(String userDirectory) { + this.userDirectory = userDirectory; + } + + /** + * Runs an SQL script (read in using the Reader parameter) + * + * @param filepath - the filepath of the script to run. May be relative to the userDirectory. + */ + public void runScript(String filepath) throws IOException, SQLException { + File file = new File(userDirectory, filepath); + this.runScript(new BufferedReader(new FileReader(file))); + } + + /** + * Runs an SQL script (read in using the Reader parameter) + * + * @param reader - the source of the script + */ + public void runScript(Reader reader) throws IOException, SQLException { + try { + boolean originalAutoCommit = connection.getAutoCommit(); + try { + if (originalAutoCommit != this.autoCommit) { + connection.setAutoCommit(this.autoCommit); + } + runScript(connection, reader); + } finally { + connection.setAutoCommit(originalAutoCommit); + } + } catch (IOException | SQLException e) { + throw e; + } catch (Exception e) { + throw new RuntimeException("Error running script. Cause: " + e, e); + } + } + + /** + * Runs an SQL script (read in using the Reader parameter) using the + * connection passed in + * + * @param conn - the connection to use for the script + * @param reader - the source of the script + * @throws SQLException if any SQL errors occur + * @throws IOException if there is an error reading from the Reader + */ + private void runScript(Connection conn, Reader reader) throws IOException, + SQLException { + StringBuffer command = null; + try { + LineNumberReader lineReader = new LineNumberReader(reader); + String line; + while ((line = lineReader.readLine()) != null) { + if (command == null) { + command = new StringBuffer(); + } + String trimmedLine = line.trim(); + final Matcher delimMatch = delimP.matcher(trimmedLine); + if (trimmedLine.length() < 1 + || trimmedLine.startsWith("//")) { + // Do nothing + } else if (delimMatch.matches()) { + setDelimiter(delimMatch.group(2), false); + } else if (trimmedLine.startsWith("--")) { + println(trimmedLine); + } else if (trimmedLine.length() < 1 + || trimmedLine.startsWith("--")) { + // Do nothing + } else if (!fullLineDelimiter + && trimmedLine.endsWith(getDelimiter()) + || fullLineDelimiter + && trimmedLine.equals(getDelimiter())) { + command.append(line.substring(0, line + .lastIndexOf(getDelimiter()))); + command.append(" "); + this.execCommand(conn, command, lineReader); + command = null; + } else { + command.append(line); + command.append("\n"); + } + } + if (command != null) { + this.execCommand(conn, command, lineReader); + } + if (!autoCommit) { + conn.commit(); + } + } + catch (IOException e) { + throw new IOException(String.format("Error executing '%s': %s", command, e.getMessage()), e); + } finally { + conn.rollback(); + flush(); + } + } + + private void execCommand(Connection conn, StringBuffer command, + LineNumberReader lineReader) throws IOException, SQLException { + + if (command.length() == 0) { + return; + } + + Matcher sourceCommandMatcher = SOURCE_COMMAND.matcher(command); + if (sourceCommandMatcher.matches()) { + this.runScriptFile(conn, sourceCommandMatcher.group(1)); + return; + } + + this.execSqlCommand(conn, command, lineReader); + } + + private void runScriptFile(Connection conn, String filepath) throws IOException, SQLException { + File file = new File(userDirectory, filepath); + this.runScript(conn, new BufferedReader(new FileReader(file))); + } + + private void execSqlCommand(Connection conn, StringBuffer command, + LineNumberReader lineReader) throws SQLException { + + Statement statement = conn.createStatement(); + + println(command); + + boolean hasResults = false; + try { + hasResults = statement.execute(command.toString()); + } catch (SQLException e) { + final String errText = String.format("Error executing '%s' (line %d): %s", + command, lineReader.getLineNumber(), e.getMessage()); + printlnError(errText); + System.err.println(errText); + if (stopOnError) { + throw new SQLException(errText, e); + } + } + + if (autoCommit && !conn.getAutoCommit()) { + conn.commit(); + } + + ResultSet rs = statement.getResultSet(); + if (hasResults && rs != null) { + ResultSetMetaData md = rs.getMetaData(); + int cols = md.getColumnCount(); + for (int i = 1; i <= cols; i++) { + String name = md.getColumnLabel(i); + print(name + "\t"); + } + println(""); + while (rs.next()) { + for (int i = 1; i <= cols; i++) { + String value = rs.getString(i); + print(value + "\t"); + } + println(""); + } + } + + try { + statement.close(); + } catch (Exception e) { + // Ignore to workaround a bug in Jakarta DBCP + } + } + + private String getDelimiter() { + return delimiter; + } + + @SuppressWarnings("UseOfSystemOutOrSystemErr") + + private void print(Object o) { + if (logWriter != null) { + logWriter.print(o); + } + } + + private void println(Object o) { + if (logWriter != null) { + logWriter.println(o); + } + } + + private void printlnError(Object o) { + if (errorLogWriter != null) { + errorLogWriter.println(o); + } + } + + private void flush() { + if (logWriter != null) { + logWriter.flush(); + } + if (errorLogWriter != null) { + errorLogWriter.flush(); + } + } +} diff --git a/src/test/java/de/cimt/talendcomp/jobinstance/test/JobInstanceHelperTest.java b/src/test/java/de/cimt/talendcomp/jobinstance/test/JobInstanceHelperTest.java index 4b73b4b..4f28f58 100644 --- a/src/test/java/de/cimt/talendcomp/jobinstance/test/JobInstanceHelperTest.java +++ b/src/test/java/de/cimt/talendcomp/jobinstance/test/JobInstanceHelperTest.java @@ -3,6 +3,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; +import java.io.*; import java.sql.Connection; import java.sql.DriverManager; import java.text.SimpleDateFormat; @@ -10,7 +11,9 @@ import java.util.HashMap; import java.util.Map; +import com.github.benoitduffez.ScriptRunner; import org.junit.After; +import org.junit.Before; import org.junit.Test; import de.cimt.talendcomp.jobinstance.manage.JobInstanceHelper; @@ -21,10 +24,25 @@ public class JobInstanceHelperTest { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); public void createConnection() throws Exception { + String host = System.getProperty("POSTGRES_HOST"); + String port = System.getProperty("POSTGRES_PORT"); + Class.forName("org.postgresql.Driver"); - Connection conn = DriverManager.getConnection("jdbc:postgresql://debiandb.local:5432/postgres", "postgres", "postgres"); + Connection conn = DriverManager.getConnection("jdbc:postgresql://" + host + ":" + port + "/postgres", "postgres", "postgres"); globalMap.put("connection", conn); } + + @Before + public void setup() throws Exception { + createConnection(); + Connection conn = (Connection) globalMap.get("connection"); + + ScriptRunner runner = new ScriptRunner(conn, false, false); + String file = "scripts/postgresql.sql"; + + InputStream is = getClass().getClassLoader().getResourceAsStream("create_table_pgsql.sql"); + runner.runScript(new InputStreamReader(is, "utf-8")); + } @After public void tearDown() throws Exception {