From d7620d85824b9e0a1fb31ae3b292f5109ccb539f Mon Sep 17 00:00:00 2001 From: Andrey Bespalov Date: Sun, 9 Jul 2017 19:06:27 +0300 Subject: [PATCH] Implement Derby database implementation for unit testing --- .gitignore | 20 +++++++ build.gradle | 1 - src/main/java/excel2db/excel2db.java | 45 ++++++++------- .../java/excel2db/service/DBConnection.java | 5 +- .../service/impl/CreateTableDerbyImpl.java | 56 +++++++++++++++++-- .../service/impl/CreateTableOracleImpl.java | 2 +- .../service/impl/CreateTablePostgresImpl.java | 1 - .../service/impl/DBConnectionDerbyImpl.java | 42 +++----------- .../service/impl/DBConnectionOracleImpl.java | 13 +---- .../impl/DBConnectionPostgresImpl.java | 22 ++++---- .../service/impl/InitInputFilesImpl.java | 3 + src/main/resources/excel2db.properties | 14 ++--- 12 files changed, 125 insertions(+), 99 deletions(-) diff --git a/.gitignore b/.gitignore index c91b435..8d1a42f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,23 @@ + +# Idea files # +################ +/.idea/ + + +# bat files # +################ +/bin/ + +# Gradle files # +################ +.gradle + + +# Files in the build folder # +############################# +/build/ + + # Compiled source # ################### *.com diff --git a/build.gradle b/build.gradle index 198adc0..bf9f05d 100644 --- a/build.gradle +++ b/build.gradle @@ -67,7 +67,6 @@ dependencies { } - jar { manifest { diff --git a/src/main/java/excel2db/excel2db.java b/src/main/java/excel2db/excel2db.java index 775cf8d..016646d 100644 --- a/src/main/java/excel2db/excel2db.java +++ b/src/main/java/excel2db/excel2db.java @@ -6,14 +6,12 @@ import java.util.HashSet; import java.util.concurrent.TimeUnit; -import excel2db.ApplicationException; import excel2db.service.CreateTable; import excel2db.service.DBConnection; import excel2db.service.GenerateFileList; import excel2db.service.InitConstants; import excel2db.service.InitInputFiles; import excel2db.service.PopulateTable; -import excel2db.Excel2dbTask; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.ApplicationContext; @@ -85,31 +83,32 @@ public static void main(String[] args) { //this way we call methods for objects that is already initialized by the Spring app.dbConnection.establishDBConnection(); - // iterate through file name values in properties file, - // for each file start a new thread - for (String fileNameValue : fileList) { - - File fileName = new File(fileNameValue); - //check if the file really exists - if (fileName.exists() == false) { - logger.error("The file " + fileNameValue + " doesn't exist"); - } else { - taskExecutor.execute(new Excel2dbTask(app, fileName)); + // in case the connection established + // iterate through file name values in properties file, for each file start a new thread + if (connection != null) { + for (String fileNameValue : fileList) { + + File fileName = new File(fileNameValue); + //check if the file really exists + if (fileName.exists() == false) { + logger.error("The file " + fileNameValue + " doesn't exist"); + } else { + taskExecutor.execute(new Excel2dbTask(app, fileName)); + } } - } - - //TODO : This is just as a workaround to wait till the thread has been really started - //TODO : Need to use the ScheduledThreadPoolExecutor to customize delays on starting threads - TimeUnit.SECONDS.sleep(1); - // Wait until all threads are finished - logger.info("Waiting until active threads exist"); - while (taskExecutor.getActiveCount() != 0) { - } - logger.info("All threads are inactive"); - app.closeConnections(); + //TODO : This is just as a workaround to wait till the thread has been really started + //TODO : Need to use the ScheduledThreadPoolExecutor to customize delays on starting threads + TimeUnit.SECONDS.sleep(1); + // Wait until all threads are finished + logger.info("Waiting until active threads exist"); + while (taskExecutor.getActiveCount() != 0) { + } + logger.info("All threads are inactive"); + app.closeConnections(); + } } catch (Exception e) { logger.error("An exception occurred while running application", e); System.exit(1); diff --git a/src/main/java/excel2db/service/DBConnection.java b/src/main/java/excel2db/service/DBConnection.java index f178aca..bef12ee 100644 --- a/src/main/java/excel2db/service/DBConnection.java +++ b/src/main/java/excel2db/service/DBConnection.java @@ -1,7 +1,10 @@ package excel2db.service; +import java.sql.Connection; +import java.sql.SQLException; + public interface DBConnection { - public void establishDBConnection(); + public void establishDBConnection() throws SQLException; } diff --git a/src/main/java/excel2db/service/impl/CreateTableDerbyImpl.java b/src/main/java/excel2db/service/impl/CreateTableDerbyImpl.java index 0d22c99..2a5cce9 100644 --- a/src/main/java/excel2db/service/impl/CreateTableDerbyImpl.java +++ b/src/main/java/excel2db/service/impl/CreateTableDerbyImpl.java @@ -4,8 +4,14 @@ * Created by Andrey on 6/21/2017. */ +import java.sql.DatabaseMetaData; +import java.sql.PreparedStatement; +import java.sql.ResultSet; import java.sql.SQLException; +import java.util.LinkedHashMap; +import java.util.Map; +import excel2db.excel2db; import excel2db.service.CreateTable; import excel2db.service.PopulateTable; import org.apache.poi.ss.usermodel.Sheet; @@ -15,15 +21,55 @@ public class CreateTableDerbyImpl implements CreateTable { - public static final Logger logger = LoggerFactory.getLogger(PopulateTableOracleImpl.class); + public static final Logger logger = LoggerFactory.getLogger(CreateTableDerbyImpl.class); - private Integer numOfProcessedRows = 0; + public void createTable(Sheet sheet, String tableName) throws SQLException { - public void createTable(Sheet sheet, String tableName) - throws SQLException { + Map header = new LinkedHashMap<>(); + header = InitInputFilesImpl.readSheetHeader(sheet); + + //dropping statement + String sqlTableDropStatement = "DROP TABLE \"" + + tableName + "\""; + + //creating statement + StringBuilder sqlTableCreateStatement = new StringBuilder(); + sqlTableCreateStatement.append("CREATE TABLE \"" + + tableName + "\"("); + for (String headerColumnName : header.keySet()) { + sqlTableCreateStatement.append("\"" + headerColumnName + "\"" + " VARCHAR(100), "); + } + + sqlTableCreateStatement.setLength(sqlTableCreateStatement.length() - 2); + sqlTableCreateStatement.append(")"); + + + //Derby doesn't support the "DROP IF EXISTS" SQL statement + //Thus, checking the table and dropping if the table exists + logger.info("Checking if the table " + tableName + " already exists"); + DatabaseMetaData dbm = excel2db.connection.getMetaData(); + ResultSet tables = dbm.getTables(null, null, tableName, null); + if (tables.next()) { + // Table exists, dropping + logger.info("The table " + tableName + " exists, dropping ..."); + PreparedStatement pstmtDrop = excel2db.connection.prepareStatement(sqlTableDropStatement); + pstmtDrop.execute(); + logger.info("The table " + tableName + " has been dropped"); + } + else { + // Table does not exist, skipp dropping + logger.info("The table " + tableName + " doesn't exist, skip dropping"); + } + + + //creating + logger.info("The table " + tableName + " is being created ..."); + PreparedStatement pstmtCreate = excel2db.connection.prepareStatement(sqlTableCreateStatement.toString()); + pstmtCreate.execute(); + logger.info("The table " + tableName + " has been created"); - logger.info("Create table method : Derby implementation is not covered yet"); } + } diff --git a/src/main/java/excel2db/service/impl/CreateTableOracleImpl.java b/src/main/java/excel2db/service/impl/CreateTableOracleImpl.java index 0e27e07..6106ec7 100644 --- a/src/main/java/excel2db/service/impl/CreateTableOracleImpl.java +++ b/src/main/java/excel2db/service/impl/CreateTableOracleImpl.java @@ -31,7 +31,7 @@ public void createTable(Sheet sheet, String tableName) throws SQLException { sqlTableCreateStatement.append("CREATE TABLE \"" + tableName + "\"("); for (String headerColumnName : header.keySet()) { - sqlTableCreateStatement.append("\"" + headerColumnName + "\"" + " VARCHAR2(20), "); + sqlTableCreateStatement.append("\"" + headerColumnName + "\"" + " VARCHAR2(100), "); } sqlTableCreateStatement.setLength(sqlTableCreateStatement.length() - 2); diff --git a/src/main/java/excel2db/service/impl/CreateTablePostgresImpl.java b/src/main/java/excel2db/service/impl/CreateTablePostgresImpl.java index 457b923..46b5d9c 100644 --- a/src/main/java/excel2db/service/impl/CreateTablePostgresImpl.java +++ b/src/main/java/excel2db/service/impl/CreateTablePostgresImpl.java @@ -19,7 +19,6 @@ public class CreateTablePostgresImpl implements CreateTable { public void createTable(Sheet sheet, String tableName) throws SQLException { - //sheetEntityManager = new SheetEntityManager(sheet); //initializing var for a header Map header = new LinkedHashMap<>(); header = InitInputFilesImpl.readSheetHeader(sheet); diff --git a/src/main/java/excel2db/service/impl/DBConnectionDerbyImpl.java b/src/main/java/excel2db/service/impl/DBConnectionDerbyImpl.java index c6a0d98..73a5240 100644 --- a/src/main/java/excel2db/service/impl/DBConnectionDerbyImpl.java +++ b/src/main/java/excel2db/service/impl/DBConnectionDerbyImpl.java @@ -4,62 +4,34 @@ * Created by Andrey on 6/21/2017. */ +import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; +import java.util.Properties; import excel2db.excel2db; import excel2db.service.DBConnection; +import org.apache.derby.jdbc.EmbeddedDriver; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; - - - public class DBConnectionDerbyImpl implements DBConnection { - // connection parameters - @Value("${db.derby.server}") - String dbServer; - - @Value("${db.derby.user}") - String dbUser; - - @Value("${db.derby.password}") - String dbPassword; - - @Value("${db.derby.port}") - String dbPort; - - @Value("${db.derby.database}") - String dbName; - - public static final Logger logger = LoggerFactory.getLogger(DBConnectionDerbyImpl.class); public void establishDBConnection() { { - try { - excel2db.connection = DriverManager.getConnection( - //"jdbc:derby//" + dbServer + ":" + dbPort + "/" + dbName + ";create=true;user=" + dbUser + ";password=" + dbPassword - "jdbc:derby://localhost:1527/testDB;create=true" - ); + //initialize an In-Memory Derby database + EmbeddedDriver driver = new EmbeddedDriver(); + excel2db.connection = driver.connect("jdbc:derby:memory:testdb;create=true", new Properties()); + logger.info("Derby connection is established"); } catch (SQLException e) { logger.error("Derby Connection Failed! Check output console"); - e.printStackTrace(); - return; - } - if (excel2db.connection != null) { - logger.info("Derby connection is established"); - } else { - logger.error("Failed to make the Derby connection!"); } - } - } - } diff --git a/src/main/java/excel2db/service/impl/DBConnectionOracleImpl.java b/src/main/java/excel2db/service/impl/DBConnectionOracleImpl.java index 47d30ab..dffa09f 100644 --- a/src/main/java/excel2db/service/impl/DBConnectionOracleImpl.java +++ b/src/main/java/excel2db/service/impl/DBConnectionOracleImpl.java @@ -38,20 +38,11 @@ public void establishDBConnection() { try { excel2db.connection = DriverManager.getConnection( - "jdbc:oracle:thin:@//" + dbServer + ":" + dbPort + "/" + dbSid, dbUser, dbPassword) - ; - + "jdbc:oracle:thin:@//" + dbServer + ":" + dbPort + "/" + dbSid, dbUser, dbPassword); + logger.info("Oracle connection is established"); } catch (SQLException e) { logger.error("Oracle Connection Failed! Check output console"); - e.printStackTrace(); - return; } - if (excel2db.connection != null) { - logger.info("Oracle connection is established"); - } else { - logger.error("Failed to make the Oracle connection!"); - } - } } diff --git a/src/main/java/excel2db/service/impl/DBConnectionPostgresImpl.java b/src/main/java/excel2db/service/impl/DBConnectionPostgresImpl.java index 8c4d1f5..2b793e1 100644 --- a/src/main/java/excel2db/service/impl/DBConnectionPostgresImpl.java +++ b/src/main/java/excel2db/service/impl/DBConnectionPostgresImpl.java @@ -1,5 +1,6 @@ package excel2db.service.impl; +import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; @@ -29,21 +30,18 @@ public class DBConnectionPostgresImpl implements DBConnection { public static final Logger logger = LoggerFactory.getLogger(DBConnectionPostgresImpl.class); - public void establishDBConnection() { + + public void establishDBConnection() throws SQLException { + + //TODO : try to use the try-catch-resource construction, connection object should be closed as soon as the program stops working with this object try { excel2db.connection = DriverManager.getConnection( - "jdbc:postgresql://" + dbServer + ":" + dbPort + "/" + dbDatabase, dbUser, dbPassword) - ; - - } catch (SQLException e) { - logger.error("Connection Failed! Check output console"); - e.printStackTrace(); - return; - } - if (excel2db.connection != null) { + "jdbc:postgresql://" + dbServer + ":" + dbPort + "/" + dbDatabase, dbUser, dbPassword); logger.info("Postgres connection is established"); - } else { - logger.error("Failed to make connection!"); + } catch (SQLException e) { + logger.error("Postgres Connection Failed! Check output console."); } + } + } diff --git a/src/main/java/excel2db/service/impl/InitInputFilesImpl.java b/src/main/java/excel2db/service/impl/InitInputFilesImpl.java index f089c26..e306529 100644 --- a/src/main/java/excel2db/service/impl/InitInputFilesImpl.java +++ b/src/main/java/excel2db/service/impl/InitInputFilesImpl.java @@ -42,6 +42,9 @@ public void setInputSheetFile(File inputSheetFile) { public static final Logger logger = LoggerFactory.getLogger(InitInputFilesImpl.class); + //fabric method for + //fabric method pattern, we don't know which object should be created + //in advance and define the object type based on an extension @Override public Sheet initInputFiles(File inputFile) throws ApplicationException, IOException { diff --git a/src/main/resources/excel2db.properties b/src/main/resources/excel2db.properties index f3b4131..b148553 100644 --- a/src/main/resources/excel2db.properties +++ b/src/main/resources/excel2db.properties @@ -1,5 +1,8 @@ -#db implementation: Postgres, Oracle -db.implementation=Postgres +#db implementation: Postgres, Oracle, Derby +#use Derby if you run Unit tests and have no Postgres and Oracle installed on you laptop +#in this case the Derby In-Memory database will be created and used during +#the UnitTest execution +db.implementation=Derby # names of input tables input.files=test.xlsx,test1.xlsx @@ -21,15 +24,8 @@ db.oracle.password=oracle # DON'T TOUCH : - # set db implementation classes based on the db.implementation dbConnectionImplenentation=excel2db.service.impl.DBConnection${db.implementation}Impl createTableImplenentation=excel2db.service.impl.CreateTable${db.implementation}Impl -# derby connection parameters -db.derby.server=localhost -db.derby.database=excel2db -db.derby.port=5433 -db.derby.user=postgres -db.derby.password=postgres