All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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(""); sb.append(""); this.ebeanConfig.serverConfigs().forEach((serverName, databaseConfig) -> { sb.append(""); sb.append(""); sb.append(""); }); sb.append("
ServerPlatform
"); sb.append(serverName); sb.append(""); sb.append(DB.byName(serverName).platform().name()); 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