play.db.ebean.orm.evolution.EvolutionMigration Maven / Gradle / Ivy
The newest version!
package play.db.ebean.orm.evolution;
import io.ebean.DB;
import io.ebean.Database;
import io.ebean.config.DatabaseConfig;
import io.ebean.dbmigration.DbMigration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import play.Environment;
import play.api.mvc.RequestHeader;
import play.core.WebCommands;
import play.db.ebean.orm.EbeanConfig;
import play.db.ebean.orm.PlayEbeanExtraConfig;
import play.mvc.Result;
import play.mvc.Results;
import play.twirl.api.Html;
import scala.Option;
import javax.inject.Inject;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Consumer;
import java.util.function.Function;
/**
* DatabaseMigration.
*
* @author Pierre Adam
* @since 22.03.04
*/
public class EvolutionMigration {
/**
* The constant RESOURCES_FOLDER.
*/
private static final String RESOURCES_FOLDER = "conf";
/**
* The constant OUTPUT_FOLDER.
*/
private static final String OUTPUT_FOLDER = "evolutions";
/**
* The Ebean config.
*/
private final EbeanConfig ebeanConfig;
/**
* The Environment.
*/
private final Environment environment;
/**
* The Routing.
*/
private final Map> routing;
/**
* The Logger.
*/
private final Logger logger = LoggerFactory.getLogger(this.getClass());
/**
* Instantiates a new Database migration.
*
* @param webCommands the web commands
* @param environment the environment
* @param ebeanConfig the ebean config
*/
@Inject
public EvolutionMigration(
final WebCommands webCommands,
final Environment environment,
final EbeanConfig ebeanConfig
) {
this.ebeanConfig = ebeanConfig;
this.environment = environment;
this.routing = new HashMap<>();
if (environment.isDev()) {
this.buildRouting();
this.registerWebCommands(webCommands);
}
}
/**
* Gets header.
*
* @return the header
*/
public static String getHeader() {
return "-- Generated by Play-Ebean --\n" +
"-- You may want to create the # --- !Downs section yourself --\n\n" +
"# --- !Ups\n";
}
/**
* Build routing.
*/
private void buildRouting() {
this.routing.put("/@ebean", this::home);
this.routing.put("/@ebean/migration", this::createMigrations);
}
/**
* Register web commands.
*
* @param webCommands the web commands
*/
private void registerWebCommands(final WebCommands webCommands) {
webCommands.addHandler((request, buildLink, path) -> {
final Result result = this.routing.getOrDefault(request.path(), r -> null).apply(request);
return result == null ? Option.empty() : Option.apply(result.asScala());
});
}
/**
* Create migration result.
*
* @param request the request
* @return the result
*/
private Result createMigrations(final RequestHeader request) {
this.ebeanConfig.serverConfigs().forEach((serverName, databaseConfig) -> {
final PlayEbeanExtraConfig extraConfig = databaseConfig.getServiceObject(PlayEbeanExtraConfig.class);
if (extraConfig.getEvolutionMigrationConfig().isEnabled()) {
this.createMigration(serverName, databaseConfig, extraConfig);
}
});
return Results.redirect("/");
}
/**
* Create migration.
*
* @param serverName the server name
* @param databaseConfig the database config
* @param extraConfig the extra config
*/
public void createMigration(
final String serverName,
final DatabaseConfig databaseConfig,
final PlayEbeanExtraConfig extraConfig
) {
final DbMigration dbMigration = DbMigration.create();
final Database db = DB.byName(serverName);
final File resourceFolder = this.environment.getFile(EvolutionMigration.RESOURCES_FOLDER);
final String outputConfRelPath = EvolutionMigration.OUTPUT_FOLDER + "/" + serverName;
dbMigration.setServerConfig(databaseConfig);
dbMigration.setServer(db);
dbMigration.setPathToResources(resourceFolder.getPath());
dbMigration.setMigrationPath(outputConfRelPath);
dbMigration.setIncludeGeneratedFileComment(true);
dbMigration.setHeader(EvolutionMigration.getHeader());
try {
final String filename = dbMigration.generateMigration();
if (filename != null) {
// If we get a filename here, we need to check if the sql file has been created.
// If the sql file is missing, we want to create to respect evolution incremental version.
final File file = new File(resourceFolder, outputConfRelPath + "/" + filename + ".sql");
if (!file.exists()) {
try (final BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(file))) {
bufferedWriter.write(EvolutionMigration.getHeader());
bufferedWriter.write("\n-- Nothing to create.");
} catch (final Exception e) {
throw new RuntimeException("Unable to write to file.", e);
}
}
}
// Process the pending drops.
for (final String pendingDrop : dbMigration.getPendingDrops()) {
dbMigration.setGeneratePendingDrop(pendingDrop);
final String dropFilename = dbMigration.generateMigration();
final File file = new File(resourceFolder, outputConfRelPath + "/" + dropFilename + ".sql");
final File newFile = new File(resourceFolder, outputConfRelPath + "/" + dropFilename.split("_")[0] + ".sql");
if (file.exists()) {
file.renameTo(newFile);
}
}
} catch (final IOException e) {
throw new RuntimeException("Something went wrong", e);
}
}
/**
* Home result.
*
* @param request the request
* @return the result
*/
public Result home(final RequestHeader request) {
final Html html = this.renderOnPage(sb -> {
sb.append("Ebean Migration
");
sb.append("");
sb.append("");
sb.append("Server Platform ");
sb.append(" ");
this.ebeanConfig.serverConfigs().forEach((serverName, databaseConfig) -> {
sb.append("");
sb.append("");
sb.append(serverName);
sb.append(" ");
sb.append(DB.byName(serverName).platform().name());
sb.append(" ");
sb.append(" ");
});
sb.append("
");
});
return Results.ok(html);
}
private Html renderOnPage(Consumer consumer) {
final StringBuilder result = new StringBuilder();
result.append("");
result.append("");
result.append("");
result.append("");
result.append("");
result.append("");
result.append("");
result.append("");
consumer.accept(result);
result.append("");
result.append("");
return new Html(result.toString());
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy