Search in sources :

Example 1 with FlywaySqlException

use of org.flywaydb.core.internal.dbsupport.FlywaySqlException in project flyway by flyway.

the class TransactionTemplate method execute.

/**
     * Executes this callback within a transaction.
     *
     * @param transactionCallback The callback to execute.
     * @return The result of the transaction code.
     */
public <T> T execute(Callable<T> transactionCallback) {
    boolean oldAutocommit = true;
    try {
        oldAutocommit = connection.getAutoCommit();
        connection.setAutoCommit(false);
        T result = transactionCallback.call();
        connection.commit();
        return result;
    } catch (SQLException e) {
        throw new FlywaySqlException("Unable to commit transaction", e);
    } catch (Exception e) {
        Savepoint savepoint = null;
        RuntimeException rethrow;
        if (e instanceof RollbackWithSavepointException) {
            savepoint = ((RollbackWithSavepointException) e).getSavepoint();
            rethrow = (RuntimeException) e.getCause();
        } else {
            if (e instanceof RuntimeException) {
                rethrow = (RuntimeException) e;
            } else {
                rethrow = new FlywayException(e);
            }
        }
        if (rollbackOnException) {
            try {
                LOG.debug("Rolling back transaction...");
                if (savepoint == null) {
                    connection.rollback();
                } else {
                    connection.rollback(savepoint);
                }
                LOG.debug("Transaction rolled back");
            } catch (SQLException se) {
                LOG.error("Unable to rollback transaction", se);
            }
        } else {
            try {
                connection.commit();
            } catch (SQLException se) {
                LOG.error("Unable to commit transaction", se);
            }
        }
        throw rethrow;
    } finally {
        try {
            connection.setAutoCommit(oldAutocommit);
        } catch (SQLException e) {
            LOG.error("Unable to restore autocommit to original value for connection", e);
        }
    }
}
Also used : FlywayException(org.flywaydb.core.api.FlywayException) FlywaySqlException(org.flywaydb.core.internal.dbsupport.FlywaySqlException) SQLException(java.sql.SQLException) Savepoint(java.sql.Savepoint) SQLException(java.sql.SQLException) FlywayException(org.flywaydb.core.api.FlywayException) FlywaySqlException(org.flywaydb.core.internal.dbsupport.FlywaySqlException)

Example 2 with FlywaySqlException

use of org.flywaydb.core.internal.dbsupport.FlywaySqlException in project flyway by flyway.

the class DbMigrate method applyMigration.

/**
     * Applies this migration to the database. The migration state and the execution time are updated accordingly.
     *
     * @param migration    The migration to apply.
     * @param isOutOfOrder If this migration is being applied out of order.
     * @return The result of the migration.
     */
private Boolean applyMigration(final MigrationInfoImpl migration, boolean isOutOfOrder) {
    MigrationVersion version = migration.getVersion();
    final MigrationExecutor migrationExecutor = migration.getResolvedMigration().getExecutor();
    final String migrationText;
    if (version != null) {
        migrationText = "schema " + schema + " to version " + version + " - " + migration.getDescription() + (isOutOfOrder ? " [out of order]" : "") + (migrationExecutor.executeInTransaction() ? "" : " [non-transactional]");
    } else {
        migrationText = "schema " + schema + " with repeatable migration " + migration.getDescription() + (migrationExecutor.executeInTransaction() ? "" : " [non-transactional]");
    }
    LOG.info("Migrating " + migrationText);
    StopWatch stopWatch = new StopWatch();
    stopWatch.start();
    try {
        if (migrationExecutor.executeInTransaction()) {
            new TransactionTemplate(connectionUserObjects).execute(new Callable<Object>() {

                @Override
                public Object call() throws SQLException {
                    doMigrate(migration, migrationExecutor, migrationText);
                    return null;
                }
            });
        } else {
            try {
                doMigrate(migration, migrationExecutor, migrationText);
            } catch (SQLException e) {
                throw new FlywaySqlException("Unable to apply migration", e);
            }
        }
    } catch (FlywayException e) {
        String failedMsg = "Migration of " + migrationText + " failed!";
        if (dbSupport.supportsDdlTransactions() && migrationExecutor.executeInTransaction()) {
            LOG.error(failedMsg + " Changes successfully rolled back.");
        } else {
            LOG.error(failedMsg + " Please restore backups and roll back database and code!");
            stopWatch.stop();
            int executionTime = (int) stopWatch.getTotalTimeMillis();
            AppliedMigration appliedMigration = new AppliedMigration(version, migration.getDescription(), migration.getType(), migration.getScript(), migration.getResolvedMigration().getChecksum(), executionTime, false);
            metaDataTable.addAppliedMigration(appliedMigration);
        }
        throw e;
    }
    stopWatch.stop();
    int executionTime = (int) stopWatch.getTotalTimeMillis();
    AppliedMigration appliedMigration = new AppliedMigration(version, migration.getDescription(), migration.getType(), migration.getScript(), migration.getResolvedMigration().getChecksum(), executionTime, true);
    metaDataTable.addAppliedMigration(appliedMigration);
    return false;
}
Also used : FlywayException(org.flywaydb.core.api.FlywayException) FlywaySqlException(org.flywaydb.core.internal.dbsupport.FlywaySqlException) SQLException(java.sql.SQLException) MigrationExecutor(org.flywaydb.core.api.resolver.MigrationExecutor) TransactionTemplate(org.flywaydb.core.internal.util.jdbc.TransactionTemplate) StopWatch(org.flywaydb.core.internal.util.StopWatch) MigrationVersion(org.flywaydb.core.api.MigrationVersion) AppliedMigration(org.flywaydb.core.internal.metadatatable.AppliedMigration)

Example 3 with FlywaySqlException

use of org.flywaydb.core.internal.dbsupport.FlywaySqlException in project flyway by flyway.

the class MetaDataTableImpl method update.

@Override
public void update(MigrationVersion version, String description, Integer checksum) {
    clearCache();
    LOG.info("Repairing metadata for version " + version + " (Description: " + description + ", Checksum: " + checksum + ")  ...");
    // Try load an update.sql file if it exists
    String resourceName = "org/flywaydb/core/internal/dbsupport/" + dbSupport.getDbName() + "/update.sql";
    ClassPathResource resource = new ClassPathResource(resourceName, getClass().getClassLoader());
    if (resource.exists()) {
        String source = resource.loadAsString("UTF-8");
        Map<String, String> placeholders = new HashMap<String, String>();
        // Placeholders for column names
        placeholders.put("schema", table.getSchema().getName());
        placeholders.put("table", table.getName());
        // Placeholders for column values
        placeholders.put("version_val", version.toString());
        placeholders.put("description_val", description);
        placeholders.put("checksum_val", String.valueOf(checksum));
        String sourceNoPlaceholders = new PlaceholderReplacer(placeholders, "${", "}").replacePlaceholders(source);
        new SqlScript(sourceNoPlaceholders, dbSupport).execute(jdbcTemplate);
    } else {
        try {
            jdbcTemplate.update("UPDATE " + table + " SET " + dbSupport.quote("description") + "='" + description + "' , " + dbSupport.quote("checksum") + "=" + checksum + " WHERE " + dbSupport.quote("version") + "='" + version + "'");
        } catch (SQLException e) {
            throw new FlywaySqlException("Unable to repair metadata table " + table + " for version " + version, e);
        }
    }
}
Also used : FlywaySqlException(org.flywaydb.core.internal.dbsupport.FlywaySqlException) HashMap(java.util.HashMap) SQLException(java.sql.SQLException) PlaceholderReplacer(org.flywaydb.core.internal.util.PlaceholderReplacer) SqlScript(org.flywaydb.core.internal.dbsupport.SqlScript) ClassPathResource(org.flywaydb.core.internal.util.scanner.classpath.ClassPathResource)

Example 4 with FlywaySqlException

use of org.flywaydb.core.internal.dbsupport.FlywaySqlException in project flyway by flyway.

the class MetaDataTableImpl method addAppliedMigration.

@Override
public void addAppliedMigration(AppliedMigration appliedMigration) {
    dbSupport.changeCurrentSchemaTo(table.getSchema());
    createIfNotExists();
    MigrationVersion version = appliedMigration.getVersion();
    try {
        String versionStr = version == null ? null : version.toString();
        // Try load an updateMetaDataTable.sql file if it exists
        String resourceName = "org/flywaydb/core/internal/dbsupport/" + dbSupport.getDbName() + "/updateMetaDataTable.sql";
        ClassPathResource classPathResource = new ClassPathResource(resourceName, getClass().getClassLoader());
        int installedRank = calculateInstalledRank();
        if (classPathResource.exists()) {
            String source = classPathResource.loadAsString("UTF-8");
            Map<String, String> placeholders = new HashMap<String, String>();
            // Placeholders for schema and table
            placeholders.put("schema", table.getSchema().getName());
            placeholders.put("table", table.getName());
            // Placeholders for column values
            placeholders.put("installed_rank_val", String.valueOf(installedRank));
            placeholders.put("version_val", versionStr);
            placeholders.put("description_val", appliedMigration.getDescription());
            placeholders.put("type_val", appliedMigration.getType().name());
            placeholders.put("script_val", appliedMigration.getScript());
            placeholders.put("checksum_val", String.valueOf(appliedMigration.getChecksum()));
            placeholders.put("installed_by_val", installedBy);
            placeholders.put("execution_time_val", String.valueOf(appliedMigration.getExecutionTime() * 1000L));
            placeholders.put("success_val", String.valueOf(appliedMigration.isSuccess()));
            String sourceNoPlaceholders = new PlaceholderReplacer(placeholders, "${", "}").replacePlaceholders(source);
            SqlScript sqlScript = new SqlScript(sourceNoPlaceholders, dbSupport);
            sqlScript.execute(jdbcTemplate);
        } else {
            // Fall back to hard-coded statements
            jdbcTemplate.update("INSERT INTO " + table + " (" + dbSupport.quote("installed_rank") + "," + dbSupport.quote("version") + "," + dbSupport.quote("description") + "," + dbSupport.quote("type") + "," + dbSupport.quote("script") + "," + dbSupport.quote("checksum") + "," + dbSupport.quote("installed_by") + "," + dbSupport.quote("execution_time") + "," + dbSupport.quote("success") + ")" + " VALUES (?, ?, ?, ?, ?, ?, " + installedBy + ", ?, ?)", installedRank, versionStr, appliedMigration.getDescription(), appliedMigration.getType().name(), appliedMigration.getScript(), appliedMigration.getChecksum(), appliedMigration.getExecutionTime(), appliedMigration.isSuccess());
        }
        LOG.debug("MetaData table " + table + " successfully updated to reflect changes");
    } catch (SQLException e) {
        throw new FlywaySqlException("Unable to insert row for version '" + version + "' in metadata table " + table, e);
    }
}
Also used : FlywaySqlException(org.flywaydb.core.internal.dbsupport.FlywaySqlException) MigrationVersion(org.flywaydb.core.api.MigrationVersion) HashMap(java.util.HashMap) SQLException(java.sql.SQLException) PlaceholderReplacer(org.flywaydb.core.internal.util.PlaceholderReplacer) SqlScript(org.flywaydb.core.internal.dbsupport.SqlScript) ClassPathResource(org.flywaydb.core.internal.util.scanner.classpath.ClassPathResource)

Example 5 with FlywaySqlException

use of org.flywaydb.core.internal.dbsupport.FlywaySqlException in project flyway by flyway.

the class MetaDataTableImpl method findAppliedMigrations.

/**
     * Retrieve the applied migrations from the metadata table.
     *
     * @param migrationTypes The specific migration types to look for. (Optional) None means find all migrations.
     * @return The applied migrations.
     */
private List<AppliedMigration> findAppliedMigrations(MigrationType... migrationTypes) {
    if (!table.exists()) {
        return new ArrayList<AppliedMigration>();
    }
    createIfNotExists();
    int minInstalledRank = cache.isEmpty() ? -1 : cache.getLast().getInstalledRank();
    String query = "SELECT " + dbSupport.quote("installed_rank") + "," + dbSupport.quote("version") + "," + dbSupport.quote("description") + "," + dbSupport.quote("type") + "," + dbSupport.quote("script") + "," + dbSupport.quote("checksum") + "," + dbSupport.quote("installed_on") + "," + dbSupport.quote("installed_by") + "," + dbSupport.quote("execution_time") + "," + dbSupport.quote("success") + " FROM " + table + " WHERE " + dbSupport.quote("installed_rank") + " > " + minInstalledRank;
    if (migrationTypes.length > 0) {
        query += " AND " + dbSupport.quote("type") + " IN (";
        for (int i = 0; i < migrationTypes.length; i++) {
            if (i > 0) {
                query += ",";
            }
            query += "'" + migrationTypes[i] + "'";
        }
        query += ")";
    }
    query += " ORDER BY " + dbSupport.quote("installed_rank");
    try {
        cache.addAll(jdbcTemplate.query(query, new RowMapper<AppliedMigration>() {

            public AppliedMigration mapRow(final ResultSet rs) throws SQLException {
                Integer checksum = rs.getInt("checksum");
                if (rs.wasNull()) {
                    checksum = null;
                }
                return new AppliedMigration(rs.getInt("installed_rank"), rs.getString("version") != null ? MigrationVersion.fromVersion(rs.getString("version")) : null, rs.getString("description"), MigrationType.valueOf(rs.getString("type")), rs.getString("script"), checksum, rs.getTimestamp("installed_on"), rs.getString("installed_by"), rs.getInt("execution_time"), rs.getBoolean("success"));
            }
        }));
        return cache;
    } catch (SQLException e) {
        throw new FlywaySqlException("Error while retrieving the list of applied migrations from metadata table " + table, e);
    }
}
Also used : FlywaySqlException(org.flywaydb.core.internal.dbsupport.FlywaySqlException) SQLException(java.sql.SQLException) ArrayList(java.util.ArrayList) ResultSet(java.sql.ResultSet) RowMapper(org.flywaydb.core.internal.util.jdbc.RowMapper)

Aggregations

SQLException (java.sql.SQLException)6 FlywaySqlException (org.flywaydb.core.internal.dbsupport.FlywaySqlException)6 HashMap (java.util.HashMap)2 FlywayException (org.flywaydb.core.api.FlywayException)2 MigrationVersion (org.flywaydb.core.api.MigrationVersion)2 SqlScript (org.flywaydb.core.internal.dbsupport.SqlScript)2 PlaceholderReplacer (org.flywaydb.core.internal.util.PlaceholderReplacer)2 ClassPathResource (org.flywaydb.core.internal.util.scanner.classpath.ClassPathResource)2 Connection (java.sql.Connection)1 ResultSet (java.sql.ResultSet)1 Savepoint (java.sql.Savepoint)1 Statement (java.sql.Statement)1 ArrayList (java.util.ArrayList)1 Properties (java.util.Properties)1 MigrationExecutor (org.flywaydb.core.api.resolver.MigrationExecutor)1 AppliedMigration (org.flywaydb.core.internal.metadatatable.AppliedMigration)1 StopWatch (org.flywaydb.core.internal.util.StopWatch)1 RowMapper (org.flywaydb.core.internal.util.jdbc.RowMapper)1 TransactionTemplate (org.flywaydb.core.internal.util.jdbc.TransactionTemplate)1