Search in sources :

Example 16 with CustomChangeException

use of liquibase.exception.CustomChangeException in project openmrs-core by openmrs.

the class BooleanConceptChangeSet method getInt.

/**
 * returns an integer resulting from the execution of an sql statement
 *
 * @param connection a DatabaseConnection
 * @param sql the sql statement to execute
 * @return integer resulting from the execution of the sql statement
 * @throws CustomChangeException
 */
private Integer getInt(JdbcConnection connection, String sql) throws CustomChangeException {
    Statement stmt = null;
    try {
        stmt = connection.createStatement();
        ResultSet rs = stmt.executeQuery(sql);
        Integer result = null;
        if (rs.next()) {
            result = rs.getInt(1);
        } else {
            // this is okay, we just return null in this case
            log.debug("Query returned no results: " + sql);
        }
        if (rs.next()) {
            log.warn("Query returned multiple results when we expected just one: " + sql);
        }
        return result;
    } catch (DatabaseException | SQLException e) {
        throw new CustomChangeException("Unable to get int", e);
    } finally {
        if (stmt != null) {
            try {
                stmt.close();
            } catch (SQLException e) {
            }
        }
    }
}
Also used : SQLException(java.sql.SQLException) PreparedStatement(java.sql.PreparedStatement) Statement(java.sql.Statement) ResultSet(java.sql.ResultSet) CustomChangeException(liquibase.exception.CustomChangeException) DatabaseException(liquibase.exception.DatabaseException)

Example 17 with CustomChangeException

use of liquibase.exception.CustomChangeException in project openmrs-core by openmrs.

the class DuplicateEncounterTypeNameChangeSet method execute.

/**
 * Method to perform validation and resolution of duplicate EncounterType names
 */
@Override
public void execute(Database database) throws CustomChangeException {
    JdbcConnection connection = (JdbcConnection) database.getConnection();
    Map<String, HashSet<Integer>> duplicates = new HashMap<>();
    Statement stmt = null;
    PreparedStatement pStmt = null;
    ResultSet rs = null;
    Boolean initialAutoCommit = null;
    try {
        initialAutoCommit = connection.getAutoCommit();
        // set auto commit mode to false for UPDATE action
        connection.setAutoCommit(false);
        stmt = connection.createStatement();
        rs = stmt.executeQuery("SELECT * FROM encounter_type INNER JOIN (SELECT name FROM encounter_type GROUP BY name HAVING count(name) > 1) dup ON encounter_type.name = dup.name");
        Integer id;
        String name;
        while (rs.next()) {
            id = rs.getInt("encounter_type_id");
            name = rs.getString("name");
            if (duplicates.get(name) == null) {
                HashSet<Integer> results = new HashSet<>();
                results.add(id);
                duplicates.put(name, results);
            } else {
                HashSet<Integer> results = duplicates.get(name);
                results.add(id);
            }
        }
        for (Object o : duplicates.entrySet()) {
            Map.Entry pairs = (Map.Entry) o;
            HashSet values = (HashSet) pairs.getValue();
            List<Integer> ids = new ArrayList<Integer>(values);
            int duplicateNameId = 1;
            for (int i = 1; i < ids.size(); i++) {
                String newName = pairs.getKey() + "_" + duplicateNameId;
                List<List<Object>> duplicateResult;
                boolean duplicateName;
                Connection con = DatabaseUpdater.getConnection();
                do {
                    String sqlValidatorString = "select * from encounter_type where name = '" + newName + "'";
                    duplicateResult = DatabaseUtil.executeSQL(con, sqlValidatorString, true);
                    if (!duplicateResult.isEmpty()) {
                        duplicateNameId += 1;
                        newName = pairs.getKey() + "_" + duplicateNameId;
                        duplicateName = true;
                    } else {
                        duplicateName = false;
                    }
                } while (duplicateName);
                pStmt = connection.prepareStatement("update encounter_type set name = ? where encounter_type_id = ?");
                pStmt.setString(1, newName);
                pStmt.setInt(2, ids.get(i));
                duplicateNameId += 1;
                pStmt.executeUpdate();
            }
        }
    } catch (BatchUpdateException e) {
        log.warn("Error generated while processsing batch insert", e);
        try {
            log.debug("Rolling back batch", e);
            connection.rollback();
        } catch (Exception rbe) {
            log.warn("Error generated while rolling back batch insert", e);
        }
        // marks the changeset as a failed one
        throw new CustomChangeException("Failed to update one or more duplicate EncounterType names", e);
    } catch (Exception e) {
        throw new CustomChangeException(e);
    } finally {
        // set auto commit to its initial state
        try {
            if (initialAutoCommit != null) {
                connection.setAutoCommit(initialAutoCommit);
            }
        } catch (DatabaseException e) {
            log.warn("Failed to set auto commit to ids initial state", e);
        }
        if (rs != null) {
            try {
                rs.close();
            } catch (SQLException e) {
                log.warn("Failed to close the resultset object");
            }
        }
        if (stmt != null) {
            try {
                stmt.close();
            } catch (SQLException e) {
                log.warn("Failed to close the select statement used to identify duplicate EncounterType object names");
            }
        }
        if (pStmt != null) {
            try {
                pStmt.close();
            } catch (SQLException e) {
                log.warn("Failed to close the prepared statement used to update duplicate EncounterType object names");
            }
        }
    }
}
Also used : HashMap(java.util.HashMap) SQLException(java.sql.SQLException) ArrayList(java.util.ArrayList) CustomChangeException(liquibase.exception.CustomChangeException) JdbcConnection(liquibase.database.jvm.JdbcConnection) ResultSet(java.sql.ResultSet) ArrayList(java.util.ArrayList) List(java.util.List) HashSet(java.util.HashSet) BatchUpdateException(java.sql.BatchUpdateException) PreparedStatement(java.sql.PreparedStatement) Statement(java.sql.Statement) Connection(java.sql.Connection) JdbcConnection(liquibase.database.jvm.JdbcConnection) PreparedStatement(java.sql.PreparedStatement) BatchUpdateException(java.sql.BatchUpdateException) DatabaseException(liquibase.exception.DatabaseException) CustomChangeException(liquibase.exception.CustomChangeException) SetupException(liquibase.exception.SetupException) SQLException(java.sql.SQLException) HashMap(java.util.HashMap) Map(java.util.Map) DatabaseException(liquibase.exception.DatabaseException)

Example 18 with CustomChangeException

use of liquibase.exception.CustomChangeException in project openmrs-core by openmrs.

the class GenerateUuid method execute.

/**
 * Adds UUIDs to all rows for the specified tables. It generates UUIDs using Java and updates one row at a time, thus
 * it is not very efficient. When running on the MySQL database, we generate SQL statements using the uuid MySQL function,
 * which is much faster.
 *
 * @see liquibase.change.custom.CustomTaskChange#execute(liquibase.database.Database)
 */
@Override
public void execute(Database database) throws CustomChangeException {
    JdbcConnection connection = (JdbcConnection) database.getConnection();
    boolean initialAutoCommit = true;
    try {
        initialAutoCommit = connection.getAutoCommit();
        connection.setAutoCommit(false);
        if ("mysql".equals(database.getTypeName())) {
            String updateSql = "update %s set " + columnName + " = uuid() where " + columnName + " is null";
            for (String tablename : tableNamesArray) {
                String rawSql = String.format(updateSql, tablename);
                Statement statement = null;
                try {
                    statement = connection.createStatement();
                    statement.execute(rawSql);
                    statement.close();
                    connection.commit();
                } catch (SQLException e) {
                    throw new CustomChangeException(e);
                } finally {
                    if (statement != null) {
                        try {
                            statement.close();
                        } catch (SQLException e) {
                            log.warn("Failed to close the statement", e);
                        }
                    }
                }
            }
        } else {
            int transactionBatchSize = 0;
            // loop over all tables
            for (String tableName : tableNamesArray) {
                try {
                    Statement idStatement = null;
                    PreparedStatement updateStatement = null;
                    try {
                        String idSql = genericIdSql.replaceAll("tablename", tableName);
                        String updateSql = genericUpdateSql.replaceAll("tablename", tableName);
                        // hacky way to deal with tables that don't follow the tableNam_id convention
                        for (Map.Entry<String, String> idException : idExceptionsMap.entrySet()) {
                            idSql = idSql.replaceFirst(idException.getKey(), idException.getValue());
                            updateSql = updateSql.replaceFirst(idException.getKey(), idException.getValue());
                        }
                        idStatement = connection.createStatement();
                        updateStatement = connection.prepareStatement(updateSql);
                        ResultSet ids = idStatement.executeQuery(idSql);
                        while (ids.next()) {
                            // set the primary key number
                            updateStatement.setObject(2, ids.getObject(1));
                            // set the uuid for this row
                            updateStatement.setString(1, UUID.randomUUID().toString());
                            updateStatement.executeUpdate();
                            transactionBatchSize++;
                            if (transactionBatchSize > TRANSACTION_BATCH_SIZE_LIMIT) {
                                transactionBatchSize = 0;
                                connection.commit();
                            }
                        }
                        idStatement.close();
                        updateStatement.close();
                    } finally {
                        if (idStatement != null) {
                            try {
                                idStatement.close();
                            } catch (SQLException e) {
                                log.warn("Failed to close statement", e);
                            }
                        }
                        if (updateStatement != null) {
                            try {
                                updateStatement.close();
                            } catch (SQLException e) {
                                log.warn("Failed to close the statement", e);
                            }
                        }
                    }
                } catch (DatabaseException | SQLException e) {
                    throw new CustomChangeException("Unable to set uuid on table: " + tableName, e);
                }
            }
            connection.commit();
        }
        connection.setAutoCommit(initialAutoCommit);
    } catch (DatabaseException e) {
        throw new CustomChangeException(e);
    } finally {
        try {
            connection.setAutoCommit(initialAutoCommit);
        } catch (DatabaseException e) {
        // silently ignore so that the actual error is not hidden
        }
    }
}
Also used : SQLException(java.sql.SQLException) PreparedStatement(java.sql.PreparedStatement) Statement(java.sql.Statement) CustomChangeException(liquibase.exception.CustomChangeException) JdbcConnection(liquibase.database.jvm.JdbcConnection) PreparedStatement(java.sql.PreparedStatement) ResultSet(java.sql.ResultSet) Map(java.util.Map) DatabaseException(liquibase.exception.DatabaseException)

Example 19 with CustomChangeException

use of liquibase.exception.CustomChangeException in project candlepin by candlepin.

the class LiquibaseCustomTaskWrapper method execute.

@Override
public void execute(Database database) throws CustomChangeException {
    try {
        T task = this.typeClass.getConstructor(Database.class, CustomTaskLogger.class).newInstance(database, new LiquibaseCustomTaskLogger());
        task.execute();
    } catch (Exception e) {
        throw new CustomChangeException(e);
    }
}
Also used : Database(liquibase.database.Database) CustomChangeException(liquibase.exception.CustomChangeException) CustomChangeException(liquibase.exception.CustomChangeException) SetupException(liquibase.exception.SetupException)

Example 20 with CustomChangeException

use of liquibase.exception.CustomChangeException in project irida by phac-nml.

the class AbsoluteToRelativePaths method generateStatements.

@Override
public SqlStatement[] generateStatements(Database database) throws CustomChangeException {
    // for each type of directory and file-class, go through and strip out
    // the prefix in the database.
    // First check if the database paths match the configured paths
    ValidationErrors testRelativePaths = testRelativePaths();
    if (testRelativePaths.hasErrors()) {
        for (String error : testRelativePaths.getErrorMessages()) {
            logger.error(error);
        }
        throw new CustomChangeException("File locations did not validate.  Change cannot be applied.");
    }
    final String sequenceFileDirectoryPath = appendPathSeparator(this.sequenceFileDirectory.toString());
    final String referenceFileDirectoryPath = appendPathSeparator(this.referenceFileDirectory.toString());
    final String outputFileDirectoryPath = appendPathSeparator(this.outputFileDirectory.toString());
    return new SqlStatement[] { new RawSqlStatement(String.format("update sequence_file set file_path = replace(file_path, '%s', '')  WHERE file_path IS NOT NULL", sequenceFileDirectoryPath)), new RawSqlStatement(String.format("update sequence_file_AUD set file_path = replace(file_path, '%s', '') WHERE file_path IS NOT NULL", sequenceFileDirectoryPath)), new RawSqlStatement(String.format("update reference_file set filePath = replace(filePath, '%s', '') WHERE filePath IS NOT NULL", referenceFileDirectoryPath)), new RawSqlStatement(String.format("update reference_file_AUD set filePath = replace(filePath, '%s', '') WHERE filePath IS NOT NULL", referenceFileDirectoryPath)), new RawSqlStatement(String.format("update analysis_output_file set file_path = replace(file_path, '%s', '') WHERE file_path IS NOT NULL", outputFileDirectoryPath)) };
}
Also used : RawSqlStatement(liquibase.statement.core.RawSqlStatement) RawSqlStatement(liquibase.statement.core.RawSqlStatement) SqlStatement(liquibase.statement.SqlStatement) ValidationErrors(liquibase.exception.ValidationErrors) CustomChangeException(liquibase.exception.CustomChangeException)

Aggregations

CustomChangeException (liquibase.exception.CustomChangeException)46 PreparedStatement (java.sql.PreparedStatement)33 ResultSet (java.sql.ResultSet)26 DatabaseException (liquibase.exception.DatabaseException)26 SQLException (java.sql.SQLException)25 JdbcConnection (liquibase.database.jvm.JdbcConnection)21 SetupException (liquibase.exception.SetupException)16 Statement (java.sql.Statement)8 ArrayList (java.util.ArrayList)6 InsertStatement (liquibase.statement.core.InsertStatement)6 Table (liquibase.structure.core.Table)6 Date (java.sql.Date)5 HashMap (java.util.HashMap)5 Map (java.util.Map)5 BatchUpdateException (java.sql.BatchUpdateException)4 Connection (java.sql.Connection)4 HashSet (java.util.HashSet)4 List (java.util.List)4 UpdateStatement (liquibase.statement.core.UpdateStatement)4 SqlStatement (liquibase.statement.SqlStatement)3