From 8364c74e9c0144c98730d5071cc869a16192c8ea Mon Sep 17 00:00:00 2001 From: ribeaudc <ribeaudc> Date: Sat, 16 Aug 2008 19:40:25 +0000 Subject: [PATCH] change: - 'Script.getCode' renamed to 'Script.getContent'. - Java migration step stuff moved into its own package. - Improve performance: 1/ Load the script only once, and not for each pre/post method. 2/ Look only for the first line (do not scan the whole script). SVN: 7934 --- .../java/ch/systemsx/cisd/common/Script.java | 20 +- .../cisd/dbmigration/DBMigrationEngine.java | 35 +-- .../dbmigration/DatabaseVersionLogDAO.java | 4 +- .../cisd/dbmigration/IDAOFactory.java | 3 +- .../JavaMigrationStepExecutor.java | 174 ------------- .../cisd/dbmigration/SqlScriptExecutor.java | 2 +- .../cisd/dbmigration/h2/H2DAOFactory.java | 10 +- .../{ => java}/IMigrationStep.java | 12 +- .../IMigrationStepExecutor.java} | 23 +- .../java/MigrationStepExecutor.java | 144 +++++++++++ .../postgresql/PostgreSQLDAOFactory.java | 12 +- .../dbmigration/DBMigrationEngineTest.java | 241 ++++++++---------- .../JavaMigrationStepExecutorTest.java | 114 --------- .../dbmigration/SqlScriptProviderTest.java | 10 +- .../java/MigrationStepExecutorTest.java | 160 ++++++++++++ .../{ => java}/MigrationStepFrom001To002.java | 15 +- .../{ => java}/MigrationStepFrom002To003.java | 20 +- 17 files changed, 486 insertions(+), 513 deletions(-) delete mode 100644 dbmigration/source/java/ch/systemsx/cisd/dbmigration/JavaMigrationStepExecutor.java rename dbmigration/source/java/ch/systemsx/cisd/dbmigration/{ => java}/IMigrationStep.java (81%) rename dbmigration/source/java/ch/systemsx/cisd/dbmigration/{IJavaMigrationStepExecutor.java => java/IMigrationStepExecutor.java} (62%) create mode 100644 dbmigration/source/java/ch/systemsx/cisd/dbmigration/java/MigrationStepExecutor.java delete mode 100644 dbmigration/sourceTest/java/ch/systemsx/cisd/dbmigration/JavaMigrationStepExecutorTest.java create mode 100644 dbmigration/sourceTest/java/ch/systemsx/cisd/dbmigration/java/MigrationStepExecutorTest.java rename dbmigration/sourceTest/java/ch/systemsx/cisd/dbmigration/{ => java}/MigrationStepFrom001To002.java (66%) rename dbmigration/sourceTest/java/ch/systemsx/cisd/dbmigration/{ => java}/MigrationStepFrom002To003.java (53%) diff --git a/common/source/java/ch/systemsx/cisd/common/Script.java b/common/source/java/ch/systemsx/cisd/common/Script.java index 734bfccdfb9..ceedf7dc31d 100644 --- a/common/source/java/ch/systemsx/cisd/common/Script.java +++ b/common/source/java/ch/systemsx/cisd/common/Script.java @@ -28,37 +28,37 @@ public class Script { private final String name; - private final String code; + private final String content; private final String version; /** - * Creates an instance for the specified script name, code and version. + * Creates an instance for the specified script name, content and version. */ - public Script(String name, String code) + public Script(final String name, final String content) { - this(name, code, "-"); + this(name, content, "-"); } /** * Creates an instance for the specified script name, code and version. */ - public Script(String name, String code, String version) + public Script(final String name, final String content, final String version) { assert name != null; - assert code != null; + assert content != null; assert version != null; this.name = name; - this.code = code; + this.content = content; this.version = version; } /** * Returns script code. */ - public String getCode() + public String getContent() { - return code; + return content; } /** @@ -78,7 +78,7 @@ public class Script } @Override - public boolean equals(Object obj) + public boolean equals(final Object obj) { return EqualsBuilder.reflectionEquals(this, obj); } diff --git a/dbmigration/source/java/ch/systemsx/cisd/dbmigration/DBMigrationEngine.java b/dbmigration/source/java/ch/systemsx/cisd/dbmigration/DBMigrationEngine.java index 8485a5e4167..a2ee43e235f 100644 --- a/dbmigration/source/java/ch/systemsx/cisd/dbmigration/DBMigrationEngine.java +++ b/dbmigration/source/java/ch/systemsx/cisd/dbmigration/DBMigrationEngine.java @@ -24,9 +24,9 @@ import ch.systemsx.cisd.common.Script; import ch.systemsx.cisd.common.db.ISqlScriptExecutor; import ch.systemsx.cisd.common.exceptions.ConfigurationFailureException; import ch.systemsx.cisd.common.exceptions.EnvironmentFailureException; -import ch.systemsx.cisd.common.exceptions.Status; import ch.systemsx.cisd.common.logging.LogCategory; import ch.systemsx.cisd.common.logging.LogFactory; +import ch.systemsx.cisd.dbmigration.java.IMigrationStepExecutor; /** * Class for creating and migrating a database. @@ -72,7 +72,7 @@ public final class DBMigrationEngine private final ISqlScriptExecutor scriptExecutor; - private final IJavaMigrationStepExecutor javaMigrationStepExecutor; + private final IMigrationStepExecutor migrationStepExecutor; /** * Creates an instance for the specified DAO factory and SQL script provider. @@ -86,7 +86,7 @@ public final class DBMigrationEngine adminDAO = daoFactory.getDatabaseDAO(); logDAO = daoFactory.getDatabaseVersionLogDAO(); scriptExecutor = daoFactory.getSqlScriptExecutor(); - javaMigrationStepExecutor = daoFactory.getJavaMigrationStepExecutor(); + migrationStepExecutor = daoFactory.getMigrationStepExecutor(); this.scriptProvider = scriptProvider; this.shouldCreateFromScratch = shouldCreateFromScratch; } @@ -255,13 +255,11 @@ public final class DBMigrationEngine throw new EnvironmentFailureException(message); } final long time = System.currentTimeMillis(); - final Status preMigrationStatusOrNull = - javaMigrationStepExecutor.tryPerformPreMigration(migrationScript); - checkErrors(preMigrationStatusOrNull, "pre"); + migrationStepExecutor.init(migrationScript); + migrationStepExecutor.performPreMigration(); scriptExecutor.execute(migrationScript, true, logDAO); - final Status postMigrationStatusOrNull = - javaMigrationStepExecutor.tryPerformPostMigration(migrationScript); - checkErrors(postMigrationStatusOrNull, "post"); + migrationStepExecutor.performPostMigration(); + migrationStepExecutor.finish(); if (operationLog.isInfoEnabled()) { operationLog.info("Successfully migrated from version " + version + " to " @@ -271,25 +269,6 @@ public final class DBMigrationEngine } while (version.equals(toVersion) == false); } - private void checkErrors(final Status migrationStatusOrNull, final String prefix) - { - if (migrationStatusOrNull != null) - { - if (migrationStatusOrNull.isError()) - { - final String message = - String.format("Java %s-migration finnished with an error status ('%s')", - prefix, migrationStatusOrNull.tryGetErrorMessage()); - operationLog.error(message); - throw new EnvironmentFailureException(message); - } else if (operationLog.isInfoEnabled()) - { - operationLog.info(String.format("Java %s-migration succesfull.", prefix)); - } - - } - } - @Private final static String increment(final String version) { diff --git a/dbmigration/source/java/ch/systemsx/cisd/dbmigration/DatabaseVersionLogDAO.java b/dbmigration/source/java/ch/systemsx/cisd/dbmigration/DatabaseVersionLogDAO.java index 79f86a65e99..7f1a3e8bd4d 100644 --- a/dbmigration/source/java/ch/systemsx/cisd/dbmigration/DatabaseVersionLogDAO.java +++ b/dbmigration/source/java/ch/systemsx/cisd/dbmigration/DatabaseVersionLogDAO.java @@ -135,7 +135,7 @@ public class DatabaseVersionLogDAO extends SimpleJdbcDaoSupport implements IData public void createTable(Script script) { JdbcTemplate template = getJdbcTemplate(); - template.execute(script.getCode()); + template.execute(script.getContent()); } public LogEntry getLastEntry() @@ -167,7 +167,7 @@ public class DatabaseVersionLogDAO extends SimpleJdbcDaoSupport implements IData ps.setString(3, LogEntry.RunStatus.START.toString()); ps.setTimestamp(4, new Timestamp(System.currentTimeMillis())); lobCreator - .setBlobAsBytes(ps, 5, getAsByteArray(moduleScript.getCode())); + .setBlobAsBytes(ps, 5, getAsByteArray(moduleScript.getContent())); } }; template.execute("insert into " + DB_VERSION_LOG + " (" + DB_VERSION + "," + MODULE_NAME diff --git a/dbmigration/source/java/ch/systemsx/cisd/dbmigration/IDAOFactory.java b/dbmigration/source/java/ch/systemsx/cisd/dbmigration/IDAOFactory.java index bea2fdb05d2..200168f2424 100644 --- a/dbmigration/source/java/ch/systemsx/cisd/dbmigration/IDAOFactory.java +++ b/dbmigration/source/java/ch/systemsx/cisd/dbmigration/IDAOFactory.java @@ -17,6 +17,7 @@ package ch.systemsx.cisd.dbmigration; import ch.systemsx.cisd.common.db.ISqlScriptExecutor; +import ch.systemsx.cisd.dbmigration.java.IMigrationStepExecutor; /** * Factory for DAOs. @@ -48,5 +49,5 @@ public interface IDAOFactory /** * Returns the java migration step executor. */ - public IJavaMigrationStepExecutor getJavaMigrationStepExecutor(); + public IMigrationStepExecutor getMigrationStepExecutor(); } diff --git a/dbmigration/source/java/ch/systemsx/cisd/dbmigration/JavaMigrationStepExecutor.java b/dbmigration/source/java/ch/systemsx/cisd/dbmigration/JavaMigrationStepExecutor.java deleted file mode 100644 index 54841948366..00000000000 --- a/dbmigration/source/java/ch/systemsx/cisd/dbmigration/JavaMigrationStepExecutor.java +++ /dev/null @@ -1,174 +0,0 @@ -/* - * Copyright 2007 ETH Zuerich, CISD - * - * 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. - */ - -package ch.systemsx.cisd.dbmigration; - -import java.util.Arrays; -import java.util.List; - -import javax.sql.DataSource; - -import org.apache.commons.lang.StringUtils; -import org.springframework.jdbc.core.simple.SimpleJdbcDaoSupport; - -import ch.systemsx.cisd.common.Script; -import ch.systemsx.cisd.common.exceptions.EnvironmentFailureException; -import ch.systemsx.cisd.common.exceptions.Status; -import ch.systemsx.cisd.common.utilities.ClassUtils; - -/** - * Allows to extract {@link IMigrationStep} class from migration script and run the <i>pre</i>- and - * <i>post</i>- migration java steps.<br> - * Example of the script containing Java Migration Step definition: - * - * <pre> - * -- JAVA ch.systemsx.cisd.openbis.db.migration.MigrationStepFrom022To023 - * </pre> - * - * @author Izabela Adamczyk - */ -public class JavaMigrationStepExecutor extends SimpleJdbcDaoSupport implements - IJavaMigrationStepExecutor -{ - private static final String JAVA_MIGRATION_STEP_PREFIX = "--JAVA"; - - public JavaMigrationStepExecutor(final DataSource dataSource) - { - setDataSource(dataSource); - } - - private IMigrationStep tryExtractMigrationStep(final Script sqlScript) - - { - if (sqlScript == null || StringUtils.isBlank(sqlScript.getCode())) - { - return null; - } - final String code = sqlScript.getCode(); - final List<String> lines = Arrays.asList(code.split("\n")); - IMigrationStep extratedMigrationStepOrNull = null; - boolean nonEmptyLineFound = false; - for (final String line : lines) - { - // blank lines are allowed at the beginning of the script - if (StringUtils.isBlank(line)) - { - continue; - } - // only the first non-blank line is supposed to contain Java Migration Step - if (nonEmptyLineFound == false) - { - extratedMigrationStepOrNull = tryExtractMigrationStepFromLine(line); - nonEmptyLineFound = true; - } else - { - checkIfCurrentLineConsistentWithAlredyProcessed(sqlScript, - extratedMigrationStepOrNull, line); - } - } - return extratedMigrationStepOrNull; - } - - private void checkIfCurrentLineConsistentWithAlredyProcessed(final Script sqlScript, - final IMigrationStep extratedMigrationStepOrNull, final String line) - { - if (tryExtractMigrationStepFromLine(line) != null) - { - final String msg; - if (extratedMigrationStepOrNull != null) - { - - msg = - String.format("Migration script '%s' contains more " - + "than one Java Migration Steps.", sqlScript.getName()); - } else - { - msg = - String.format("Java Migration Step should be defined in the first " - + "non-blank line of the migration script '%s'.", sqlScript - .getName()); - } - throw new EnvironmentFailureException(msg); - } - } - - private final IMigrationStep tryExtractMigrationStepFromLine(final String lineToProcess) - { - final String line = StringUtils.deleteWhitespace(lineToProcess); - if (line != null && line.startsWith(JAVA_MIGRATION_STEP_PREFIX)) - { - final String className = StringUtils.removeStart(line, JAVA_MIGRATION_STEP_PREFIX); - try - { - return (IMigrationStep) ClassUtils.createInstance(Class.forName(className)); - } catch (final ClassNotFoundException ex) - { - throw new EnvironmentFailureException(String.format("Class '%s' not found.", - className)); - } catch (final RuntimeException ex) - { - throw new EnvironmentFailureException(ex.getMessage()); - } - } else - { - return null; - } - } - - // - // IJavaMigrationStepExecutor - // - - /** - * Returns null if MigrationStep has not been found and status returned by - * {@link IMigrationStep#performPreMigration(org.springframework.jdbc.core.simple.SimpleJdbcTemplate)} - * otherwise. - */ - public final Status tryPerformPreMigration(final Script sqlScript) - - { - final IMigrationStep migrationStep = tryExtractMigrationStep(sqlScript); - if (migrationStep != null) - { - final Status preMigrationStatus = - migrationStep.performPreMigration(getSimpleJdbcTemplate()); - return preMigrationStatus; - } else - { - return null; - } - } - - /** - * Returns null if MigrationStep has not been found and status returned by - * {@link IMigrationStep#performPostMigration(org.springframework.jdbc.core.simple.SimpleJdbcTemplate)} - * otherwise. - */ - public final Status tryPerformPostMigration(final Script sqlScript) - { - final IMigrationStep migrationStep = tryExtractMigrationStep(sqlScript); - if (migrationStep != null) - { - final Status postMigrationStatus = - migrationStep.performPostMigration(getSimpleJdbcTemplate()); - return postMigrationStatus; - } else - { - return null; - } - } - -} diff --git a/dbmigration/source/java/ch/systemsx/cisd/dbmigration/SqlScriptExecutor.java b/dbmigration/source/java/ch/systemsx/cisd/dbmigration/SqlScriptExecutor.java index 544550c755e..803cecd0a53 100644 --- a/dbmigration/source/java/ch/systemsx/cisd/dbmigration/SqlScriptExecutor.java +++ b/dbmigration/source/java/ch/systemsx/cisd/dbmigration/SqlScriptExecutor.java @@ -62,7 +62,7 @@ public class SqlScriptExecutor extends JdbcDaoSupport implements ISqlScriptExecu } try { - final String sqlScriptCode = sqlScript.getCode(); + final String sqlScriptCode = sqlScript.getContent(); if (singleStepMode && honorSingleStepMode) { String lastSqlStatement = ""; diff --git a/dbmigration/source/java/ch/systemsx/cisd/dbmigration/h2/H2DAOFactory.java b/dbmigration/source/java/ch/systemsx/cisd/dbmigration/h2/H2DAOFactory.java index 27863e57017..72a0fdf34ad 100644 --- a/dbmigration/source/java/ch/systemsx/cisd/dbmigration/h2/H2DAOFactory.java +++ b/dbmigration/source/java/ch/systemsx/cisd/dbmigration/h2/H2DAOFactory.java @@ -27,10 +27,10 @@ import ch.systemsx.cisd.dbmigration.DatabaseVersionLogDAO; import ch.systemsx.cisd.dbmigration.IDAOFactory; import ch.systemsx.cisd.dbmigration.IDatabaseAdminDAO; import ch.systemsx.cisd.dbmigration.IDatabaseVersionLogDAO; -import ch.systemsx.cisd.dbmigration.IJavaMigrationStepExecutor; import ch.systemsx.cisd.dbmigration.IMassUploader; -import ch.systemsx.cisd.dbmigration.JavaMigrationStepExecutor; import ch.systemsx.cisd.dbmigration.SqlScriptExecutor; +import ch.systemsx.cisd.dbmigration.java.IMigrationStepExecutor; +import ch.systemsx.cisd.dbmigration.java.MigrationStepExecutor; /** * Implementation of {@link IDAOFactory} for H2. @@ -47,7 +47,7 @@ public class H2DAOFactory implements IDAOFactory private final IMassUploader massUploader; - private final IJavaMigrationStepExecutor javaMigrationStepExecutor; + private final IMigrationStepExecutor javaMigrationStepExecutor; /** * Creates an instance based on the specified configuration context. @@ -56,7 +56,7 @@ public class H2DAOFactory implements IDAOFactory { final DataSource dataSource = context.getDataSource(); sqlScriptExecutor = new SqlScriptExecutor(dataSource, context.isScriptSingleStepMode()); - javaMigrationStepExecutor = new JavaMigrationStepExecutor(dataSource); + javaMigrationStepExecutor = new MigrationStepExecutor(dataSource); databaseVersionLogDAO = new DatabaseVersionLogDAO(dataSource, context.getLobHandler()); try { @@ -90,7 +90,7 @@ public class H2DAOFactory implements IDAOFactory return massUploader; } - public IJavaMigrationStepExecutor getJavaMigrationStepExecutor() + public IMigrationStepExecutor getMigrationStepExecutor() { return javaMigrationStepExecutor; } diff --git a/dbmigration/source/java/ch/systemsx/cisd/dbmigration/IMigrationStep.java b/dbmigration/source/java/ch/systemsx/cisd/dbmigration/java/IMigrationStep.java similarity index 81% rename from dbmigration/source/java/ch/systemsx/cisd/dbmigration/IMigrationStep.java rename to dbmigration/source/java/ch/systemsx/cisd/dbmigration/java/IMigrationStep.java index a4a727c4abd..7b9aa7389d0 100644 --- a/dbmigration/source/java/ch/systemsx/cisd/dbmigration/IMigrationStep.java +++ b/dbmigration/source/java/ch/systemsx/cisd/dbmigration/java/IMigrationStep.java @@ -14,12 +14,11 @@ * limitations under the License. */ -package ch.systemsx.cisd.dbmigration; +package ch.systemsx.cisd.dbmigration.java; +import org.springframework.dao.DataAccessException; import org.springframework.jdbc.core.simple.SimpleJdbcTemplate; -import ch.systemsx.cisd.common.exceptions.Status; - /** * An interface which must be implemented by all classes providing Java code that performs migration * steps prior (<i>pre</i>) or after (<i>post</i>) the SQL migration script ran. @@ -44,11 +43,12 @@ public interface IMigrationStep /** * Called before the SQL migration is performed. */ - public Status performPreMigration(final SimpleJdbcTemplate simpleJdbcTemplate); + public void performPreMigration(final SimpleJdbcTemplate simpleJdbcTemplate) + throws DataAccessException; /** * Called after the SQL migration has been performed. */ - public Status performPostMigration(final SimpleJdbcTemplate simpleJdbcTemplate); - + public void performPostMigration(final SimpleJdbcTemplate simpleJdbcTemplate) + throws DataAccessException; } diff --git a/dbmigration/source/java/ch/systemsx/cisd/dbmigration/IJavaMigrationStepExecutor.java b/dbmigration/source/java/ch/systemsx/cisd/dbmigration/java/IMigrationStepExecutor.java similarity index 62% rename from dbmigration/source/java/ch/systemsx/cisd/dbmigration/IJavaMigrationStepExecutor.java rename to dbmigration/source/java/ch/systemsx/cisd/dbmigration/java/IMigrationStepExecutor.java index 4f6df71730d..20bc5998d63 100644 --- a/dbmigration/source/java/ch/systemsx/cisd/dbmigration/IJavaMigrationStepExecutor.java +++ b/dbmigration/source/java/ch/systemsx/cisd/dbmigration/java/IMigrationStepExecutor.java @@ -14,26 +14,39 @@ * limitations under the License. */ -package ch.systemsx.cisd.dbmigration; +package ch.systemsx.cisd.dbmigration.java; import ch.systemsx.cisd.common.Script; -import ch.systemsx.cisd.common.exceptions.Status; /** * A migration step executor. * * @author Christian Ribeaud */ -public interface IJavaMigrationStepExecutor +public interface IMigrationStepExecutor { + /** + * Initializes the migration step executor with given <var>migrationScript</var>. + * <p> + * Is called just before {@link #performPreMigration()} and/or {@link #performPostMigration()}. + * </p> + */ + public void init(final Script migrationScript); + /** * Performs some step after the migration has happened. */ - public Status tryPerformPostMigration(final Script sqlScript); + public void performPostMigration(); /** * Performs some step before the migration has happened. */ - public Status tryPerformPreMigration(final Script sqlScript); + public void performPreMigration(); + + /** + * Resets the migration step executor. + */ + public void finish(); + } diff --git a/dbmigration/source/java/ch/systemsx/cisd/dbmigration/java/MigrationStepExecutor.java b/dbmigration/source/java/ch/systemsx/cisd/dbmigration/java/MigrationStepExecutor.java new file mode 100644 index 00000000000..c96289cbd82 --- /dev/null +++ b/dbmigration/source/java/ch/systemsx/cisd/dbmigration/java/MigrationStepExecutor.java @@ -0,0 +1,144 @@ +/* + * Copyright 2007 ETH Zuerich, CISD + * + * 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. + */ + +package ch.systemsx.cisd.dbmigration.java; + +import java.io.StringReader; + +import javax.sql.DataSource; + +import org.apache.commons.lang.StringUtils; +import org.apache.log4j.Logger; +import org.springframework.jdbc.core.simple.SimpleJdbcDaoSupport; + +import ch.systemsx.cisd.common.Script; +import ch.systemsx.cisd.common.exceptions.CheckedExceptionTunnel; +import ch.systemsx.cisd.common.logging.LogCategory; +import ch.systemsx.cisd.common.logging.LogFactory; +import ch.systemsx.cisd.common.parser.Line; +import ch.systemsx.cisd.common.parser.ParserUtilities; +import ch.systemsx.cisd.common.parser.filter.NonEmptyLineFilter; +import ch.systemsx.cisd.common.utilities.ClassUtils; + +/** + * Allows to extract {@link IMigrationStep} class from migration script and run the <i>pre</i>- and + * <i>post</i>- migration java steps.<br> + * Example of the script containing Java Migration Step definition: + * + * <pre> + * -- JAVA ch.systemsx.cisd.openbis.db.migration.MigrationStepFrom022To023 + * </pre> + * + * @author Izabela Adamczyk + */ +public class MigrationStepExecutor extends SimpleJdbcDaoSupport implements IMigrationStepExecutor +{ + private static final Logger operationLog = + LogFactory.getLogger(LogCategory.OPERATION, MigrationStepExecutor.class); + + private static final String JAVA_MIGRATION_STEP_PREFIX = "--JAVA"; + + private IMigrationStep migrationStep; + + private boolean inited; + + public MigrationStepExecutor(final DataSource dataSource) + { + setDataSource(dataSource); + } + + private final static IMigrationStep tryExtractMigrationStep(final Script sqlScript) + + { + assert sqlScript != null : "SQL script not provided"; + final String content = sqlScript.getContent(); + if (StringUtils.isBlank(content)) + { + return null; + } + final Line firstNonEmptyLineOrNull = + ParserUtilities.tryGetFirstAcceptedLine(new StringReader(content), + NonEmptyLineFilter.INSTANCE); + if (firstNonEmptyLineOrNull != null) + { + return tryExtractMigrationStepFromLine(firstNonEmptyLineOrNull.getText()); + } + return null; + } + + private final static IMigrationStep tryExtractMigrationStepFromLine(final String lineToProcess) + { + final String line = StringUtils.deleteWhitespace(lineToProcess); + if (line != null && line.startsWith(JAVA_MIGRATION_STEP_PREFIX)) + { + final String className = StringUtils.removeStart(line, JAVA_MIGRATION_STEP_PREFIX); + try + { + return (IMigrationStep) ClassUtils.createInstance(Class.forName(className)); + } catch (final ClassNotFoundException ex) + { + throw CheckedExceptionTunnel.wrapIfNecessary(ex); + } + } else + { + return null; + } + } + + // + // IMigrationStepExecutor + // + + public final void init(final Script migrationScript) + { + migrationStep = tryExtractMigrationStep(migrationScript); + if (migrationStep != null) + { + operationLog.info(String.format( + "Migration step class '%s' found for migration script '%s'.", migrationStep + .getClass().getSimpleName(), migrationScript.getName())); + } else + { + operationLog.debug(String.format( + "No migration step class found for migration script '%s'.", migrationScript + .getName())); + } + inited = true; + } + + public final void performPreMigration() + { + assert inited : "Executor not initialized."; + if (migrationStep != null) + { + migrationStep.performPreMigration(getSimpleJdbcTemplate()); + } + } + + public final void performPostMigration() + { + assert inited : "Executor not initialized."; + if (migrationStep != null) + { + migrationStep.performPostMigration(getSimpleJdbcTemplate()); + } + } + + public final void finish() + { + inited = false; + } +} diff --git a/dbmigration/source/java/ch/systemsx/cisd/dbmigration/postgresql/PostgreSQLDAOFactory.java b/dbmigration/source/java/ch/systemsx/cisd/dbmigration/postgresql/PostgreSQLDAOFactory.java index 60e5da6698b..4226b9683bb 100644 --- a/dbmigration/source/java/ch/systemsx/cisd/dbmigration/postgresql/PostgreSQLDAOFactory.java +++ b/dbmigration/source/java/ch/systemsx/cisd/dbmigration/postgresql/PostgreSQLDAOFactory.java @@ -27,10 +27,10 @@ import ch.systemsx.cisd.dbmigration.DatabaseVersionLogDAO; import ch.systemsx.cisd.dbmigration.IDAOFactory; import ch.systemsx.cisd.dbmigration.IDatabaseAdminDAO; import ch.systemsx.cisd.dbmigration.IDatabaseVersionLogDAO; -import ch.systemsx.cisd.dbmigration.IJavaMigrationStepExecutor; import ch.systemsx.cisd.dbmigration.IMassUploader; -import ch.systemsx.cisd.dbmigration.JavaMigrationStepExecutor; import ch.systemsx.cisd.dbmigration.SqlScriptExecutor; +import ch.systemsx.cisd.dbmigration.java.IMigrationStepExecutor; +import ch.systemsx.cisd.dbmigration.java.MigrationStepExecutor; /** * Implementation of {@link IDAOFactory} for PostgreSQL. @@ -47,7 +47,7 @@ public class PostgreSQLDAOFactory implements IDAOFactory private final IMassUploader massUploader; - private final IJavaMigrationStepExecutor javaMigrationStepExecutor; + private final IMigrationStepExecutor migrationStepExecutor; /** * Creates an instance based on the specified configuration context. @@ -56,7 +56,7 @@ public class PostgreSQLDAOFactory implements IDAOFactory { final DataSource dataSource = context.getDataSource(); sqlScriptExecutor = new SqlScriptExecutor(dataSource, context.isScriptSingleStepMode()); - javaMigrationStepExecutor = new JavaMigrationStepExecutor(dataSource); + migrationStepExecutor = new MigrationStepExecutor(dataSource); databaseVersionLogDAO = new DatabaseVersionLogDAO(dataSource, context.getLobHandler()); try { @@ -91,9 +91,9 @@ public class PostgreSQLDAOFactory implements IDAOFactory return massUploader; } - public IJavaMigrationStepExecutor getJavaMigrationStepExecutor() + public IMigrationStepExecutor getMigrationStepExecutor() { - return javaMigrationStepExecutor; + return migrationStepExecutor; } } diff --git a/dbmigration/sourceTest/java/ch/systemsx/cisd/dbmigration/DBMigrationEngineTest.java b/dbmigration/sourceTest/java/ch/systemsx/cisd/dbmigration/DBMigrationEngineTest.java index bce3d3e46df..0dd11e5d61d 100644 --- a/dbmigration/sourceTest/java/ch/systemsx/cisd/dbmigration/DBMigrationEngineTest.java +++ b/dbmigration/sourceTest/java/ch/systemsx/cisd/dbmigration/DBMigrationEngineTest.java @@ -18,16 +18,18 @@ package ch.systemsx.cisd.dbmigration; import static org.testng.AssertJUnit.assertEquals; import static org.testng.AssertJUnit.assertSame; -import static org.testng.AssertJUnit.assertTrue; import static org.testng.AssertJUnit.fail; import java.io.File; import java.sql.SQLException; import java.util.Date; +import org.apache.commons.lang.StringUtils; import org.apache.log4j.Level; import org.jmock.Expectations; import org.jmock.Mockery; +import org.springframework.dao.DataIntegrityViolationException; +import org.springframework.dao.EmptyResultDataAccessException; import org.springframework.jdbc.BadSqlGrammarException; import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeMethod; @@ -38,9 +40,9 @@ import ch.systemsx.cisd.common.Script; import ch.systemsx.cisd.common.db.ISqlScriptExecutor; import ch.systemsx.cisd.common.exceptions.ConfigurationFailureException; import ch.systemsx.cisd.common.exceptions.EnvironmentFailureException; -import ch.systemsx.cisd.common.exceptions.Status; import ch.systemsx.cisd.common.logging.BufferedAppender; import ch.systemsx.cisd.common.utilities.OSUtilities; +import ch.systemsx.cisd.dbmigration.java.IMigrationStepExecutor; /** * Tests of {@link DBMigrationEngine} using mocks for database and {@link SqlScriptProvider}. @@ -64,11 +66,11 @@ public class DBMigrationEngineTest final boolean honorSingleStepMode) { will(returnValue(script)); - one(javaMigrationStepExecutor).tryPerformPreMigration(script); - will(returnValue(Status.OK)); + one(migrationStepExecutor).init(script); + one(migrationStepExecutor).performPreMigration(); one(scriptExecutor).execute(script, honorSingleStepMode, logDAO); - one(javaMigrationStepExecutor).tryPerformPostMigration(script); - will(returnValue(Status.OK)); + one(migrationStepExecutor).performPostMigration(); + one(migrationStepExecutor).finish(); } } @@ -84,7 +86,7 @@ public class DBMigrationEngineTest private ISqlScriptExecutor scriptExecutor; - private IJavaMigrationStepExecutor javaMigrationStepExecutor; + private IMigrationStepExecutor migrationStepExecutor; private BufferedAppender logRecorder; @@ -97,7 +99,7 @@ public class DBMigrationEngineTest adminDAO = context.mock(IDatabaseAdminDAO.class); logDAO = context.mock(IDatabaseVersionLogDAO.class); scriptExecutor = context.mock(ISqlScriptExecutor.class); - javaMigrationStepExecutor = context.mock(IJavaMigrationStepExecutor.class); + migrationStepExecutor = context.mock(IMigrationStepExecutor.class); logRecorder = new BufferedAppender("%-5p %c - %m%n", Level.DEBUG); } @@ -132,8 +134,8 @@ public class DBMigrationEngineTest will(returnValue(logDAO)); one(daoFactory).getSqlScriptExecutor(); will(returnValue(scriptExecutor)); - one(daoFactory).getJavaMigrationStepExecutor(); - will(returnValue(javaMigrationStepExecutor)); + one(daoFactory).getMigrationStepExecutor(); + will(returnValue(migrationStepExecutor)); one(adminDAO).dropDatabase(); one(logDAO).canConnectToDatabase(); @@ -159,13 +161,11 @@ public class DBMigrationEngineTest final DBMigrationEngine migrationEngine = new DBMigrationEngine(daoFactory, scriptProvider, true); migrationEngine.migrateTo(version); - assertEquals( - "INFO OPERATION.DBMigrationEngine - Dropping database." - + OSUtilities.LINE_SEPARATOR - + "INFO OPERATION.DBMigrationEngine - " - + "Database 'my 1. database' does not exist." + OSUtilities.LINE_SEPARATOR - + "INFO OPERATION.DBMigrationEngine - " - + "Database 'my 2. database' version 042 has been successfully created.", + assertEquals("INFO OPERATION.DBMigrationEngine - Dropping database." + + OSUtilities.LINE_SEPARATOR + "INFO OPERATION.DBMigrationEngine - " + + "Database 'my 1. database' does not exist." + OSUtilities.LINE_SEPARATOR + + "INFO OPERATION.DBMigrationEngine - " + + "Database 'my 2. database' version 042 has been successfully created.", logRecorder.getLogContent()); context.assertIsSatisfied(); @@ -184,8 +184,8 @@ public class DBMigrationEngineTest will(returnValue(logDAO)); one(daoFactory).getSqlScriptExecutor(); will(returnValue(scriptExecutor)); - one(daoFactory).getJavaMigrationStepExecutor(); - will(returnValue(javaMigrationStepExecutor)); + one(daoFactory).getMigrationStepExecutor(); + will(returnValue(migrationStepExecutor)); one(adminDAO).dropDatabase(); one(logDAO).canConnectToDatabase(); @@ -207,13 +207,11 @@ public class DBMigrationEngineTest final DBMigrationEngine migrationEngine = new DBMigrationEngine(daoFactory, scriptProvider, true); migrationEngine.migrateTo(version); - assertEquals( - "INFO OPERATION.DBMigrationEngine - Dropping database." - + OSUtilities.LINE_SEPARATOR - + "INFO OPERATION.DBMigrationEngine - " - + "Database 'my 1. database' does not exist." + OSUtilities.LINE_SEPARATOR - + "INFO OPERATION.DBMigrationEngine - " - + "Database 'my 2. database' version 042 has been successfully created.", + assertEquals("INFO OPERATION.DBMigrationEngine - Dropping database." + + OSUtilities.LINE_SEPARATOR + "INFO OPERATION.DBMigrationEngine - " + + "Database 'my 1. database' does not exist." + OSUtilities.LINE_SEPARATOR + + "INFO OPERATION.DBMigrationEngine - " + + "Database 'my 2. database' version 042 has been successfully created.", logRecorder.getLogContent()); context.assertIsSatisfied(); @@ -235,8 +233,8 @@ public class DBMigrationEngineTest one(daoFactory).getSqlScriptExecutor(); will(returnValue(scriptExecutor)); - one(daoFactory).getJavaMigrationStepExecutor(); - will(returnValue(javaMigrationStepExecutor)); + one(daoFactory).getMigrationStepExecutor(); + will(returnValue(migrationStepExecutor)); one(adminDAO).dropDatabase(); one(logDAO).canConnectToDatabase(); @@ -257,11 +255,9 @@ public class DBMigrationEngineTest { assertSame(exception, e); } - assertEquals( - "INFO OPERATION.DBMigrationEngine - Dropping database." - + OSUtilities.LINE_SEPARATOR - + "INFO OPERATION.DBMigrationEngine - " - + "Database 'my 1. database' does not exist.", logRecorder.getLogContent()); + assertEquals("INFO OPERATION.DBMigrationEngine - Dropping database." + + OSUtilities.LINE_SEPARATOR + "INFO OPERATION.DBMigrationEngine - " + + "Database 'my 1. database' does not exist.", logRecorder.getLogContent()); context.assertIsSatisfied(); } @@ -279,8 +275,8 @@ public class DBMigrationEngineTest will(returnValue(logDAO)); one(daoFactory).getSqlScriptExecutor(); will(returnValue(scriptExecutor)); - one(daoFactory).getJavaMigrationStepExecutor(); - will(returnValue(javaMigrationStepExecutor)); + one(daoFactory).getMigrationStepExecutor(); + will(returnValue(migrationStepExecutor)); one(logDAO).canConnectToDatabase(); will(returnValue(false)); @@ -326,8 +322,8 @@ public class DBMigrationEngineTest one(daoFactory).getSqlScriptExecutor(); will(returnValue(scriptExecutor)); - one(daoFactory).getJavaMigrationStepExecutor(); - will(returnValue(javaMigrationStepExecutor)); + one(daoFactory).getMigrationStepExecutor(); + will(returnValue(migrationStepExecutor)); one(logDAO).canConnectToDatabase(); will(returnValue(false)); @@ -374,8 +370,8 @@ public class DBMigrationEngineTest will(returnValue(logDAO)); one(daoFactory).getSqlScriptExecutor(); will(returnValue(scriptExecutor)); - one(daoFactory).getJavaMigrationStepExecutor(); - will(returnValue(javaMigrationStepExecutor)); + one(daoFactory).getMigrationStepExecutor(); + will(returnValue(migrationStepExecutor)); one(logDAO).canConnectToDatabase(); will(returnValue(false)); @@ -402,8 +398,7 @@ public class DBMigrationEngineTest } assertEquals("INFO OPERATION.DBMigrationEngine - " + "Database 'my 1. database' does not exist." + OSUtilities.LINE_SEPARATOR - + "ERROR OPERATION.DBMigrationEngine - " + message, - logRecorder.getLogContent()); + + "ERROR OPERATION.DBMigrationEngine - " + message, logRecorder.getLogContent()); context.assertIsSatisfied(); } @@ -421,8 +416,8 @@ public class DBMigrationEngineTest will(returnValue(logDAO)); one(daoFactory).getSqlScriptExecutor(); will(returnValue(scriptExecutor)); - one(daoFactory).getJavaMigrationStepExecutor(); - will(returnValue(javaMigrationStepExecutor)); + one(daoFactory).getMigrationStepExecutor(); + will(returnValue(migrationStepExecutor)); one(logDAO).canConnectToDatabase(); will(returnValue(true)); @@ -441,11 +436,10 @@ public class DBMigrationEngineTest new DBMigrationEngine(daoFactory, scriptProvider, false); migrationEngine.migrateTo(version); - assertEquals( - "DEBUG OPERATION.DBMigrationEngine - " - + "No migration needed for database 'my database'. It has the right version (042)." - + OSUtilities.LINE_SEPARATOR - + "INFO OPERATION.DBMigrationEngine - Using database 'my database URL'", + assertEquals("DEBUG OPERATION.DBMigrationEngine - " + + "No migration needed for database 'my database'. It has the right version (042)." + + OSUtilities.LINE_SEPARATOR + + "INFO OPERATION.DBMigrationEngine - Using database 'my database URL'", logRecorder.getLogContent()); context.assertIsSatisfied(); @@ -465,8 +459,8 @@ public class DBMigrationEngineTest will(returnValue(logDAO)); one(daoFactory).getSqlScriptExecutor(); will(returnValue(scriptExecutor)); - one(daoFactory).getJavaMigrationStepExecutor(); - will(returnValue(javaMigrationStepExecutor)); + one(daoFactory).getMigrationStepExecutor(); + will(returnValue(migrationStepExecutor)); one(logDAO).canConnectToDatabase(); will(returnValue(true)); @@ -497,28 +491,16 @@ public class DBMigrationEngineTest migrationEngine.migrateTo(toVersion); String logContent = logRecorder.getLogContent(); logContent = logContent.replaceAll("\\d+ msec", "0 msec"); - assertEquals( - "INFO OPERATION.DBMigrationEngine - " - + "Trying to migrate database 'my 1. database' from version 099 to 101." - + OSUtilities.LINE_SEPARATOR - + "INFO OPERATION.DBMigrationEngine - Java pre-migration succesfull." - + OSUtilities.LINE_SEPARATOR - + "INFO OPERATION.DBMigrationEngine - Java post-migration succesfull." - + OSUtilities.LINE_SEPARATOR - + "INFO OPERATION.DBMigrationEngine - " - + "Successfully migrated from version 099 to 100 in 0 msec" - + OSUtilities.LINE_SEPARATOR - + "INFO OPERATION.DBMigrationEngine - Java pre-migration succesfull." - + OSUtilities.LINE_SEPARATOR - + "INFO OPERATION.DBMigrationEngine - Java post-migration succesfull." - + OSUtilities.LINE_SEPARATOR - + "INFO OPERATION.DBMigrationEngine - " - + "Successfully migrated from version 100 to 101 in 0 msec" - + OSUtilities.LINE_SEPARATOR - + "INFO OPERATION.DBMigrationEngine - " - + "Database 'my 2. database' successfully migrated from version 099 to 101." - + OSUtilities.LINE_SEPARATOR - + "INFO OPERATION.DBMigrationEngine - Using database 'my database URL'", + assertEquals("INFO OPERATION.DBMigrationEngine - " + + "Trying to migrate database 'my 1. database' from version 099 to 101." + + OSUtilities.LINE_SEPARATOR + "INFO OPERATION.DBMigrationEngine - " + + "Successfully migrated from version 099 to 100 in 0 msec" + + OSUtilities.LINE_SEPARATOR + "INFO OPERATION.DBMigrationEngine - " + + "Successfully migrated from version 100 to 101 in 0 msec" + + OSUtilities.LINE_SEPARATOR + "INFO OPERATION.DBMigrationEngine - " + + "Database 'my 2. database' successfully migrated from version 099 to 101." + + OSUtilities.LINE_SEPARATOR + + "INFO OPERATION.DBMigrationEngine - Using database 'my database URL'", logContent); context.assertIsSatisfied(); @@ -538,8 +520,8 @@ public class DBMigrationEngineTest will(returnValue(logDAO)); one(daoFactory).getSqlScriptExecutor(); will(returnValue(scriptExecutor)); - one(daoFactory).getJavaMigrationStepExecutor(); - will(returnValue(javaMigrationStepExecutor)); + one(daoFactory).getMigrationStepExecutor(); + will(returnValue(migrationStepExecutor)); one(logDAO).canConnectToDatabase(); will(returnValue(true)); @@ -555,40 +537,29 @@ public class DBMigrationEngineTest will(returnValue(script)); - one(javaMigrationStepExecutor).tryPerformPreMigration(script); - will(returnValue(Status.OK)); + one(migrationStepExecutor).init(script); + one(migrationStepExecutor).performPreMigration(); one(scriptExecutor).execute(script, true, logDAO); - one(javaMigrationStepExecutor).tryPerformPostMigration(script); - will(returnValue(Status.createError("Bad system user code."))); + one(migrationStepExecutor).performPostMigration(); + will(throwException(new DataIntegrityViolationException(StringUtils.EMPTY))); } }); final DBMigrationEngine migrationEngine = new DBMigrationEngine(daoFactory, scriptProvider, false); - - boolean exceptionThrown = false; try { migrationEngine.migrateTo(toVersion); - } catch (final EnvironmentFailureException e) + fail(); + } catch (final DataIntegrityViolationException e) { - exceptionThrown = true; - assertEquals( - "Java post-migration finnished with an error status ('Bad system user code.')", - e.getMessage()); + // Nothing to do here. } - assertTrue(exceptionThrown); String logContent = logRecorder.getLogContent(); logContent = logContent.replaceAll("\\d+ msec", "0 msec"); - assertEquals( - "INFO OPERATION.DBMigrationEngine - " - + "Trying to migrate database 'my 1. database' from version 099 to 101." - + OSUtilities.LINE_SEPARATOR - + "INFO OPERATION.DBMigrationEngine - Java pre-migration succesfull." - + OSUtilities.LINE_SEPARATOR - + "ERROR OPERATION.DBMigrationEngine - Java post-migration finnished with an error status ('Bad system user code.')", + assertEquals("INFO OPERATION.DBMigrationEngine - " + + "Trying to migrate database 'my 1. database' from version 099 to 101.", logContent); - context.assertIsSatisfied(); } @@ -606,8 +577,8 @@ public class DBMigrationEngineTest will(returnValue(logDAO)); one(daoFactory).getSqlScriptExecutor(); will(returnValue(scriptExecutor)); - one(daoFactory).getJavaMigrationStepExecutor(); - will(returnValue(javaMigrationStepExecutor)); + one(daoFactory).getMigrationStepExecutor(); + will(returnValue(migrationStepExecutor)); one(logDAO).canConnectToDatabase(); will(returnValue(true)); @@ -621,30 +592,26 @@ public class DBMigrationEngineTest one(scriptProvider).tryGetMigrationScript(fromVersion, "100"); final Script script = new Script("m-099-100", "code 099 100", toVersion); will(returnValue(script)); - one(javaMigrationStepExecutor).tryPerformPreMigration(script); - will(returnValue(Status.createError("Bad system user code."))); + + one(migrationStepExecutor).init(script); + one(migrationStepExecutor).performPreMigration(); + will(throwException(new EmptyResultDataAccessException(1))); } }); final DBMigrationEngine migrationEngine = new DBMigrationEngine(daoFactory, scriptProvider, false); - boolean exceptionThrown = false; try { migrationEngine.migrateTo(toVersion); - } catch (final EnvironmentFailureException e) + fail(); + } catch (final EmptyResultDataAccessException e) { - exceptionThrown = true; - assertEquals( - "Java pre-migration finnished with an error status ('Bad system user code.')", - e.getMessage()); + // Nothing to do here. } - assertTrue(exceptionThrown); String logContent = logRecorder.getLogContent(); logContent = logContent.replaceAll("\\d+ msec", "0 msec"); assertEquals( - "INFO OPERATION.DBMigrationEngine - Trying to migrate database 'my 1. database' from version 099 to 101." - + OSUtilities.LINE_SEPARATOR - + "ERROR OPERATION.DBMigrationEngine - Java pre-migration finnished with an error status ('Bad system user code.')", + "INFO OPERATION.DBMigrationEngine - Trying to migrate database 'my 1. database' from version 099 to 101.", logContent); context.assertIsSatisfied(); @@ -664,8 +631,8 @@ public class DBMigrationEngineTest will(returnValue(logDAO)); one(daoFactory).getSqlScriptExecutor(); will(returnValue(scriptExecutor)); - one(daoFactory).getJavaMigrationStepExecutor(); - will(returnValue(javaMigrationStepExecutor)); + one(daoFactory).getMigrationStepExecutor(); + will(returnValue(migrationStepExecutor)); one(logDAO).canConnectToDatabase(); will(returnValue(true)); @@ -697,8 +664,7 @@ public class DBMigrationEngineTest } assertEquals("INFO OPERATION.DBMigrationEngine - " + "Trying to migrate database 'my 1. database' from version 099 to 101." - + OSUtilities.LINE_SEPARATOR - + "ERROR OPERATION.DBMigrationEngine - " + + OSUtilities.LINE_SEPARATOR + "ERROR OPERATION.DBMigrationEngine - " + errorMessage, logRecorder.getLogContent()); context.assertIsSatisfied(); @@ -718,8 +684,8 @@ public class DBMigrationEngineTest will(returnValue(logDAO)); one(daoFactory).getSqlScriptExecutor(); will(returnValue(scriptExecutor)); - one(daoFactory).getJavaMigrationStepExecutor(); - will(returnValue(javaMigrationStepExecutor)); + one(daoFactory).getMigrationStepExecutor(); + will(returnValue(migrationStepExecutor)); one(logDAO).canConnectToDatabase(); will(returnValue(true)); @@ -745,8 +711,8 @@ public class DBMigrationEngineTest { assertEquals(errorMessage, e.getMessage()); } - assertEquals("ERROR OPERATION.DBMigrationEngine - " - + errorMessage, logRecorder.getLogContent()); + assertEquals("ERROR OPERATION.DBMigrationEngine - " + errorMessage, logRecorder + .getLogContent()); context.assertIsSatisfied(); } @@ -763,8 +729,8 @@ public class DBMigrationEngineTest will(returnValue(logDAO)); one(daoFactory).getSqlScriptExecutor(); will(returnValue(scriptExecutor)); - one(daoFactory).getJavaMigrationStepExecutor(); - will(returnValue(javaMigrationStepExecutor)); + one(daoFactory).getMigrationStepExecutor(); + will(returnValue(migrationStepExecutor)); one(adminDAO).dropDatabase(); one(logDAO).canConnectToDatabase(); @@ -784,11 +750,9 @@ public class DBMigrationEngineTest { assertEquals(message, e.getMessage()); } - assertEquals( - "INFO OPERATION.DBMigrationEngine - Dropping database." - + OSUtilities.LINE_SEPARATOR - + "ERROR OPERATION.DBMigrationEngine - " - + message, logRecorder.getLogContent()); + assertEquals("INFO OPERATION.DBMigrationEngine - Dropping database." + + OSUtilities.LINE_SEPARATOR + "ERROR OPERATION.DBMigrationEngine - " + message, + logRecorder.getLogContent()); context.assertIsSatisfied(); } @@ -810,8 +774,8 @@ public class DBMigrationEngineTest will(returnValue(logDAO)); one(daoFactory).getSqlScriptExecutor(); will(returnValue(scriptExecutor)); - one(daoFactory).getJavaMigrationStepExecutor(); - will(returnValue(javaMigrationStepExecutor)); + one(daoFactory).getMigrationStepExecutor(); + will(returnValue(migrationStepExecutor)); one(adminDAO).dropDatabase(); one(logDAO).canConnectToDatabase(); @@ -834,11 +798,9 @@ public class DBMigrationEngineTest { assertEquals(message, e.getMessage()); } - assertEquals( - "INFO OPERATION.DBMigrationEngine - Dropping database." - + OSUtilities.LINE_SEPARATOR - + "ERROR OPERATION.DBMigrationEngine - " - + message, logRecorder.getLogContent()); + assertEquals("INFO OPERATION.DBMigrationEngine - Dropping database." + + OSUtilities.LINE_SEPARATOR + "ERROR OPERATION.DBMigrationEngine - " + message, + logRecorder.getLogContent()); context.assertIsSatisfied(); } @@ -861,8 +823,8 @@ public class DBMigrationEngineTest will(returnValue(logDAO)); one(daoFactory).getSqlScriptExecutor(); will(returnValue(scriptExecutor)); - one(daoFactory).getJavaMigrationStepExecutor(); - will(returnValue(javaMigrationStepExecutor)); + one(daoFactory).getMigrationStepExecutor(); + will(returnValue(migrationStepExecutor)); one(adminDAO).dropDatabase(); one(logDAO).canConnectToDatabase(); @@ -885,11 +847,9 @@ public class DBMigrationEngineTest { assertEquals(message, e.getMessage()); } - assertEquals( - "INFO OPERATION.DBMigrationEngine - Dropping database." - + OSUtilities.LINE_SEPARATOR - + "ERROR OPERATION.DBMigrationEngine - " - + message, logRecorder.getLogContent()); + assertEquals("INFO OPERATION.DBMigrationEngine - Dropping database." + + OSUtilities.LINE_SEPARATOR + "ERROR OPERATION.DBMigrationEngine - " + message, + logRecorder.getLogContent()); context.assertIsSatisfied(); } @@ -909,8 +869,8 @@ public class DBMigrationEngineTest will(returnValue(logDAO)); one(daoFactory).getSqlScriptExecutor(); will(returnValue(scriptExecutor)); - one(daoFactory).getJavaMigrationStepExecutor(); - will(returnValue(javaMigrationStepExecutor)); + one(daoFactory).getMigrationStepExecutor(); + will(returnValue(migrationStepExecutor)); one(logDAO).canConnectToDatabase(); will(returnValue(true)); @@ -925,7 +885,8 @@ public class DBMigrationEngineTest final Script script = new Script("m-1-2", "code", toVersion); will(returnValue(script)); - one(javaMigrationStepExecutor).tryPerformPreMigration(script); + one(migrationStepExecutor).init(script); + one(migrationStepExecutor).performPreMigration(); one(scriptExecutor).execute(script, true, logDAO); will(throwException(exception)); } diff --git a/dbmigration/sourceTest/java/ch/systemsx/cisd/dbmigration/JavaMigrationStepExecutorTest.java b/dbmigration/sourceTest/java/ch/systemsx/cisd/dbmigration/JavaMigrationStepExecutorTest.java deleted file mode 100644 index a1f5a64dac3..00000000000 --- a/dbmigration/sourceTest/java/ch/systemsx/cisd/dbmigration/JavaMigrationStepExecutorTest.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright 2008 ETH Zuerich, CISD - * - * 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. - */ - -package ch.systemsx.cisd.dbmigration; - -import javax.sql.DataSource; - -import org.jmock.Mockery; -import org.testng.Assert; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.BeforeMethod; -import org.testng.annotations.Test; - -import ch.systemsx.cisd.common.Script; -import ch.systemsx.cisd.common.exceptions.EnvironmentFailureException; -import ch.systemsx.cisd.common.exceptions.StatusFlag; -import ch.systemsx.cisd.common.logging.LogInitializer; - -/** - * Test cases for the {@link JavaMigrationStepExecutor}. - * - * @author Izabela Adamczyk - */ -public class JavaMigrationStepExecutorTest -{ - private Mockery context; - - DataSource dataSource; - - @BeforeMethod - public void setUp() - { - context = new Mockery(); - dataSource = context.mock(DataSource.class); - } - - @BeforeClass(alwaysRun = true) - public void beforeClass() throws Exception - { - LogInitializer.init(); - } - - @Test - public void testHappyCase() - { - final JavaMigrationStepExecutor javaMigrationStepExecutor = - new JavaMigrationStepExecutor(dataSource); - final Script script = - new Script("001To002.sql", - "-- JAVA ch.systemsx.cisd.dbmigration.MigrationStepFrom001To002"); - Assert.assertTrue(javaMigrationStepExecutor.tryPerformPreMigration(script).getFlag() - .equals(StatusFlag.OK)); - Assert.assertTrue(javaMigrationStepExecutor.tryPerformPostMigration(script).getFlag() - .equals(StatusFlag.OK)); - - } - - @Test - public void testUnhappyCase() - { - final JavaMigrationStepExecutor javaMigrationStepExecutor = - new JavaMigrationStepExecutor(dataSource); - final Script script = - new Script("002To003.sql", - "-- JAVA ch.systemsx.cisd.dbmigration.MigrationStepFrom002To003"); - - Assert.assertTrue(javaMigrationStepExecutor.tryPerformPreMigration(script).getFlag() - .equals(StatusFlag.ERROR)); - Assert.assertTrue(javaMigrationStepExecutor.tryPerformPreMigration(script) - .tryGetErrorMessage().equals("bad pre")); - - Assert.assertTrue(javaMigrationStepExecutor.tryPerformPostMigration(script).getFlag() - .equals(StatusFlag.ERROR)); - Assert.assertTrue(javaMigrationStepExecutor.tryPerformPostMigration(script) - .tryGetErrorMessage().equals("bad post")); - - } - - @Test - public void testClassNotFound() - { - final JavaMigrationStepExecutor javaMigrationStepExecutor = - new JavaMigrationStepExecutor(dataSource); - final Script script = - new Script("003To004.sql", - "-- JAVA ch.systemsx.cisd.dbmigration.MigrationStepFrom003To003"); - boolean exceptionThrown = false; - try - { - javaMigrationStepExecutor.tryPerformPreMigration(script); - } catch (final EnvironmentFailureException e) - { - exceptionThrown = true; - Assert.assertEquals(e.getMessage(), - "Class 'ch.systemsx.cisd.dbmigration.MigrationStepFrom003To003' not found."); - } - Assert.assertTrue(exceptionThrown); - - } - -} diff --git a/dbmigration/sourceTest/java/ch/systemsx/cisd/dbmigration/SqlScriptProviderTest.java b/dbmigration/sourceTest/java/ch/systemsx/cisd/dbmigration/SqlScriptProviderTest.java index 357dd09a2de..f0bd9b79ce5 100644 --- a/dbmigration/sourceTest/java/ch/systemsx/cisd/dbmigration/SqlScriptProviderTest.java +++ b/dbmigration/sourceTest/java/ch/systemsx/cisd/dbmigration/SqlScriptProviderTest.java @@ -147,7 +147,7 @@ public class SqlScriptProviderTest assertNotNull(script); assertEquals(TEMP_SCHEMA_SPECIFIC_SCRIPT_FOLDER.getPath() + "/" + VERSION + "/schema-" + VERSION + ".sql", script.getName()); - assertEquals("code: schema", script.getCode().trim()); + assertEquals("code: schema", script.getContent().trim()); } // Note: we make it dependent on testGetSchemaScript(), because we delete the specific schema @@ -167,7 +167,7 @@ public class SqlScriptProviderTest assertNotNull(script); assertEquals(TEMP_SCHEMA_GENERIC_SCRIPT_FOLDER.getPath() + "/" + VERSION + "/schema-" + VERSION + ".sql", script.getName()); - assertEquals(genericSchemaScriptContent, script.getCode().trim()); + assertEquals(genericSchemaScriptContent, script.getContent().trim()); } @Test @@ -183,7 +183,7 @@ public class SqlScriptProviderTest assertNotNull(script); assertEquals(TEMP_SCHEMA_SPECIFIC_SCRIPT_FOLDER.getPath() + "/" + VERSION + "/function-" + VERSION + ".sql", script.getName()); - assertEquals("code: function", script.getCode().trim()); + assertEquals("code: function", script.getContent().trim()); } @Test @@ -198,7 +198,7 @@ public class SqlScriptProviderTest Script script = sqlScriptProvider.tryGetDataScript(VERSION); assertEquals(TEMP_SCHEMA_SPECIFIC_SCRIPT_FOLDER + "/" + VERSION + "/data-" + VERSION + ".sql", script.getName()); - assertEquals("code: data", script.getCode().trim()); + assertEquals("code: data", script.getContent().trim()); } @Test @@ -213,7 +213,7 @@ public class SqlScriptProviderTest Script script = sqlScriptProvider.tryGetMigrationScript(VERSION, VERSION2); assertEquals(TEMP_SCHEMA_SPECIFIC_SCRIPT_FOLDER.getPath() + "/" + MIGRATION + "/migration-" + VERSION + "-" + VERSION2 + ".sql", script.getName()); - assertEquals("code: migration", script.getCode().trim()); + assertEquals("code: migration", script.getContent().trim()); } @Test diff --git a/dbmigration/sourceTest/java/ch/systemsx/cisd/dbmigration/java/MigrationStepExecutorTest.java b/dbmigration/sourceTest/java/ch/systemsx/cisd/dbmigration/java/MigrationStepExecutorTest.java new file mode 100644 index 00000000000..533523aec98 --- /dev/null +++ b/dbmigration/sourceTest/java/ch/systemsx/cisd/dbmigration/java/MigrationStepExecutorTest.java @@ -0,0 +1,160 @@ +/* + * Copyright 2008 ETH Zuerich, CISD + * + * 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. + */ + +package ch.systemsx.cisd.dbmigration.java; + +import static org.testng.AssertJUnit.assertEquals; +import static org.testng.AssertJUnit.assertFalse; +import static org.testng.AssertJUnit.fail; + +import javax.sql.DataSource; + +import org.apache.log4j.Level; +import org.jmock.Mockery; +import org.springframework.dao.DataIntegrityViolationException; +import org.springframework.dao.EmptyResultDataAccessException; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import ch.systemsx.cisd.common.Script; +import ch.systemsx.cisd.common.exceptions.CheckedExceptionTunnel; +import ch.systemsx.cisd.common.logging.BufferedAppender; +import ch.systemsx.cisd.common.logging.LogInitializer; + +/** + * Test cases for the {@link MigrationStepExecutor}. + * + * @author Izabela Adamczyk + */ +public final class MigrationStepExecutorTest +{ + private Mockery context; + + private DataSource dataSource; + + private BufferedAppender logRecorder; + + @BeforeMethod + public final void setUp() + { + context = new Mockery(); + dataSource = context.mock(DataSource.class); + logRecorder = new BufferedAppender("%m%n", Level.DEBUG); + } + + @BeforeClass(alwaysRun = true) + public final void beforeClass() throws Exception + { + LogInitializer.init(); + } + + @Test + public final void testHappyCase() + { + final MigrationStepExecutor migrationStepExecutor = new MigrationStepExecutor(dataSource); + Script script = + new Script("001To002.sql", + "-- JAVA ch.systemsx.cisd.dbmigration.java.MigrationStepFrom001To002"); + migrationStepExecutor.init(script); + migrationStepExecutor.performPreMigration(); + migrationStepExecutor.performPostMigration(); + migrationStepExecutor.finish(); + assertEquals("Migration step class 'MigrationStepFrom001To002' found for " + + "migration script '001To002.sql'.", logRecorder.getLogContent()); + logRecorder.resetLogContent(); + script = + new Script("001To002.sql", "\n\n \n" + + "--JAVA ch.systemsx.cisd.dbmigration.java.MigrationStepFrom001To002"); + migrationStepExecutor.init(script); + assertEquals("Migration step class 'MigrationStepFrom001To002' found for " + + "migration script '001To002.sql'.", logRecorder.getLogContent()); + } + + @Test + public final void testFinish() + { + final MigrationStepExecutor migrationStepExecutor = new MigrationStepExecutor(dataSource); + final Script script = + new Script("001To002.sql", + "-- JAVA ch.systemsx.cisd.dbmigration.java.MigrationStepFrom001To002"); + migrationStepExecutor.init(script); + migrationStepExecutor.performPreMigration(); + migrationStepExecutor.performPostMigration(); + migrationStepExecutor.finish(); + boolean fail = true; + try + { + migrationStepExecutor.performPreMigration(); + } catch (final AssertionError ex) + { + fail = false; + } + assertFalse(fail); + } + + @Test + public final void testUnhappyCase() + { + final MigrationStepExecutor migrationStepExecutor = new MigrationStepExecutor(dataSource); + Script script = + new Script("002To003.sql", "\n-- This is a comment\n" + + "-- JAVA ch.systemsx.cisd.dbmigration.java.MigrationStepFrom002To003"); + migrationStepExecutor.init(script); + assertEquals("No migration step class found for migration script '002To003.sql'.", + logRecorder.getLogContent()); + logRecorder.resetLogContent(); + script = + new Script("002To003.sql", + "-- JAVA ch.systemsx.cisd.dbmigration.java.MigrationStepFrom002To003"); + migrationStepExecutor.init(script); + assertEquals("Migration step class 'MigrationStepFrom002To003' found for " + + "migration script '002To003.sql'.", logRecorder.getLogContent()); + try + { + migrationStepExecutor.performPreMigration(); + fail(); + } catch (final DataIntegrityViolationException ex) + { + // Nothing to do here. + } + try + { + migrationStepExecutor.performPostMigration(); + fail(); + } catch (final EmptyResultDataAccessException ex) + { + // Nothing to do here. + } + } + + @Test + public final void testClassNotFound() + { + final MigrationStepExecutor migrationStepExecutor = new MigrationStepExecutor(dataSource); + final Script script = + new Script("003To004.sql", + "-- JAVA ch.systemsx.cisd.dbmigration.java.MigrationStepFrom003To003"); + try + { + migrationStepExecutor.init(script); + fail(); + } catch (final CheckedExceptionTunnel e) + { + // Nothing to do here. + } + } +} diff --git a/dbmigration/sourceTest/java/ch/systemsx/cisd/dbmigration/MigrationStepFrom001To002.java b/dbmigration/sourceTest/java/ch/systemsx/cisd/dbmigration/java/MigrationStepFrom001To002.java similarity index 66% rename from dbmigration/sourceTest/java/ch/systemsx/cisd/dbmigration/MigrationStepFrom001To002.java rename to dbmigration/sourceTest/java/ch/systemsx/cisd/dbmigration/java/MigrationStepFrom001To002.java index dadcc9f8f41..f82fa54a83c 100644 --- a/dbmigration/sourceTest/java/ch/systemsx/cisd/dbmigration/MigrationStepFrom001To002.java +++ b/dbmigration/sourceTest/java/ch/systemsx/cisd/dbmigration/java/MigrationStepFrom001To002.java @@ -14,32 +14,31 @@ * limitations under the License. */ -package ch.systemsx.cisd.dbmigration; +package ch.systemsx.cisd.dbmigration.java; +import org.springframework.dao.DataAccessException; import org.springframework.jdbc.core.simple.SimpleJdbcTemplate; -import ch.systemsx.cisd.common.exceptions.Status; - /** * A <code>IMigrationStep</code> implementation for test. * * @author Izabela Adamczyk */ -public class MigrationStepFrom001To002 implements IMigrationStep +public final class MigrationStepFrom001To002 implements IMigrationStep { // // IMigrationStep // - public final Status performPostMigration(final SimpleJdbcTemplate simpleJdbcTemplate) + public final void performPostMigration(final SimpleJdbcTemplate simpleJdbcTemplate) + throws DataAccessException { - return Status.OK; } - public final Status performPreMigration(final SimpleJdbcTemplate simpleJdbcTemplate) + public final void performPreMigration(final SimpleJdbcTemplate simpleJdbcTemplate) + throws DataAccessException { - return Status.OK; } } diff --git a/dbmigration/sourceTest/java/ch/systemsx/cisd/dbmigration/MigrationStepFrom002To003.java b/dbmigration/sourceTest/java/ch/systemsx/cisd/dbmigration/java/MigrationStepFrom002To003.java similarity index 53% rename from dbmigration/sourceTest/java/ch/systemsx/cisd/dbmigration/MigrationStepFrom002To003.java rename to dbmigration/sourceTest/java/ch/systemsx/cisd/dbmigration/java/MigrationStepFrom002To003.java index 5a182419a6c..27cfe28b346 100644 --- a/dbmigration/sourceTest/java/ch/systemsx/cisd/dbmigration/MigrationStepFrom002To003.java +++ b/dbmigration/sourceTest/java/ch/systemsx/cisd/dbmigration/java/MigrationStepFrom002To003.java @@ -14,32 +14,36 @@ * limitations under the License. */ -package ch.systemsx.cisd.dbmigration; +package ch.systemsx.cisd.dbmigration.java; +import org.apache.commons.lang.StringUtils; +import org.springframework.dao.DataAccessException; +import org.springframework.dao.DataIntegrityViolationException; +import org.springframework.dao.EmptyResultDataAccessException; import org.springframework.jdbc.core.simple.SimpleJdbcTemplate; -import ch.systemsx.cisd.common.exceptions.Status; - /** * A <code>IMigrationStep</code> implementation for test. * * @author Izabela Adamczyk */ -public class MigrationStepFrom002To003 implements IMigrationStep +public final class MigrationStepFrom002To003 implements IMigrationStep { // // IMigrationStep // - public final Status performPostMigration(final SimpleJdbcTemplate simpleJdbcTemplate) + public final void performPostMigration(final SimpleJdbcTemplate simpleJdbcTemplate) + throws DataAccessException { - return Status.createError("bad post"); + throw new EmptyResultDataAccessException(1); } - public final Status performPreMigration(final SimpleJdbcTemplate simpleJdbcTemplate) + public final void performPreMigration(final SimpleJdbcTemplate simpleJdbcTemplate) + throws DataAccessException { - return Status.createError("bad pre"); + throw new DataIntegrityViolationException(StringUtils.EMPTY); } } -- GitLab