diff --git a/build.gradle b/build.gradle index 81c751a..fa7e724 100644 --- a/build.gradle +++ b/build.gradle @@ -61,6 +61,8 @@ dependencies { api "io.ebean:ebean-querybean:12.5.1" api "io.ebean:ebean:12.5.1" + implementation "io.ebean:ebean-migration:12.1.4" + testImplementation group: 'com.h2database', name: 'h2', version: '1.4.200' testImplementation 'org.junit.jupiter:junit-jupiter:5.+' diff --git a/src/main/java/net/silthus/ebean/Config.java b/src/main/java/net/silthus/ebean/Config.java index 4e54c2b..6b7d22d 100644 --- a/src/main/java/net/silthus/ebean/Config.java +++ b/src/main/java/net/silthus/ebean/Config.java @@ -1,13 +1,17 @@ package net.silthus.ebean; +import com.google.common.base.Strings; +import com.google.common.io.Files; import io.ebean.config.DatabaseConfig; import io.ebean.datasource.DataSourceConfig; import lombok.AllArgsConstructor; import lombok.Setter; import lombok.Value; import lombok.experimental.Accessors; +import lombok.extern.java.Log; import java.io.File; +import java.io.IOException; import java.util.Arrays; @Value @@ -24,6 +28,8 @@ public static Builder builder() { boolean runMigrations; boolean createAll; Class[] entities; + Class migrationClass; + String migrationPath; public Builder toBuilder() { DataSourceConfig dataSourceConfig = databaseConfig.getDataSourceConfig(); @@ -37,12 +43,15 @@ public Builder toBuilder() { autoDownloadDriver, runMigrations, createAll, - entities); + entities, + migrationClass, + migrationPath); } @Setter @AllArgsConstructor @Accessors(fluent = true) + @Log public static class Builder { private DriverMapping driver = DriverMapping.DRIVERS.get("h2"); @@ -56,6 +65,8 @@ public static class Builder { private boolean runMigrations = false; private boolean createAll = true; private Class[] entities = new Class[0]; + private Class migrationClass = getClass(); + private String migrationPath = "dbmigration"; Builder() { } @@ -94,19 +105,30 @@ public Config build() { databaseConfig.setClasses(Arrays.asList(entities.clone())); if (runMigrations) { - databaseConfig.setRunMigration(true); + try { + File tempDir = Files.createTempDir(); + File migrationDir = new File(tempDir, migrationPath); + databaseConfig.setRunMigration(true); + JarUtil.copyFolderFromJar(migrationClass, migrationPath, tempDir, JarUtil.CopyOption.REPLACE_IF_EXIST); + databaseConfig.getMigrationConfig().setMigrationPath("filesystem:" + migrationDir.getAbsolutePath()); + } catch (IOException e) { + e.printStackTrace(); + databaseConfig.setRunMigration(false); + } } else if (createAll) { + databaseConfig.setRunMigration(false); databaseConfig.setDdlGenerate(true); databaseConfig.setDdlRun(true); } - return new Config(driver, driverPath, databaseConfig, autoDownloadDriver, runMigrations, createAll, entities); + return new Config(driver, driverPath, databaseConfig, autoDownloadDriver, runMigrations, createAll, entities, migrationClass, migrationPath); } private DatabaseConfig defaultDatabaseConfig() { DatabaseConfig databaseConfig = new DatabaseConfig(); + databaseConfig.loadFromProperties(); databaseConfig.setDefaultServer(true); databaseConfig.setRegister(true); diff --git a/src/main/java/net/silthus/ebean/EbeanWrapper.java b/src/main/java/net/silthus/ebean/EbeanWrapper.java index 5947deb..9e49a31 100644 --- a/src/main/java/net/silthus/ebean/EbeanWrapper.java +++ b/src/main/java/net/silthus/ebean/EbeanWrapper.java @@ -7,6 +7,7 @@ import io.ebean.config.DbMigrationConfig; import io.ebean.dbmigration.DbMigration; import io.ebean.migration.MigrationConfig; +import io.ebean.migration.MigrationRunner; import org.apache.commons.io.FileUtils; import java.io.File; diff --git a/src/main/java/net/silthus/ebean/JarUtil.java b/src/main/java/net/silthus/ebean/JarUtil.java new file mode 100644 index 0000000..c50c271 --- /dev/null +++ b/src/main/java/net/silthus/ebean/JarUtil.java @@ -0,0 +1,86 @@ +package net.silthus.ebean; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; + +public class JarUtil { + + public static final char JAR_SEPARATOR = '/'; + + public static void copyFolderFromJar(Class sourceClass, String folderName, File destFolder, CopyOption option) throws IOException { + copyFolderFromJar(sourceClass, folderName, destFolder, option, null); + } + + public static void copyFolderFromJar(Class sourceClass, String folderName, File destFolder, CopyOption option, PathTrimmer trimmer) throws IOException { + if (!destFolder.exists()) + destFolder.mkdirs(); + + byte[] buffer = new byte[1024]; + + File fullPath = null; + String path = sourceClass.getProtectionDomain().getCodeSource().getLocation().getPath(); + if (trimmer != null) + path = trimmer.trim(path); + try { + if (!path.startsWith("file")) + path = "file://" + path; + + fullPath = new File(new URI(path)); + } catch (URISyntaxException e) { + e.printStackTrace(); + } + ZipInputStream zis = new ZipInputStream(new FileInputStream(fullPath)); + + ZipEntry entry; + while ((entry = zis.getNextEntry()) != null) { + if (!entry.getName().startsWith(folderName + JAR_SEPARATOR)) + continue; + + String fileName = entry.getName(); + + if (fileName.charAt(fileName.length() - 1) == JAR_SEPARATOR) { + File file = new File(destFolder + File.separator + fileName); + if (file.isFile()) { + file.delete(); + } + file.mkdirs(); + continue; + } + + File file = new File(destFolder + File.separator + fileName); + if (option == CopyOption.COPY_IF_NOT_EXIST && file.exists()) + continue; + + if (!file.getParentFile().exists()) + file.getParentFile().mkdirs(); + + if (!file.exists()) + file.createNewFile(); + FileOutputStream fos = new FileOutputStream(file); + + int len; + while ((len = zis.read(buffer)) > 0) { + fos.write(buffer, 0, len); + } + fos.close(); + } + + zis.closeEntry(); + zis.close(); + } + + public enum CopyOption { + COPY_IF_NOT_EXIST, REPLACE_IF_EXIST; + } + + @FunctionalInterface + public interface PathTrimmer { + String trim(String original); + } +} diff --git a/src/main/resources/application.yaml b/src/main/resources/application.yaml index 56bdf87..63827b2 100644 --- a/src/main/resources/application.yaml +++ b/src/main/resources/application.yaml @@ -1,8 +1,3 @@ -## H2 setup - In memory -datasource: - db: - url: jdbc:h2:~/ebean - driver: org.h2.Driver ebean: migration: run: true \ No newline at end of file