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

org.springframework.util.FlywayUtils Maven / Gradle / Ivy

package org.springframework.util;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.Date;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.UUID;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.dbunit.DatabaseUnitException;
import org.dbunit.database.DatabaseConnection;
import org.dbunit.dataset.ITable;
import org.dbunit.dataset.ReplacementDataSet;
import org.dbunit.dataset.datatype.IDataTypeFactory;
import org.dbunit.dataset.xml.FlatXmlDataSetBuilder;
import org.dbunit.ext.mssql.InsertIdentityOperation;
import org.dbunit.operation.DatabaseOperation;
import org.springframework.boot.autoconfigure.orm.jpa.JpaBaseConfiguration;
import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties;
import org.springframework.context.ApplicationContext;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.ConnectionCallback;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.orm.jpa.vendor.Database;

public class FlywayUtils {
  private final static Log logger = LogFactory.getLog(FlywayUtils.class);

  /**
   * 
    Class clazz = getClass();
    Class databaseDialectClass = getDatabaseDialectClass(new JpaProperties().determineDatabase(jdbcTemplate.getDataSource()));
    ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(false);
    provider.addIncludeFilter(new RegexPatternTypeFilter(Pattern.compile(".*")));
    final MetadataSources metadataSources = new MetadataSources();
    for (BeanDefinition beanDefinition : provider.findCandidateComponents(ClassUtils.getPackageName(clazz))) {
      metadataSources.addAnnotatedClassName(beanDefinition.getBeanClassName());
    }
    String[] packageNames = clazz.getPackage().getName().split("[.]");
    if (packageNames != null && packageNames.length > 1) {
      provider.setResourcePattern("*" + ClassUtils.CLASS_FILE_SUFFIX);
      for (BeanDefinition beanDefinition : provider.findCandidateComponents(StringUtils.arrayToDelimitedString(Arrays.copyOf(packageNames, packageNames.length - 1), "."))) {
        metadataSources.addAnnotatedClassName(beanDefinition.getBeanClassName());
      }
    }
  
    final SchemaExport schemaExport = new SchemaExport();
    schemaExport.setDelimiter(";");
    schemaExport.setFormat(true);
  
    final EnumSet targetTypes = EnumSet.of(TargetType.STDOUT, TargetType.SCRIPT);
    try {
      String prefix = ClassUtils.getShortName(clazz) + '_' + ClassUtils.getShortName(databaseDialectClass) + '_';
      String suffix = ".sql";
      File directory = Paths.get(SystemPropertyUtils.resolvePlaceholders("${user.home}"), Paths.get(SystemPropertyUtils.resolvePlaceholders("${java.io.tmpdir}")).toFile().getName()).toFile();
      Assert.isTrue(directory != null && (directory.mkdirs() || directory.isDirectory()), "Create Directory fail... " + directory);
      schemaExport.setOutputFile(File.createTempFile(prefix, suffix, directory).getPath());
    }
    catch (IOException e) {
      throw new IllegalStateException(e);
    }
  
    final StandardServiceRegistryBuilder standardServiceRegistryBuilder = new StandardServiceRegistryBuilder(new BootstrapServiceRegistryBuilder().build());
    standardServiceRegistryBuilder.applySettings(org.hibernate.cfg.Environment.getProperties());
    standardServiceRegistryBuilder.applySetting(org.hibernate.cfg.AvailableSettings.DIALECT, databaseDialectClass);
  
    jdbcTemplate.execute(new ConnectionCallback() {
      @Override
      public Void doInConnection(Connection connection) throws SQLException, DataAccessException {
        standardServiceRegistryBuilder.applySetting(org.hibernate.cfg.AvailableSettings.HBM2DDL_CONNECTION, connection);
        schemaExport.createOnly(targetTypes, metadataSources.getMetadataBuilder(standardServiceRegistryBuilder.build()).build());
        return null;
      }
    });
  private Class getDatabaseDialectClass(Database database) {
    Assert.notNull(database, "'database' must not be null");
    switch (database) {
    case H2:
      return H2Dialect.class;
    case MYSQL:
      return org.hibernate.dialect.MySQL5InnoDBDialect.class;
    case SQL_SERVER:
      return org.hibernate.dialect.SQLServer2008DialectCustom.class;
    default:
      throw new UnsupportedOperationException();
    }
  }
   * 
   * @see javax.persistence.Persistence#generateSchema(String, java.util.Map)
   * @see org.dbunit.dataset.ReplacementTable#NO_VAULE
   */
  public static void DDL(ApplicationContext applicationContext, JdbcTemplate jdbcTemplate, Class clazz) throws IOException {
    Assert.notNull(applicationContext, "'applicationContext' must not be null");
    JpaProperties jpaProperties = applicationContext.getBean(JpaProperties.class);
    jpaProperties.getProperties().put("javax.persistence.schema-generation.database.action", "create");
    jpaProperties.getProperties().put("javax.persistence.schema-generation.scripts.action", "create");
    String id = applicationContext.getId();
    if (StringUtils.hasText(id)) {
      Database database = new JpaProperties().determineDatabase(jdbcTemplate.getDataSource());
      File tmpdir = new File(SystemPropertyUtils.resolvePlaceholders("${java.io.tmpdir}"));
      File directory = new File(SystemPropertyUtils.resolvePlaceholders("${user.home}"), StringUtils.getFilename(tmpdir.getName()));

      Assert.isTrue(directory != null && (directory.mkdirs() || directory.isDirectory()), "Create Directory fail..." + directory);
      jpaProperties.getProperties().put("javax.persistence.schema-generation.scripts.create-target",
          File.createTempFile(ClassUtils.getShortName(clazz) + '_' + id.replace(':', '_') + '_' + database + '_', ".sql", directory).getCanonicalPath());
    }
    applicationContext.getBean(JpaBaseConfiguration.class).entityManagerFactory(null);
  }

  public static void DML(ApplicationContext applicationContext, JdbcTemplate jdbcTemplate, Class clazz) {
    Assert.notNull(applicationContext, "'applicationContext' must not be null");

    Set resources = new LinkedHashSet();
    resources.add(new ClassPathResource(ClassUtils.convertClassNameToResourcePath(ClassUtils.getPackageName(clazz)) + '/' + ClassUtils.getShortName(clazz) + ".xml"));
    for (String profile : applicationContext.getEnvironment().getDefaultProfiles()) {
      resources.add(new ClassPathResource(ClassUtils.convertClassNameToResourcePath(ClassUtils.getPackageName(clazz)) + '/' + ClassUtils.getShortName(clazz) + '_' + profile + ".xml"));
    }
    for (String profile : applicationContext.getEnvironment().getActiveProfiles()) {
      resources.add(new ClassPathResource(ClassUtils.convertClassNameToResourcePath(ClassUtils.getPackageName(clazz)) + '/' + ClassUtils.getShortName(clazz) + '_' + profile + ".xml"));
    }
    Database database = new JpaProperties().determineDatabase(jdbcTemplate.getDataSource());

    String lob = UUID.randomUUID().toString();
    logger.info(String.format("%n%nUsing default lob: %s%n", lob));

    for (Resource resource : resources) {
      if (resource.exists()) {
        String[] tableNames = jdbcTemplate.execute(new ConnectionCallback() {
          /**
           * @see java.nio.charset.StandardCharsets#UTF_8
           * @see org.dbunit.dataset.xml.XmlDataSet#XmlDataSet(InputStream)
           * @see org.dbunit.database.DatabaseConfig#FEATURE_CASE_SENSITIVE_TABLE_NAMES
           */
          @Override
          public String[] doInConnection(Connection con) throws SQLException, DataAccessException {
            try (InputStream inputStream = resource.getInputStream(); AutoCloseableDatabaseConnection databaseConnection = new AutoCloseableDatabaseConnection(con)) {
              databaseConnection.getConfig().setProperty(org.dbunit.database.DatabaseConfig.PROPERTY_DATATYPE_FACTORY, getDatatypeFactory(database));
              databaseConnection.getConfig().setProperty(org.dbunit.database.DatabaseConfig.PROPERTY_ESCAPE_PATTERN, getEscapePattern(database));
              databaseConnection.getConfig().setProperty(org.dbunit.database.DatabaseConfig.FEATURE_CASE_SENSITIVE_TABLE_NAMES, true);

              FlatXmlDataSetBuilder flatXmlDataSetBuilder = new FlatXmlDataSetBuilder();
              flatXmlDataSetBuilder.setColumnSensing(true);
              flatXmlDataSetBuilder.setCaseSensitiveTableNames(true);

              ReplacementDataSet replacementDataSet = new ReplacementDataSet(flatXmlDataSetBuilder.build(inputStream));
              replacementDataSet.addReplacementObject(ITable.NO_VALUE, null);
              replacementDataSet.addReplacementObject("[null]", null);
              replacementDataSet.addReplacementObject("[date]", new Date());
              replacementDataSet.addReplacementObject("[lob]", lob.getBytes());
              DatabaseOperation databaseOperation = DatabaseOperation.INSERT;
              if (database != null && database == Database.SQL_SERVER) {
                databaseOperation = new InsertIdentityOperation(databaseOperation);
              }
              databaseOperation.execute(databaseConnection, replacementDataSet);
              return replacementDataSet.getTableNames();
            }
            catch (SQLException | IOException | DatabaseUnitException e) {
              throw new SQLException("DBunit execute fail... from " + resource, e);
            }
          }
        });
        logger.info("Table: " + Arrays.asList(tableNames));
      }
    }
  }

  // "'?'"
  private static String getEscapePattern(Database database) {
    Assert.notNull(database, "'database' must not be null");
    switch (database) {
    case H2:
      return "\"?\"";
    case MYSQL:
      return "`?`";
    case SQL_SERVER:
      return "[?]";
    default:
      return "?";
    }
  }

  /**
   * @see UnsupportedOperationException
   */
  private static IDataTypeFactory getDatatypeFactory(Database database) {
    Assert.notNull(database, "'database' must not be null");
    switch (database) {
    case H2:
      return new org.dbunit.ext.h2.H2DataTypeFactory();
    case MYSQL:
      return new org.dbunit.ext.mysql.MySqlDataTypeFactory();
    case SQL_SERVER:
      return new org.dbunit.ext.mssql.MsSqlDataTypeFactory();
    default:
      return new org.dbunit.dataset.datatype.DefaultDataTypeFactory();
    }
  }
}

class AutoCloseableDatabaseConnection extends DatabaseConnection implements AutoCloseable {
  public AutoCloseableDatabaseConnection(Connection connection) throws DatabaseUnitException {
    super(connection);
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy