diff --git a/src/main/java/com/avaje/ebean/config/DbMigrationConfig.java b/src/main/java/com/avaje/ebean/config/DbMigrationConfig.java index 95b7dd301..e71a449c9 100644 --- a/src/main/java/com/avaje/ebean/config/DbMigrationConfig.java +++ b/src/main/java/com/avaje/ebean/config/DbMigrationConfig.java @@ -18,13 +18,16 @@ public class DbMigrationConfig { */ protected DbPlatformName platform; - protected boolean useSubdirectories; - /** * Set to true if the DB migration should be generated on server start. */ protected boolean generate; + /** + * Set to true to suppress the output of the rollback script. + */ + protected boolean suppressRollback; + /** * The migration version name (typically FlywayDb compatible). *

@@ -50,9 +53,40 @@ public class DbMigrationConfig { /** * Resource path for the migration xml and sql. - * Typically you would change 'app' to be a better/more unique. */ - protected String resourcePath = "dbmigration/app"; + protected String migrationPath = "dbmigration"; + + /** + * Subdirectory the model xml files go into. + */ + protected String modelPath = "model"; + + /** + * Subdirectory the drop ddl scripts go into. + */ + protected String dropPath = "drop"; + + /** + * Subdirectory the rollback ddl scripts go into. + */ + protected String rollbackPath = "rollback"; + + /** + * Apply script suffix. + */ + protected String applySuffix = ".sql"; + + /** + * Default drop script suffix to ddl so that it isn't picked up by FlywayDb. + */ + protected String dropSuffix = ".drop.ddl"; + + /** + * Default rollback script suffix to ddl so that it isn't picked up by FlywayDb. + */ + protected String rollbackSuffix = ".rollback.ddl"; + + protected String modelSuffix = ".model.xml"; /** * Return the DB platform to generate migration DDL for. @@ -74,34 +108,132 @@ public class DbMigrationConfig { /** * Return the resource path for db migrations. */ - public String getResourcePath() { - return resourcePath; - } - - /** - * Return true if the 'rollback' and 'drop' scripts should be put into subdirectories. - */ - public boolean isUseSubdirectories() { - return useSubdirectories; - } - - /** - * Set to true if the 'rollback' and 'drop' scripts should be put into subdirectories. - */ - public void setUseSubdirectories(boolean useSubdirectories) { - this.useSubdirectories = useSubdirectories; + public String getMigrationPath() { + return migrationPath; } /** * Set the resource path for db migrations. *

- * Typically this would be something like "dbmigration/myapp" where myapp gives it a - * unique resource path in the case there are multiple EbeanServer applications in the - * single classpath. + * The default of "dbmigration" is reasonable in most cases. You may look to set this + * to be something like "dbmigration/myapp" where myapp gives it a unique resource path + * in the case there are multiple EbeanServer applications in the single classpath. *

*/ - public void setResourcePath(String resourcePath) { - this.resourcePath = resourcePath; + public void setMigrationPath(String migrationPath) { + this.migrationPath = migrationPath; + } + + /** + * Return the relative path for the model files (defaults to model). + */ + public String getModelPath() { + return modelPath; + } + + /** + * Set the relative path for the model files. + */ + public void setModelPath(String modelPath) { + this.modelPath = modelPath; + } + + /** + * Return the relative path for the drop ddl scripts (defaults to drop). + */ + public String getDropPath() { + return dropPath; + } + + /** + * Set the relative path for the drop ddl scripts (defaults to drop). + */ + public void setDropPath(String dropPath) { + this.dropPath = dropPath; + } + + /** + * Return the relative path for the rollback ddl scripts (defaults to rollback). + */ + public String getRollbackPath() { + return rollbackPath; + } + + /** + * Set the relative path for the rollback ddl scripts (defaults to rollback). + */ + public void setRollbackPath(String rollbackPath) { + this.rollbackPath = rollbackPath; + } + + /** + * Return the model suffix (defaults to model.xml) + */ + public String getModelSuffix() { + return modelSuffix; + } + + /** + * Set the model suffix. + */ + public void setModelSuffix(String modelSuffix) { + this.modelSuffix = modelSuffix; + } + + /** + * Return true if the rollback script should not be output. + */ + public boolean isSuppressRollback() { + return suppressRollback; + } + + /** + * Set to true to suppress the output of the rollback script. + */ + public void setSuppressRollback(boolean suppressRollback) { + this.suppressRollback = suppressRollback; + } + + /** + * Return the apply script suffix (defaults to sql). + */ + public String getApplySuffix() { + return applySuffix; + } + + /** + * Set the apply script suffix (defaults to sql). + */ + public void setApplySuffix(String applySuffix) { + this.applySuffix = applySuffix; + } + + /** + * Return the drop script suffix (defaults to ddl so that it isn't picked up by FlywayDb). + */ + public String getDropSuffix() { + return dropSuffix; + } + + /** + * Set the drop script suffix (defaults to ddl so that it isn't picked up by FlywayDb). + */ + public void setDropSuffix(String dropSuffix) { + this.dropSuffix = dropSuffix; + } + + /** + * Return the rollback script suffix (defaults to ddl so that it isn't picked up by FlywayDb). + */ + public String getRollbackSuffix() { + return rollbackSuffix; + } + + /** + * Set the rollback script suffix (defaults to ddl so that it isn't picked up by FlywayDb). + */ + public void setRollbackSuffix(String rollbackSuffix) { + this.rollbackSuffix = rollbackSuffix; } /** @@ -122,16 +254,40 @@ public class DbMigrationConfig { this.name = name; } + /** + * Set the model, rollback and drop paths to be empty such that all the migration files are generated + * into a single directory. + */ + public void singleDirectory() { + this.dropPath = ""; + this.rollbackPath = ""; + this.modelPath = ""; + } + /** * Load the settings from the PropertiesWrapper. */ public void loadSettings(PropertiesWrapper properties) { - resourcePath = properties.get("migration.resourcePath", resourcePath); + + migrationPath = properties.get("migration.migrationPath", migrationPath); + if (properties.getBoolean("migration.singleDirectory", false)) { + singleDirectory(); + } else { + modelPath = properties.get("migration.modelPath", modelPath); + rollbackPath = properties.get("migration.rollbackPath", rollbackPath); + dropPath = properties.get("migration.dropPath", dropPath); + } + applySuffix = properties.get("migration.applySuffix", applySuffix); + dropSuffix = properties.get("migration.dropSuffix", dropSuffix); + rollbackSuffix = properties.get("migration.rollbackSuffix", rollbackSuffix); + modelSuffix = properties.get("migration.modelSuffix", modelSuffix); + platform = properties.getEnum(DbPlatformName.class, "migration.platform", platform); + suppressRollback = properties.getBoolean("migration.suppressRollback", suppressRollback); + generate = properties.getBoolean("migration.generate", generate); version = properties.get("migration.version", version); name = properties.get("migration.name", name); - useSubdirectories = properties.getBoolean("migration.useSubdirectories", useSubdirectories); } /** diff --git a/src/main/java/com/avaje/ebean/dbmigration/DbMigration.java b/src/main/java/com/avaje/ebean/dbmigration/DbMigration.java index 257cb00b2..52d89514a 100644 --- a/src/main/java/com/avaje/ebean/dbmigration/DbMigration.java +++ b/src/main/java/com/avaje/ebean/dbmigration/DbMigration.java @@ -204,9 +204,10 @@ public class DbMigration { try { - File migrationDirectory = getMigrationDirectory(); + File migrationDir = getMigrationDirectory(); + File modelDir = getModelDirectory(migrationDir); - MigrationModel migrationModel = new MigrationModel(migrationDirectory); + MigrationModel migrationModel = new MigrationModel(modelDir, migrationConfig.getModelSuffix()); ModelContainer migrated = migrationModel.read(); CurrentModel currentModel = new CurrentModel(server, constraintNaming); @@ -226,7 +227,7 @@ public class DbMigration { String fullVersion = getFullVersion(migrationModel); logger.info("generating migration:{}", fullVersion); - if (!writeMigrationXml(dbMigration, migrationDirectory, fullVersion)) { + if (!writeMigrationXml(dbMigration, modelDir, fullVersion)) { logger.warn("migration already exists, not generating DDL"); } else { @@ -235,9 +236,9 @@ public class DbMigration { // history ddl generation (triggers, history tables etc) DdlWrite write = new DdlWrite(new MConfiguration(), currentModel.read()); PlatformDdlWriter writer = createDdlWriter(databasePlatform, ""); - writer.processMigration(dbMigration, write, migrationDirectory, fullVersion); + writer.processMigration(dbMigration, write, migrationDir , fullVersion); } - writeExtraPlatformDdl(fullVersion, currentModel, dbMigration, migrationDirectory); + writeExtraPlatformDdl(fullVersion, currentModel, dbMigration, migrationDir); } } finally { @@ -290,7 +291,7 @@ public class DbMigration { } private PlatformDdlWriter createDdlWriter(DatabasePlatform platform, String prefix) { - return new PlatformDdlWriter(platform, serverConfig, prefix, migrationConfig.isUseSubdirectories()); + return new PlatformDdlWriter(platform, serverConfig, prefix, migrationConfig); } /** @@ -298,7 +299,8 @@ public class DbMigration { */ protected boolean writeMigrationXml(Migration dbMigration, File resourcePath, String fullVersion) { - File file = new File(resourcePath, fullVersion+".xml"); + String modelFile = fullVersion + migrationConfig.getModelSuffix(); + File file = new File(resourcePath, modelFile); if (file.exists()) { return false; } @@ -329,10 +331,9 @@ public class DbMigration { // path to src/main/resources in typical maven project File resourceRootDir = new File(pathToResources); + String resourcePath = migrationConfig.getMigrationPath(); - String resourcePath = migrationConfig.getResourcePath(); - - // expect to be a path to something like - src/main/resources/dbmigration/myapp + // expect to be a path to something like - src/main/resources/dbmigration/model File path = new File(resourceRootDir, resourcePath); if (!path.exists()) { if (!path.mkdirs()) { @@ -342,6 +343,21 @@ public class DbMigration { return path; } + /** + * Return the model directory (relative to the migration directory). + */ + protected File getModelDirectory(File migrationDirectory) { + String modelPath = migrationConfig.getModelPath(); + if (modelPath == null || modelPath.isEmpty()) { + return migrationDirectory; + } + File modelDir = new File(migrationDirectory, migrationConfig.getModelPath()); + if (!modelDir.exists() && !modelDir.mkdirs()) { + logger.debug("Unable to ensure migration model directory exists at {}", modelDir.getAbsolutePath()); + } + return modelDir; + } + /** * Return the DatabasePlatform given the platform key. */ diff --git a/src/main/java/com/avaje/ebean/dbmigration/model/MigrationModel.java b/src/main/java/com/avaje/ebean/dbmigration/model/MigrationModel.java index aacdde839..79b73fb73 100644 --- a/src/main/java/com/avaje/ebean/dbmigration/model/MigrationModel.java +++ b/src/main/java/com/avaje/ebean/dbmigration/model/MigrationModel.java @@ -18,12 +18,15 @@ public class MigrationModel { private final ModelContainer model = new ModelContainer(); - private final File migrationDirectory; + private final File modelDirectory; + + private final String modelSuffix; private MigrationVersion lastVersion; - public MigrationModel(File migrationDirectory) { - this.migrationDirectory = migrationDirectory; + public MigrationModel(File modelDirectory, String modelSuffix) { + this.modelDirectory = modelDirectory; + this.modelSuffix = modelSuffix; } /** @@ -39,10 +42,10 @@ public class MigrationModel { private void readMigrations() { // find all the migration xml files - File[] xmlFiles = migrationDirectory.listFiles(new FileFilter() { + File[] xmlFiles = modelDirectory.listFiles(new FileFilter() { @Override public boolean accept(File pathname) { - return pathname.getName().toLowerCase().endsWith(".xml"); + return pathname.getName().toLowerCase().endsWith(modelSuffix); } }); diff --git a/src/main/java/com/avaje/ebean/dbmigration/model/PlatformDdlWriter.java b/src/main/java/com/avaje/ebean/dbmigration/model/PlatformDdlWriter.java index 4f8cb0ffd..a6d4011ac 100644 --- a/src/main/java/com/avaje/ebean/dbmigration/model/PlatformDdlWriter.java +++ b/src/main/java/com/avaje/ebean/dbmigration/model/PlatformDdlWriter.java @@ -1,5 +1,6 @@ package com.avaje.ebean.dbmigration.model; +import com.avaje.ebean.config.DbMigrationConfig; import com.avaje.ebean.config.ServerConfig; import com.avaje.ebean.config.dbplatform.DatabasePlatform; import com.avaje.ebean.dbmigration.ddlgeneration.DdlHandler; @@ -24,13 +25,13 @@ public class PlatformDdlWriter { private final String platformPrefix; - private final boolean useSubdirectories; + private final DbMigrationConfig config; - public PlatformDdlWriter(DatabasePlatform platform, ServerConfig serverConfig, String platformPrefix, boolean useSubdirectories) { + public PlatformDdlWriter(DatabasePlatform platform, ServerConfig serverConfig, String platformPrefix, DbMigrationConfig config) { this.platform = platform; this.serverConfig = serverConfig; this.platformPrefix = platformPrefix; - this.useSubdirectories = useSubdirectories; + this.config = config; } /** @@ -57,7 +58,7 @@ public class PlatformDdlWriter { protected void writePlatformDdl(DdlWrite write, File resourcePath, String fullVersion) throws IOException { if (!write.isApplyEmpty()) { - FileWriter applyWriter = createWriter(resourcePath, fullVersion, ""); + FileWriter applyWriter = createWriter(resourcePath, fullVersion, "", config.getApplySuffix()); try { writeApplyDdl(applyWriter, write); applyWriter.flush(); @@ -65,8 +66,8 @@ public class PlatformDdlWriter { applyWriter.close(); } - if (!write.isApplyRollbackEmpty()) { - FileWriter applyRollbackWriter = createWriter(resourcePath, fullVersion, "rollback"); + if (!config.isSuppressRollback() && !write.isApplyRollbackEmpty()) { + FileWriter applyRollbackWriter = createWriter(resourcePath, fullVersion, config.getRollbackPath(), config.getRollbackSuffix()); try { writeApplyRollbackDdl(applyRollbackWriter, write); applyRollbackWriter.flush(); @@ -77,7 +78,7 @@ public class PlatformDdlWriter { } if (!write.isDropEmpty()) { - FileWriter dropWriter = createWriter(resourcePath, fullVersion, "drop"); + FileWriter dropWriter = createWriter(resourcePath, fullVersion, config.getDropPath(), config.getDropSuffix()); try { writeDropDdl(dropWriter, write); dropWriter.flush(); @@ -87,25 +88,21 @@ public class PlatformDdlWriter { } } - protected FileWriter createWriter(File path, String fullVersion, String suffix) throws IOException { + protected FileWriter createWriter(File path, String fullVersion, String subPath, String suffix) throws IOException { String fileName = fullVersion; if (!platformPrefix.isEmpty()) { fileName += "-"+platformPrefix; } - if (!suffix.isEmpty()) { - fileName += "-"+suffix; - path = subPath(path, suffix); + if (subPath != null && !subPath.isEmpty()) { + path = subPath(path, subPath); } - fileName += ".sql"; + fileName += suffix; File applyFile = new File(path, fileName); return new FileWriter(applyFile); } protected File subPath(File path, String suffix) { - if (!useSubdirectories) { - return path; - } File subPath = new File(path, suffix); if (!subPath.exists()) { subPath.mkdirs(); diff --git a/src/test/java/com/avaje/ebean/config/DbMigrationConfigTest.java b/src/test/java/com/avaje/ebean/config/DbMigrationConfigTest.java index 9b2ccd843..2d9fd7523 100644 --- a/src/test/java/com/avaje/ebean/config/DbMigrationConfigTest.java +++ b/src/test/java/com/avaje/ebean/config/DbMigrationConfigTest.java @@ -17,6 +17,6 @@ public class DbMigrationConfigTest { DbMigrationConfig migrationConfig = config.getMigrationConfig(); - assertThat(migrationConfig.getResourcePath()).isEqualTo("dbmigration/myapp"); + assertThat(migrationConfig.getMigrationPath()).isEqualTo("dbmigration/myapp"); } } \ No newline at end of file