From 668ae5ac9f25658068ed85bde17cebe6b0a28749 Mon Sep 17 00:00:00 2001 From: felmer <felmer> Date: Tue, 19 Jun 2007 13:13:01 +0000 Subject: [PATCH] LMS-34 Move SQL code to create DATABSE_VERSION_LOG into a separate script file SVN: 592 --- .../cisd/dbmigration/DBMigrationEngine.java | 21 +++- .../dbmigration/DatabaseVersionLogDAO.java | 14 +-- .../dbmigration/IDatabaseVersionLogDAO.java | 4 +- .../cisd/dbmigration/ISqlScriptProvider.java | 8 ++ .../cisd/dbmigration/SqlScriptProvider.java | 10 +- .../dbmigration/DBMigrationEngineTest.java | 103 +++++++++++++++++- .../dbmigration/SqlScriptExecutorTest.java | 15 +++ 7 files changed, 155 insertions(+), 20 deletions(-) diff --git a/dbmigration/source/java/ch/systemsx/cisd/dbmigration/DBMigrationEngine.java b/dbmigration/source/java/ch/systemsx/cisd/dbmigration/DBMigrationEngine.java index 051c0899b93..61a3b7827af 100644 --- a/dbmigration/source/java/ch/systemsx/cisd/dbmigration/DBMigrationEngine.java +++ b/dbmigration/source/java/ch/systemsx/cisd/dbmigration/DBMigrationEngine.java @@ -22,6 +22,7 @@ import ch.systemsx.cisd.common.exceptions.CheckedExceptionTunnel; import ch.systemsx.cisd.common.exceptions.EnvironmentFailureException; import ch.systemsx.cisd.common.logging.LogCategory; import ch.systemsx.cisd.common.logging.LogFactory; +import ch.systemsx.cisd.common.utilities.OSUtilities; /** * Class for creating and migrating a database. @@ -30,6 +31,9 @@ import ch.systemsx.cisd.common.logging.LogFactory; */ public class DBMigrationEngine { + //@Private + static final String CREATE_LOG_SQL = "createLog.sql"; + private static final Logger operationLog = LogFactory.getLogger(LogCategory.OPERATION, DBMigrationEngine.class); private final boolean shouldCreateFromScratch; @@ -141,7 +145,22 @@ public class DBMigrationEngine private void createEmptyDatabase(String version) { adminDAO.createDatabase(); - logDAO.createTable(); + Script createScript = scriptProvider.getScript(CREATE_LOG_SQL); + if (createScript == null) + { + String message = "Missing script " + CREATE_LOG_SQL; + operationLog.error(message); + throw new EnvironmentFailureException(message); + } + try + { + logDAO.createTable(createScript); + } catch (RuntimeException e) + { + operationLog.error("Script '" + createScript.getName() + "' failed:" + OSUtilities.LINE_SEPARATOR + + createScript.getCode(), e); + throw e; + } Script script = scriptProvider.getSchemaScript(version); if (script == null) diff --git a/dbmigration/source/java/ch/systemsx/cisd/dbmigration/DatabaseVersionLogDAO.java b/dbmigration/source/java/ch/systemsx/cisd/dbmigration/DatabaseVersionLogDAO.java index 421800232ba..39faa93fe3c 100644 --- a/dbmigration/source/java/ch/systemsx/cisd/dbmigration/DatabaseVersionLogDAO.java +++ b/dbmigration/source/java/ch/systemsx/cisd/dbmigration/DatabaseVersionLogDAO.java @@ -67,16 +67,6 @@ class DatabaseVersionLogDAO extends SimpleJdbcDaoSupport implements IDatabaseVer private static final String DB_VERSION_LOG = "database_version_logs"; - private static final String CREATE_DB_VERSION_TABLE = - "create table " + DB_VERSION_LOG - + " (" + DB_VERSION + " varchar(4) not null" - + " ," + MODULE_NAME + " varchar(250)" - + " ," + RUN_STATUS + " varchar(10)" - + " ," + RUN_STATUS_TIMESTAMP + " timestamp" - + " ," + MODULE_CODE + " bytea" - + " ," + RUN_EXCEPTION + " bytea" - + ")"; - private static final class LogEntryRowMapper implements ParameterizedRowMapper<LogEntry> { private final LobHandler lobHandler; @@ -145,10 +135,10 @@ class DatabaseVersionLogDAO extends SimpleJdbcDaoSupport implements IDatabaseVer } } - public void createTable() + public void createTable(Script script) { JdbcTemplate template = getJdbcTemplate(); - template.execute(CREATE_DB_VERSION_TABLE); + template.execute(script.getCode()); } public LogEntry getLastEntry() diff --git a/dbmigration/source/java/ch/systemsx/cisd/dbmigration/IDatabaseVersionLogDAO.java b/dbmigration/source/java/ch/systemsx/cisd/dbmigration/IDatabaseVersionLogDAO.java index 7b97f40a512..4cbf496e47b 100644 --- a/dbmigration/source/java/ch/systemsx/cisd/dbmigration/IDatabaseVersionLogDAO.java +++ b/dbmigration/source/java/ch/systemsx/cisd/dbmigration/IDatabaseVersionLogDAO.java @@ -30,9 +30,9 @@ public interface IDatabaseVersionLogDAO public boolean canConnectToDatabase(); /** - * Creates the table DATABASE_VERSION_LOG. + * Creates the table DATABASE_VERSION_LOG by using the specified script. */ - public void createTable(); + public void createTable(Script script); /** * Returns the last log entry found. diff --git a/dbmigration/source/java/ch/systemsx/cisd/dbmigration/ISqlScriptProvider.java b/dbmigration/source/java/ch/systemsx/cisd/dbmigration/ISqlScriptProvider.java index a32de7ca80f..1442bef42c3 100644 --- a/dbmigration/source/java/ch/systemsx/cisd/dbmigration/ISqlScriptProvider.java +++ b/dbmigration/source/java/ch/systemsx/cisd/dbmigration/ISqlScriptProvider.java @@ -47,4 +47,12 @@ public interface ISqlScriptProvider * @return <code>null</code> if there isn't such a migration script. */ public Script getMigrationScript(String fromVersion, String toVersion); + + /** + * Returns the specified script. + * + * @param scriptName The name of the script file. File extension has to be included. + * @return <code>null</code> if there isn't such a script. + */ + public Script getScript(String scriptName); } diff --git a/dbmigration/source/java/ch/systemsx/cisd/dbmigration/SqlScriptProvider.java b/dbmigration/source/java/ch/systemsx/cisd/dbmigration/SqlScriptProvider.java index 07d95de3371..07252b2a466 100644 --- a/dbmigration/source/java/ch/systemsx/cisd/dbmigration/SqlScriptProvider.java +++ b/dbmigration/source/java/ch/systemsx/cisd/dbmigration/SqlScriptProvider.java @@ -76,7 +76,7 @@ public class SqlScriptProvider implements ISqlScriptProvider } /** - * Returns the schmea script for the specified version. + * Returns the schema script for the specified version. * The name of the script is expected to be * <pre><schema script folder>/<version>/schema-<version>.sql</pre> */ @@ -85,6 +85,14 @@ public class SqlScriptProvider implements ISqlScriptProvider return loadScript(schemaScriptFolder + "/" + version, "schema-" + version + SQL_FILE_TYPE); } + /** + * Returns the specified script relative to the schema script folder. + */ + public Script getScript(String scriptName) + { + return loadScript(schemaScriptFolder, scriptName); + } + private Script loadScript(String folder, String scriptName) { String fullScriptName = folder + "/" + scriptName; diff --git a/dbmigration/sourceTest/java/ch/systemsx/cisd/dbmigration/DBMigrationEngineTest.java b/dbmigration/sourceTest/java/ch/systemsx/cisd/dbmigration/DBMigrationEngineTest.java index 6441fd6dd80..91fb59dca15 100644 --- a/dbmigration/sourceTest/java/ch/systemsx/cisd/dbmigration/DBMigrationEngineTest.java +++ b/dbmigration/sourceTest/java/ch/systemsx/cisd/dbmigration/DBMigrationEngineTest.java @@ -57,6 +57,14 @@ public class DBMigrationEngineTest one(scriptExecutor).execute(script.getCode()); one(logDAO).logSuccess(version, script.getName()); } + + protected void expectCreateLogDAOTable() + { + one(scriptProvider).getScript(DBMigrationEngine.CREATE_LOG_SQL); + Script script = new Script(DBMigrationEngine.CREATE_LOG_SQL, "create log"); + will(returnValue(script)); + one(logDAO).createTable(with(same(script))); + } } private Mockery context; @@ -128,7 +136,8 @@ public class DBMigrationEngineTest will(returnValue("my 1. database")); one(adminDAO).createOwner(); one(adminDAO).createDatabase(); - one(logDAO).createTable(); + + expectCreateLogDAOTable(); one(scriptProvider).getSchemaScript(version); expectSuccessfulExecution(new Script("schema", "schema code"), version); one(scriptProvider).getDataScript(version); @@ -210,7 +219,7 @@ public class DBMigrationEngineTest will(returnValue("my 1. database")); one(adminDAO).createOwner(); one(adminDAO).createDatabase(); - one(logDAO).createTable(); + expectCreateLogDAOTable(); one(scriptProvider).getSchemaScript(version); expectSuccessfulExecution(new Script("schema", "schema code"), version); one(scriptProvider).getDataScript(version); @@ -251,7 +260,7 @@ public class DBMigrationEngineTest will(returnValue("my 1. database")); one(adminDAO).createOwner(); one(adminDAO).createDatabase(); - one(logDAO).createTable(); + expectCreateLogDAOTable(); one(scriptProvider).getSchemaScript(version); expectSuccessfulExecution(new Script("schema", "schema code"), version); one(scriptProvider).getDataScript(version); @@ -291,7 +300,7 @@ public class DBMigrationEngineTest will(returnValue("my 1. database")); one(adminDAO).createOwner(); one(adminDAO).createDatabase(); - one(logDAO).createTable(); + expectCreateLogDAOTable(); one(scriptProvider).getSchemaScript(version); } }); @@ -314,6 +323,92 @@ public class DBMigrationEngineTest context.assertIsSatisfied(); } + @Test + public void testCreateFromScratchWithMissingCreateLogScript() + { + final String version = "042"; + context.checking(new MyExpectations() + { + { + one(daoFactory).getDatabaseDAO(); + will(returnValue(adminDAO)); + one(daoFactory).getDatabaseVersionLogDAO(); + will(returnValue(logDAO)); + one(daoFactory).getSqlScriptExecutor(); + will(returnValue(scriptExecutor)); + + one(logDAO).canConnectToDatabase(); + will(returnValue(false)); + one(adminDAO).getDatabaseName(); + will(returnValue("my 1. database")); + one(adminDAO).createOwner(); + one(adminDAO).createDatabase(); + one(scriptProvider).getScript(DBMigrationEngine.CREATE_LOG_SQL); + } + }); + DBMigrationEngine migrationEngine = new DBMigrationEngine(daoFactory, scriptProvider, false); + + logRecorder.reset(); + String message = "Missing script createLog.sql"; + try + { + migrationEngine.migrateTo(version); + fail("EnvironmentFailureException expected because of missing log creation script"); + } catch (EnvironmentFailureException e) + { + assertEquals(message, e.getMessage()); + } + assertEquals("INFO OPERATION.ch.systemsx.cisd.dbmigration.DBMigrationEngine - " + + "Database 'my 1. database' does not exist." + OSUtilities.LINE_SEPARATOR + + "ERROR OPERATION.ch.systemsx.cisd.dbmigration.DBMigrationEngine - " + message, getLogContent()); + + context.assertIsSatisfied(); + } + + @Test + public void testCreateFromScratchWithCreateLogScriptWhichFails() + { + final String version = "042"; + final RuntimeException exception = new RuntimeException(); + context.checking(new MyExpectations() + { + { + one(daoFactory).getDatabaseDAO(); + will(returnValue(adminDAO)); + one(daoFactory).getDatabaseVersionLogDAO(); + will(returnValue(logDAO)); + one(daoFactory).getSqlScriptExecutor(); + will(returnValue(scriptExecutor)); + + one(logDAO).canConnectToDatabase(); + will(returnValue(false)); + one(adminDAO).getDatabaseName(); + will(returnValue("my database")); + one(adminDAO).createOwner(); + one(adminDAO).createDatabase(); + expectCreateLogDAOTable(); + will(throwException(exception)); + } + }); + DBMigrationEngine migrationEngine = new DBMigrationEngine(daoFactory, scriptProvider, false); + + logRecorder.reset(); + try + { + migrationEngine.migrateTo(version); + fail("RuntimeException expected because of failing log creation script"); + } catch (RuntimeException e) + { + assertSame(exception, e); + } + assertEquals("INFO OPERATION.ch.systemsx.cisd.dbmigration.DBMigrationEngine - " + + "Database 'my database' does not exist." + OSUtilities.LINE_SEPARATOR + + "ERROR OPERATION.ch.systemsx.cisd.dbmigration.DBMigrationEngine - Script 'createLog.sql' failed:" + OSUtilities.LINE_SEPARATOR + + "create log" + OSUtilities.LINE_SEPARATOR + getStackTrace(exception), getLogContent()); + + context.assertIsSatisfied(); + } + @Test public void testCaseNoMigrationNeeded() { diff --git a/dbmigration/sourceTest/java/ch/systemsx/cisd/dbmigration/SqlScriptExecutorTest.java b/dbmigration/sourceTest/java/ch/systemsx/cisd/dbmigration/SqlScriptExecutorTest.java index c9fd88e5004..fff6cfb0cb7 100644 --- a/dbmigration/sourceTest/java/ch/systemsx/cisd/dbmigration/SqlScriptExecutorTest.java +++ b/dbmigration/sourceTest/java/ch/systemsx/cisd/dbmigration/SqlScriptExecutorTest.java @@ -49,6 +49,7 @@ public class SqlScriptExecutorTest public void setUpTestFiles() throws IOException { TEMP_SCHEMA_SCRIPT_FOLDER.mkdir(); + write(new File(TEMP_SCHEMA_SCRIPT_FOLDER, "hello.script"), "hello world!"); File schemaVersionFolder = new File(TEMP_SCHEMA_SCRIPT_FOLDER, VERSION); schemaVersionFolder.mkdir(); write(new File(schemaVersionFolder, "schema-" + VERSION + ".sql"), "code: schema"); @@ -141,4 +142,18 @@ public class SqlScriptExecutorTest assertEquals(null, sqlScriptProvider.getMigrationScript("000", "001")); } + @Test + public void testGetScript() + { + Script script = sqlScriptProvider.getScript("hello.script"); + assertEquals(TEMPORARY_SCHEMA_SCRIPT_FOLDER_NAME + "/hello.script", script.getName()); + assertEquals("hello world!", script.getCode().trim()); + } + + @Test + public void testGetNonExistingScript() + { + assertEquals(null, sqlScriptProvider.getScript("blabla.sql")); + } + } -- GitLab