package org.constellation.database.configuration; import org.constellation.configuration.ConfigurationRuntimeException; import org.constellation.database.model.FlywayUtils; import org.flywaydb.core.Flyway; import org.flywaydb.core.api.MigrationVersion; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.annotation.Configuration; import javax.annotation.PostConstruct; import javax.sql.DataSource; import java.sql.*; /** * Bean used to initialize/migrate database in Spring context. * * @author Quentin Boileau (Geomatys) */ @Configuration public class FlywaySpring { private static final Logger LOGGER = LoggerFactory.getLogger(FlywaySpring.class); @Autowired @Qualifier(value = "dataSource") private DataSource dataSource; @PostConstruct public void migrate() throws ConfigurationRuntimeException { LOGGER.info("Start database migration check"); boolean liquibaseInstalled = false; boolean liquibaseUpToDate = false; //search for previous installation using liquibase try (Connection conn = dataSource.getConnection()) { final DatabaseMetaData metaData = conn.getMetaData(); try (ResultSet liquibaseTable = metaData.getTables(null, "public", "databasechangelog", null)) { if (liquibaseTable.next()) { liquibaseInstalled = true; final String lastLBVersion = "SELECT 1 FROM public.databasechangelog WHERE id='version_1.45';"; try (Statement stmt = conn.createStatement(); ResultSet upToDate = stmt.executeQuery(lastLBVersion)) { if (upToDate.next()) { liquibaseUpToDate = true; } } } } } catch (SQLException ex) { throw new ConfigurationRuntimeException("An error occurs during database analysis searching for " + "previous installations.", ex); } try { final Flyway flyway = FlywayUtils.createFlywayConfig(dataSource); //create schema_version table if not exist, even if database is not empty flyway.setBaselineOnMigrate(true); //previous liquibase installation found but not up to date if (liquibaseInstalled) { if (liquibaseUpToDate) { //start after 1.1.0.0 flyway.setBaselineVersion(MigrationVersion.fromVersion("1.1.0.0")); LOGGER.info("Previous installation with Liquibase detected and up to date, start migration from 1.1.0.0 patch"); } else { throw new ConfigurationRuntimeException("Previous database installation found but not up to date, " + "please update to 1.0.13 before applying this update."); } } flyway.migrate(); } catch (SQLException ex) { throw new ConfigurationRuntimeException(ex.getMessage(), ex); } //clean old liquibase changelogs if (liquibaseInstalled) { LOGGER.info("Drop old liquibase changelogs tables"); try (Connection conn = dataSource.getConnection(); Statement stmt = conn.createStatement()) { stmt.execute("DROP TABLE IF EXISTS public.databasechangelog CASCADE;"); stmt.execute("DROP TABLE IF EXISTS public.databasechangeloglock CASCADE;"); } catch (SQLException ex) { throw new ConfigurationRuntimeException("Unable to delete old liquibase changelog tables", ex); } } } }