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

org.openmetadata.service.migration.utils.MigrationFile Maven / Gradle / Ivy

There is a newer version: 1.5.11
Show newest version
package org.openmetadata.service.migration.utils;

import java.io.File;
import java.nio.charset.StandardCharsets;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import org.flywaydb.core.api.configuration.ClassicConfiguration;
import org.flywaydb.core.api.configuration.Configuration;
import org.flywaydb.core.internal.database.postgresql.PostgreSQLParser;
import org.flywaydb.core.internal.parser.Parser;
import org.flywaydb.core.internal.parser.ParsingContext;
import org.flywaydb.core.internal.resource.filesystem.FileSystemResource;
import org.flywaydb.core.internal.sqlscript.SqlStatementIterator;
import org.flywaydb.database.mysql.MySQLParser;
import org.openmetadata.schema.api.configuration.pipelineServiceClient.PipelineServiceClientConfiguration;
import org.openmetadata.schema.api.security.AuthenticationConfiguration;
import org.openmetadata.service.jdbi3.MigrationDAO;
import org.openmetadata.service.jdbi3.locator.ConnectionType;
import org.openmetadata.service.util.EntityUtil;

public class MigrationFile implements Comparable {
  public final int[] versionNumbers;
  public final String version;
  public final ConnectionType connectionType;
  public final PipelineServiceClientConfiguration pipelineServiceClientConfiguration;
  public final AuthenticationConfiguration authenticationConfiguration;

  public final File dir;
  public final Boolean isExtension;
  public final String dbPackageName;

  private final MigrationDAO migrationDAO;
  private final List schemaChanges;
  private final List postDDLScripts;
  public static final String DEFAULT_MIGRATION_PROCESS_CLASS =
      "org.openmetadata.service.migration.api.MigrationProcessImpl";

  public MigrationFile(
      File dir,
      MigrationDAO migrationDAO,
      ConnectionType connectionType,
      PipelineServiceClientConfiguration pipelineServiceClientConfiguration,
      AuthenticationConfiguration authenticationConfiguration,
      Boolean isExtension) {
    this.dir = dir;
    this.isExtension = isExtension;
    this.version = dir.getName();
    this.connectionType = connectionType;
    this.migrationDAO = migrationDAO;
    this.pipelineServiceClientConfiguration = pipelineServiceClientConfiguration;
    this.authenticationConfiguration = authenticationConfiguration;
    this.dbPackageName = connectionType == ConnectionType.MYSQL ? "mysql" : "postgres";
    versionNumbers = convertToNumber(version);
    schemaChanges = new ArrayList<>();
    postDDLScripts = new ArrayList<>();
  }

  @Override
  public int compareTo(MigrationFile another) {
    return compareVersionNumbers(another.versionNumbers);
  }

  public boolean biggerThan(String version) {
    int[] numbers = convertToNumber(version);
    int compare = compareVersionNumbers(numbers);
    return compare > 0;
  }

  public void parseSQLFiles() {
    final ParsingContext parsingContext = new ParsingContext();
    Configuration configuration = new ClassicConfiguration();
    Parser parser = new PostgreSQLParser(configuration, parsingContext);
    if (connectionType == ConnectionType.MYSQL) {
      parser = new MySQLParser(configuration, parsingContext);
    }
    if (new File(getSchemaChangesFile()).isFile()) {
      try (SqlStatementIterator schemaChangesIterator =
          parser.parse(
              new FileSystemResource(null, getSchemaChangesFile(), StandardCharsets.UTF_8, true))) {
        while (schemaChangesIterator.hasNext()) {
          String sqlStatement = schemaChangesIterator.next().getSql();
          if (!checkIfQueryPreviouslyRan(sqlStatement)) {
            schemaChanges.add(sqlStatement);
          }
        }
      }
    }
    if (new File(getPostDDLScriptFile()).isFile()) {
      try (SqlStatementIterator schemaChangesIterator =
          parser.parse(
              new FileSystemResource(null, getPostDDLScriptFile(), StandardCharsets.UTF_8, true))) {
        while (schemaChangesIterator.hasNext()) {
          String sqlStatement = schemaChangesIterator.next().getSql();
          if (!checkIfQueryPreviouslyRan(sqlStatement)) {
            postDDLScripts.add(sqlStatement);
          }
        }
      }
    }
  }

  public String getMigrationProcessClassName() {
    String clazzName =
        String.format(
            "org.openmetadata.service.migration.%s.%s.Migration",
            dbPackageName, getVersionPackageName());
    try {
      Class.forName(clazzName);
    } catch (ClassNotFoundException e) {
      return DEFAULT_MIGRATION_PROCESS_CLASS;
    }
    return clazzName;
  }

  public String getMigrationsFilePath() {
    if (connectionType == ConnectionType.MYSQL) {
      return Paths.get(dir.getAbsolutePath(), "mysql").toString();
    } else {
      return Paths.get(dir.getAbsolutePath(), "postgres").toString();
    }
  }

  public String getSchemaChangesFile() {
    if (connectionType == ConnectionType.MYSQL) {
      return Paths.get(dir.getAbsolutePath(), "mysql", "schemaChanges.sql").toString();
    } else {
      return Paths.get(dir.getAbsolutePath(), "postgres", "schemaChanges.sql").toString();
    }
  }

  public String getPostDDLScriptFile() {
    if (connectionType == ConnectionType.MYSQL) {
      return Paths.get(dir.getAbsolutePath(), "mysql", "postDataMigrationSQLScript.sql").toString();
    } else {
      return Paths.get(dir.getAbsolutePath(), "postgres", "postDataMigrationSQLScript.sql")
          .toString();
    }
  }

  public List getSchemaChanges() {
    return schemaChanges;
  }

  public List getPostDDLScripts() {
    return postDDLScripts;
  }

  private int[] convertToNumber(String version) {
    final String[] split = version.split("\\-")[0].split("\\.");
    int[] numbers = new int[split.length];
    for (int i = 0; i < split.length; i++) {
      numbers[i] = Integer.parseInt(split[i]);
    }
    return numbers;
  }

  private int compareVersionNumbers(int[] another) {
    final int maxLength = Math.max(versionNumbers.length, another.length);
    for (int i = 0; i < maxLength; i++) {
      final int left = i < versionNumbers.length ? versionNumbers[i] : 0;
      final int right = i < another.length ? another[i] : 0;
      if (left != right) {
        return left < right ? -1 : 1;
      }
    }
    return 0;
  }

  private String getVersionPackageName() {
    StringBuilder arrayAsString = new StringBuilder();
    for (int versionNumber : versionNumbers) {
      arrayAsString.append(versionNumber);
    }
    return "v" + arrayAsString;
  }

  private boolean checkIfQueryPreviouslyRan(String query) {
    String checksum = EntityUtil.hash(query);
    String sqlStatement = migrationDAO.checkIfQueryPreviouslyRan(checksum);
    return sqlStatement != null;
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy