diff --git a/ebean-bom/pom.xml b/ebean-bom/pom.xml index 2c3dfe8ba..3de0074b1 100644 --- a/ebean-bom/pom.xml +++ b/ebean-bom/pom.xml @@ -92,6 +92,12 @@ 12.14.1-FOC1-SNAPSHOT + + io.ebean + ebean-dbmigration-runner + 12.14.1-FOC1-SNAPSHOT + + io.ebean ebean-ddl-generator diff --git a/ebean-core/pom.xml b/ebean-core/pom.xml index 9fdef1a77..67a83e54d 100644 --- a/ebean-core/pom.xml +++ b/ebean-core/pom.xml @@ -32,12 +32,6 @@ 6.2 - - io.ebean - ebean-migration-auto - 1.1 - - io.ebean ebean-api diff --git a/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultServer.java b/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultServer.java index 5981ef9bf..84cf05a34 100644 --- a/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultServer.java +++ b/ebean-core/src/main/java/io/ebeaninternal/server/core/DefaultServer.java @@ -65,7 +65,6 @@ import io.ebean.meta.MetaQueryPlan; import io.ebean.meta.MetricVisitor; import io.ebean.meta.QueryPlanInit; import io.ebean.meta.QueryPlanRequest; -import io.ebean.migration.auto.AutoMigrationRunner; import io.ebean.plugin.BeanType; import io.ebean.plugin.Plugin; import io.ebean.plugin.Property; @@ -367,21 +366,6 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer { @Override public void start() { - - if (config.isRunMigration()) { - final AutoMigrationRunner migrationRunner = ServiceUtil.service(AutoMigrationRunner.class); - if (migrationRunner == null) { - throw new IllegalStateException("No AutoMigrationRunner found. Probably ebean-migration is not in the classpath?"); - } - final String dbSchema = config.getDbSchema(); - if (dbSchema != null) { - migrationRunner.setDefaultDbSchema(dbSchema); - } - migrationRunner.setName(config.getName()); - migrationRunner.setPlatform(config.getDatabasePlatform().getPlatform().base().name().toLowerCase()); - migrationRunner.loadProperties(config.getProperties()); - migrationRunner.run(config.getDataSource()); - } for (Plugin plugin : serverPlugins) { plugin.start(); } diff --git a/ebean-dbmigration-runner/pom.xml b/ebean-dbmigration-runner/pom.xml new file mode 100644 index 000000000..a57aa2958 --- /dev/null +++ b/ebean-dbmigration-runner/pom.xml @@ -0,0 +1,122 @@ + + + 4.0.0 + + ebean-parent + io.ebean + 12.14.1-FOC1-SNAPSHOT + + + ebean dbmigration runner + DB Migration runner plugin + ebean-dbmigration-runner + + + + + + + + io.ebean + ebean-migration-auto + 1.1 + + + + io.ebean + ebean-core + 12.14.1-FOC1-SNAPSHOT + provided + + + + io.ebean + ebean-migration + 12.12.1 + + + + + + + + + + io.ebean + ebean-maven-plugin + ${ebean-maven-plugin.version} + + + test + process-test-classes + + debug=0 + + + testEnhance + + + + + + io.repaint.maven + tiles-maven-plugin + 2.24 + true + + + io.avaje.tile:moditech-module:1.0 + + + + + + diff --git a/ebean-dbmigration-runner/src/main/java/io/ebeaninternal/dbmigration/run/DbRunMigrationPlugin.java b/ebean-dbmigration-runner/src/main/java/io/ebeaninternal/dbmigration/run/DbRunMigrationPlugin.java new file mode 100644 index 000000000..37ab3987f --- /dev/null +++ b/ebean-dbmigration-runner/src/main/java/io/ebeaninternal/dbmigration/run/DbRunMigrationPlugin.java @@ -0,0 +1,48 @@ +package io.ebeaninternal.dbmigration.run; + +import io.ebean.config.DatabaseConfig; +import io.ebean.migration.auto.AutoMigrationRunner; +import io.ebean.plugin.Plugin; +import io.ebean.plugin.SpiServer; +import io.ebeaninternal.server.core.ServiceUtil; + +public class DbRunMigrationPlugin implements Plugin { + + private SpiServer server; + private AutoMigrationRunner migrationRunner; + + @Override + public void configure(SpiServer server) { + this.server = server; + DatabaseConfig config = server.config(); + if (config.isRunMigration()) { + migrationRunner = ServiceUtil.service(AutoMigrationRunner.class); + if (migrationRunner == null) { + throw new IllegalStateException( + "No AutoMigrationRunner found. Probably ebean-migration is not in the classpath?"); + } + final String dbSchema = config.getDbSchema(); + if (dbSchema != null) { + migrationRunner.setDefaultDbSchema(dbSchema); + } + migrationRunner.setName(config.getName()); + migrationRunner.setPlatform(config.getDatabasePlatform().getPlatform().base().name().toLowerCase()); + migrationRunner.loadProperties(config.getProperties()); + } + } + + @Override + public void online(boolean online) { + + } + + @Override + public void shutdown() { + + } + + @Override + public void start() { + migrationRunner.run(server.dataSource()); + } +} diff --git a/ebean-dbmigration-runner/src/main/resources/META-INF/services/io.ebean.plugin.Plugin b/ebean-dbmigration-runner/src/main/resources/META-INF/services/io.ebean.plugin.Plugin new file mode 100644 index 000000000..873033a79 --- /dev/null +++ b/ebean-dbmigration-runner/src/main/resources/META-INF/services/io.ebean.plugin.Plugin @@ -0,0 +1,2 @@ + +io.ebeaninternal.dbmigration.run.DbRunMigrationPlugin diff --git a/ebean-ddl-generator/pom.xml b/ebean-ddl-generator/pom.xml index d1c9fc188..bf3fa7318 100644 --- a/ebean-ddl-generator/pom.xml +++ b/ebean-ddl-generator/pom.xml @@ -55,6 +55,13 @@ test + + io.ebean + ebean-dbmigration-runner + 12.14.1-FOC1-SNAPSHOT + test + + io.ebean ebean-datasource diff --git a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/DefaultDbMigration.java b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/DefaultDbMigration.java index 2b8345a16..52c1897f6 100644 --- a/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/DefaultDbMigration.java +++ b/ebean-ddl-generator/src/main/java/io/ebeaninternal/dbmigration/DefaultDbMigration.java @@ -132,7 +132,7 @@ public class DefaultDbMigration implements DbMigration { private int lockTimeoutSeconds; protected boolean includeBuiltInPartitioning = true; protected boolean includeIndex; - protected boolean generate = true; + protected boolean generate = false; protected boolean generateInit = false; private boolean keepLastInit = true; diff --git a/ebean-ddl-generator/src/test/java/io/ebeaninternal/dbmigration/DbMigrationDropHistoryTest.java b/ebean-ddl-generator/src/test/java/io/ebeaninternal/dbmigration/DbMigrationDropHistoryTest.java index 56752e7f2..6133928b4 100644 --- a/ebean-ddl-generator/src/test/java/io/ebeaninternal/dbmigration/DbMigrationDropHistoryTest.java +++ b/ebean-ddl-generator/src/test/java/io/ebeaninternal/dbmigration/DbMigrationDropHistoryTest.java @@ -75,13 +75,11 @@ public class DbMigrationDropHistoryTest { List pendingDrops = migration.getPendingDrops(); assertThat(pendingDrops).contains("1.1"); - //System.setProperty("ddl.migration.pendingDropsFor", "1.1"); migration.setGeneratePendingDrop("1.1"); assertThat(migration.generateMigration()).isEqualTo("1.2__dropsFor_1.1"); assertThatThrownBy(()->migration.generateMigration()) .isInstanceOf(IllegalArgumentException.class) .hasMessageContaining("No 'pendingDrops'"); // subsequent call - System.clearProperty("ddl.migration.pendingDropsFor"); server.shutdown(); logger.info("end"); diff --git a/ebean-ddl-generator/src/test/java/io/ebeaninternal/dbmigration/DbMigrationGenerateTest.java b/ebean-ddl-generator/src/test/java/io/ebeaninternal/dbmigration/DbMigrationGenerateTest.java index d207cc987..7ed69b3a2 100644 --- a/ebean-ddl-generator/src/test/java/io/ebeaninternal/dbmigration/DbMigrationGenerateTest.java +++ b/ebean-ddl-generator/src/test/java/io/ebeaninternal/dbmigration/DbMigrationGenerateTest.java @@ -1,8 +1,6 @@ package io.ebeaninternal.dbmigration; -import io.ebean.Database; import io.ebean.DatabaseFactory; -import io.ebean.annotation.Platform; import io.ebean.config.DatabaseConfig; import org.junit.jupiter.api.Test; import org.slf4j.Logger; @@ -16,7 +14,6 @@ import java.nio.file.Paths; import java.util.Arrays; import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; /** @@ -45,14 +42,7 @@ public class DbMigrationGenerateTest { config.loadFromProperties(); config.setRegister(false); config.setDefaultServer(false); - config.getProperties().put("ebean.hana.generateUniqueDdl", "true"); // need to generate unique statements to prevent them from being filtered out as duplicates by the DdlRunner - - config.getProperties().put("ebean.migrationtest.migration.pathToResources", pathToResources); - config.getProperties().put("ebean.migrationtest.migration.includeIndex", "true"); - config.getProperties().put("ebean.migrationtest.migration.generateInit", "true"); - config.getProperties().put("ebean.migrationtest.migration.generatePendingDrop", "auto"); - config.getProperties().put("ebean.migrationtest.migration.platforms", "db2,h2,hsqldb,mysql,mysql55=mysql55,postgres,oracle,sqlite,sqlserver17=sqlserver17,hana"); config.setPackages(Arrays.asList("misc.migration.v1_0")); // First, we clean up the output-directory diff --git a/ebean-ddl-generator/src/test/java/io/ebeaninternal/dbmigration/MysqlGenerateMigrationTest.java b/ebean-ddl-generator/src/test/java/io/ebeaninternal/dbmigration/MysqlGenerateMigrationTest.java index b75793634..50b52bda1 100644 --- a/ebean-ddl-generator/src/test/java/io/ebeaninternal/dbmigration/MysqlGenerateMigrationTest.java +++ b/ebean-ddl-generator/src/test/java/io/ebeaninternal/dbmigration/MysqlGenerateMigrationTest.java @@ -1,19 +1,14 @@ package io.ebeaninternal.dbmigration; -import io.ebean.Database; import io.ebean.DatabaseFactory; -import io.ebean.annotation.Platform; import io.ebean.config.DatabaseConfig; -import io.ebean.config.PlatformConfig; -import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; import java.io.File; -import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; +import java.nio.file.Paths; import java.util.Arrays; import static org.assertj.core.api.Assertions.assertThat; @@ -25,62 +20,102 @@ import static org.assertj.core.api.Assertions.assertThat; */ public class MysqlGenerateMigrationTest { - @AfterEach - public void resetPendingDropsProperty() { - System.clearProperty("ddl.migration.pendingDropsFor"); - } - @Test public void testMysqlStoredProcedures() throws Exception { - DefaultDbMigration migration = new DefaultDbMigration(); - migration.setIncludeIndex(true); - // We use src/test/resources as output directory (so we see in GIT if files will change) - migration.setPathToResources("src/test/resources"); - - migration.addPlatform(Platform.MYSQL, "mysql"); - - final PlatformConfig platformConfig = new PlatformConfig(); - platformConfig.setUseMigrationStoredProcedures(true); - + + + String pathToResources = "src/test/resources"; + DatabaseConfig config = new DatabaseConfig(); config.setName("migrationtest"); config.loadFromProperties(); - config.setPlatformConfig(platformConfig); config.setRegister(false); config.setDefaultServer(false); - config.getProperties().put("ebean.migration.migrationPath", "db/migration/mysql"); - - config.setPackages(Arrays.asList("misc.migration.mysql_v1_0")); - Database server = DatabaseFactory.create(config); - migration.setServer(server); - migration.setMigrationPath("mysql/procedures"); + config.getProperties().put("ebean.migrationtest.migration.pathToResources", pathToResources); + config.getProperties().put("ebean.migrationtest.useMigrationStoredProcedures", true); + config.getProperties().put("ebean.migrationtest.migration.platforms", "mysql"); + config.getProperties().put("ebean.migrationtest.migration.migrationPath", "dbmigration/migrationtest-procedures/"); + config.setPackages(Arrays.asList("misc.migration.v1_0")); // First, we clean up the output-directory - assertThat(migration.migrationDirectory().getAbsolutePath()).contains("procedures"); - Files.walk(migration.migrationDirectory().toPath()) - .filter(Files::isRegularFile) - .map(Path::toFile).forEach(File::delete); +// Files.walk(Paths.get(pathToResources , "dbmigration","migrationtest-procedures")) +// .filter(Files::isRegularFile).map(Path::toFile).forEach(File::delete); + + DatabaseFactory.create(config).shutdown(); // then we generate migration scripts for v1_0 - assertThat(migration.generateMigration()).isEqualTo("1.0__initial"); + assertThat(DbMigrationPlugin.getLastMigration()).isEqualTo("1.0__initial"); + assertThat(DbMigrationPlugin.getLastInit()).isEqualTo("1.0__initial"); + + // and we check repeatative calls + DatabaseFactory.create(config).shutdown(); + assertThat(DbMigrationPlugin.getLastMigration()).isNull(); + assertThat(DbMigrationPlugin.getLastInit()).isNull(); + + // and now for v1_1 + config.setPackages(Arrays.asList("misc.migration.v1_1")); + DatabaseFactory.create(config).shutdown(); + assertThat(DbMigrationPlugin.getLastMigration()).isEqualTo("1.1,1.2__dropsFor_1.1"); + assertThat(DbMigrationPlugin.getLastInit()).isEqualTo("1.2"); - config.setPackages(Arrays.asList("misc.migration.mysql_v1_1")); - server.shutdown(); - server = DatabaseFactory.create(config); - migration.setServer(server); - migration.setMigrationPath("mysql/procedures"); - assertThat(migration.generateMigration()).isEqualTo("1.1"); - - System.setProperty("ddl.migration.pendingDropsFor", "1.1"); - assertThat(migration.generateMigration()).isEqualTo("1.2__dropsFor_1.1"); - - final Path sqlFile = migration.migrationDirectory().toPath() - .resolve("mysql/1.2__dropsFor_1.1.sql"); - - assertThat(sqlFile).isNotEmptyFile(); - assertThat(Files.readAllLines(sqlFile, StandardCharsets.UTF_8)) - .contains("CALL usp_ebean_drop_column('migtest_e_basic', 'status2');") - .contains("CALL usp_ebean_drop_column('migtest_e_basic', 'description');"); +// // subsequent call +// DatabaseFactory.create(config).shutdown(); +// assertThat(DbMigrationPlugin.getLastMigration()).isNull(); +// assertThat(DbMigrationPlugin.getLastInit()).isNull(); +// +// // and now for v1_2 +// config.setPackages(Arrays.asList("misc.migration.v1_2")); +// DatabaseFactory.create(config).shutdown(); +// assertThat(DbMigrationPlugin.getLastMigration()).isEqualTo("1.3,1.4__dropsFor_1.3"); +// assertThat(DbMigrationPlugin.getLastInit()).isEqualTo("1.4"); +// +// +// DefaultDbMigration migration = new DefaultDbMigration(); +// migration.setIncludeIndex(true); +// // We use src/test/resources as output directory (so we see in GIT if files will change) +// migration.setPathToResources("src/test/resources"); +// +// migration.addPlatform(Platform.MYSQL, "mysql"); +// +// final PlatformConfig platformConfig = new PlatformConfig(); +// platformConfig.setUseMigrationStoredProcedures(true); +// +// DatabaseConfig config = new DatabaseConfig(); +// config.setName("migrationtest"); +// config.loadFromProperties(); +// config.setPlatformConfig(platformConfig); +// config.setRegister(false); +// config.setDefaultServer(false); +// config.getProperties().put("ebean.migration.migrationPath", "db/migration/mysql"); +// +// config.setPackages(Arrays.asList("misc.migration.mysql_v1_0")); +// Database server = DatabaseFactory.create(config); +// migration.setServer(server); +// migration.setMigrationPath("mysql/procedures"); +// +// // First, we clean up the output-directory +// assertThat(migration.migrationDirectory().getAbsolutePath()).contains("procedures"); +// Files.walk(migration.migrationDirectory().toPath()) +// .filter(Files::isRegularFile) +// .map(Path::toFile).forEach(File::delete); +// +// // then we generate migration scripts for v1_0 +// assertThat(migration.generateMigration()).isEqualTo("1.0__initial"); +// +// config.setPackages(Arrays.asList("misc.migration.mysql_v1_1")); +// server.shutdown(); +// server = DatabaseFactory.create(config); +// migration.setServer(server); +// migration.setMigrationPath("mysql/procedures"); +// assertThat(migration.generateMigration()).isEqualTo("1.1,1.2__dropsFor_1.1"); +// +// final Path sqlFile = migration.migrationDirectory().toPath() +// .resolve("mysql/1.2__dropsFor_1.1.sql"); +// +// assertThat(sqlFile).isNotEmptyFile(); +// assertThat(Files.readAllLines(sqlFile, StandardCharsets.UTF_8)) +// .contains("CALL usp_ebean_drop_column('migtest_e_basic', 'status2');") +// .contains("CALL usp_ebean_drop_column('migtest_e_basic', 'description');"); } } diff --git a/ebean-ddl-generator/src/test/resources/application-test.properties b/ebean-ddl-generator/src/test/resources/application-test.properties index dfcb052ab..a162570da 100644 --- a/ebean-ddl-generator/src/test/resources/application-test.properties +++ b/ebean-ddl-generator/src/test/resources/application-test.properties @@ -22,6 +22,16 @@ ebean.migrationtest.ddl.header=-- Migrationscripts for ebean unittest ebean.migrationtest.migration.appName=migrationtest ebean.migrationtest.migration.migrationPath=dbmigration/migrationtest ebean.migrationtest.migration.strict=true +ebean.migrationtest.migration.generate=true +ebean.migrationtest.migration.run=true +ebean.migrationtest.migration.includeIndex=true +ebean.migrationtest.migration.generateInit=true +ebean.migrationtest.migration.generatePendingDrop=auto +ebean.migrationtest.migration.platforms=db2,h2,hsqldb,mysql,mysql55=mysql55,postgres,oracle,sqlite,sqlserver17=sqlserver17,hana + +# need to generate unique statements to prevent them from being filtered out as duplicates by the DdlRunner +ebean.hana.generateUniqueDdl=true + # parameters for migration test datasource.migrationtest-history.username=SA diff --git a/ebean-test/pom.xml b/ebean-test/pom.xml index 0228f3512..e7d13cdc5 100644 --- a/ebean-test/pom.xml +++ b/ebean-test/pom.xml @@ -90,8 +90,8 @@ io.ebean - ebean-migration - 12.12.1 + ebean-dbmigration-runner + 12.14.1-FOC1-SNAPSHOT test diff --git a/pom.xml b/pom.xml index 72e4e31dc..72b6aa18a 100644 --- a/pom.xml +++ b/pom.xml @@ -99,6 +99,7 @@ ebean-core-type ebean-core ebean-ddl-generator + ebean-dbmigration-runner ebean-autotune ebean-externalmapping-api ebean-externalmapping-xml