
play.db.ebean.orm.EbeanDynamicEvolutions Maven / Gradle / Ivy
The newest version!
/*
* Copyright (C) 2009-2014 Typesafe Inc.
*/
package play.db.ebean.orm;
import com.typesafe.config.Config;
import io.ebean.EbeanServer;
import io.ebean.EbeanServerFactory;
import io.ebeaninternal.api.SpiEbeanServer;
import io.ebeaninternal.dbmigration.model.CurrentModel;
import play.Environment;
import play.api.db.evolutions.DynamicEvolutions;
import play.inject.ApplicationLifecycle;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
/**
* A Play module that automatically manages Ebean configuration.
*
* @since 14.11.27
*/
@Singleton
public class EbeanDynamicEvolutions extends DynamicEvolutions {
/**
* @since 14.11.27
*/
private final EbeanConfig ebeanConfig;
/**
* @since 16.12.16
*/
private final Config configuration;
/**
* @since 14.11.27
*/
private final Environment environment;
/**
* @since 16.02.17
*/
private final Map servers = new HashMap<>();
/**
* Build a default instance.
*
* @param ebeanConfig The current Ebean servers configuration
* @param configuration The current Play configuration
* @param environment The current Play environment
* @param lifecycle The current Play lifecycle instance
* @since 14.11.27
*/
@Inject
public EbeanDynamicEvolutions(final EbeanConfig ebeanConfig, final Environment environment,
final Config configuration, final ApplicationLifecycle lifecycle) {
this.ebeanConfig = ebeanConfig;
this.configuration = configuration;
this.environment = environment;
this.start();
lifecycle.addStopHook(() -> {
servers.forEach((database, server) ->
server.shutdown(
false,
false
)
);
return CompletableFuture.completedFuture(null);
});
}
/**
* Helper method that generates the required evolution
* to properly run Ebean.
*
* @param server The EbeanServer
* @return The complete migration script generated by Ebean
* @since 14.11.27
*/
public static String generateEvolutionScript(final EbeanServer server) {
try {
final SpiEbeanServer spiServer = (SpiEbeanServer) server;
final CurrentModel ddl = new CurrentModel(spiServer);
final String ups = ddl.getCreateDdl();
final String downs = ddl.getDropAllDdl();
if (ups == null || ups.trim().isEmpty()) {
return null;
}
return (
"# --- Created by Ebean DDL\r\n" +
"# To stop Ebean DDL generation, remove this comment and start using Evolutions\r\n" +
"\r\n" +
"# --- !Ups\r\n" +
"\r\n" +
ups +
"\r\n" +
"# --- !Downs\r\n" +
"\r\n" +
downs
);
} catch (IOException ex) {
throw new RuntimeException(ex);
}
}
/**
* Initialise the Ebean servers.
*
* @since 14.11.27
*/
public void start() {
this.ebeanConfig
.serverConfigs()
.forEach((key, serverConfig) ->
this.servers
.put(
key,
EbeanServerFactory.create(serverConfig)
)
);
}
/**
* Generate evolutions.
*
* @since 14.11.27
*/
@Override
public void create() {
if (!this.environment.isProd()) {
this.ebeanConfig
.serverConfigs()
.forEach((key, serverConfig) -> {
final String evolutionScript;
if (!this.configuration.hasPath("play.evolutions.db." + key + ".enabled")
||this.configuration.getBoolean("play.evolutions.db." + key + ".enabled")) {
evolutionScript = EbeanDynamicEvolutions.generateEvolutionScript(this.servers.get(key));
} else {
evolutionScript = null;
}
if (evolutionScript != null) {
final File evolutions = this.environment.getFile("conf/evolutions/" + key + "/1.sql");
try {
String content = "";
if (evolutions.exists()) {
content = new String(
Files.readAllBytes(evolutions.toPath()),
StandardCharsets.UTF_8
);
}
if (content.isEmpty() || content.startsWith("# --- Created by Ebean DDL")) {
final File dirToCreate = this.environment.getFile("conf/evolutions/" + key);
if (!dirToCreate.exists()) {
if (!this.environment.getFile("conf/evolutions/" + key).mkdirs()) {
throw new RuntimeException("Can't create 'Evolution' directory");
}
}
if (!content.equals(evolutionScript)) {
Files.write(
evolutions.toPath(),
evolutionScript.getBytes(StandardCharsets.UTF_8)
);
}
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
});
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy