001package io.ebeaninternal.dbmigration.model;
002
003import org.slf4j.Logger;
004import org.slf4j.LoggerFactory;
005
006import io.ebean.migration.MigrationVersion;
007
008import java.io.File;
009import java.util.ArrayList;
010import java.util.Collections;
011import java.util.List;
012
013/**
014 * Build the model from the series of migrations.
015 */
016public class MigrationModel {
017
018  private static final Logger logger = LoggerFactory.getLogger(MigrationModel.class);
019
020  private final ModelContainer model = new ModelContainer();
021
022  private final File modelDirectory;
023
024  private final String modelSuffix;
025
026  private MigrationVersion lastVersion;
027
028  public MigrationModel(File modelDirectory, String modelSuffix) {
029    this.modelDirectory = modelDirectory;
030    this.modelSuffix = modelSuffix;
031  }
032
033  /**
034   * Read all the migrations returning the model with all
035   * the migrations applied in version order.
036   *
037   * @param dbinitMigration If true we don't apply model changes, migration is from scratch.
038   */
039  public ModelContainer read(boolean dbinitMigration) {
040
041    readMigrations(dbinitMigration);
042    return model;
043  }
044
045  private void readMigrations(boolean dbinitMigration) {
046
047    // find all the migration xml files
048    File[] xmlFiles = modelDirectory.listFiles(pathname -> pathname.getName().toLowerCase().endsWith(modelSuffix));
049    if (xmlFiles == null || xmlFiles.length == 0) {
050      return;
051    }
052    List<MigrationResource> resources = new ArrayList<>(xmlFiles.length);
053    for (File xmlFile : xmlFiles) {
054      resources.add(new MigrationResource(xmlFile, createVersion(xmlFile)));
055    }
056
057    // sort into version order before applying
058    Collections.sort(resources);
059
060    if (!dbinitMigration) {
061      for (MigrationResource migrationResource : resources) {
062        logger.debug("read {}", migrationResource);
063        model.apply(migrationResource.read(), migrationResource.getVersion());
064      }
065    }
066
067    // remember the last version
068    if (!resources.isEmpty()) {
069      lastVersion = resources.get(resources.size() - 1).getVersion();
070    }
071  }
072
073  private MigrationVersion createVersion(File xmlFile) {
074    String fileName = xmlFile.getName();
075    String versionName = fileName.substring(0, fileName.length() - modelSuffix.length());
076    return MigrationVersion.parse(versionName);
077  }
078
079  public String getNextVersion(String initialVersion) {
080
081    return lastVersion == null ? initialVersion : lastVersion.nextVersion();
082  }
083}