Search in sources :

Example 86 with DatabaseException

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

the class MigrateConceptReferenceTermChangeSet method execute.

/**
 * @see liquibase.change.custom.CustomTaskChange#execute(liquibase.database.Database)
 */
@Override
public void execute(Database database) throws CustomChangeException {
    final JdbcConnection connection = (JdbcConnection) database.getConnection();
    Boolean prevAutoCommit = null;
    PreparedStatement selectTypes = null;
    PreparedStatement batchUpdateMap = null;
    PreparedStatement selectMap = null;
    PreparedStatement updateMapTerm = null;
    PreparedStatement insertTerm = null;
    PreparedStatement updateMapType = null;
    try {
        prevAutoCommit = connection.getAutoCommit();
        connection.setAutoCommit(false);
        // Prepare a list of types and their ids.
        Map<String, Integer> typesToIds = new HashMap<>();
        selectTypes = connection.prepareStatement("select * from concept_map_type");
        selectTypes.execute();
        ResultSet selectTypeResult = selectTypes.getResultSet();
        while (selectTypeResult.next()) {
            typesToIds.put(selectTypeResult.getString("name").trim().toUpperCase(), selectTypeResult.getInt("concept_map_type_id"));
        }
        selectTypes.close();
        // The FK on concept_reference_term_id is not yet created so we are safe to copy over IDs.
        // The trims are done to be able to compare properly.
        batchUpdateMap = connection.prepareStatement("update concept_reference_map set" + " concept_reference_term_id = concept_map_id," + " source_code = trim(source_code), comment = trim(comment)");
        batchUpdateMap.execute();
        batchUpdateMap.close();
        // Preparing statements for use in the loop.
        updateMapTerm = connection.prepareStatement("update concept_reference_map set" + " concept_reference_term_id = ? where concept_map_id = ?");
        insertTerm = connection.prepareStatement("insert into concept_reference_term" + " (concept_reference_term_id, uuid, concept_source_id, code, creator, date_created, description)" + " values (?, ?, ?, ?, ?, ?, ?)");
        updateMapType = connection.prepareStatement("update concept_reference_map set" + " concept_map_type_id = ? where concept_map_id = ?");
        int prevSource = -1;
        String prevSourceCode = null;
        String prevComment = null;
        int prevInsertedTerm = -1;
        // In addition to source and source_code we order by UUID to always insert the same term if run on different systems.
        selectMap = connection.prepareStatement("select * from concept_reference_map" + " order by source, source_code, uuid");
        selectMap.execute();
        final ResultSet selectMapResult = selectMap.getResultSet();
        while (selectMapResult.next()) {
            final int conceptMapId = selectMapResult.getInt("concept_map_id");
            final int source = selectMapResult.getInt("source");
            final String sourceCode = selectMapResult.getString("source_code");
            final String comment = selectMapResult.getString("comment");
            final int creator = selectMapResult.getInt("creator");
            final Date dateCreated = selectMapResult.getDate("date_created");
            final String uuid = selectMapResult.getString("uuid");
            final Integer mapTypeId = determineMapTypeId(comment, typesToIds);
            final int updatedMapTypeId = (mapTypeId == null) ? typesToIds.get(DEFAULT_CONCEPT_MAP_TYPE) : mapTypeId;
            updateMapType.setInt(1, updatedMapTypeId);
            updateMapType.setInt(2, conceptMapId);
            updateMapType.execute();
            if (updateMapType.getUpdateCount() != 1) {
                throw new CustomChangeException("Failed to set map type: " + mapTypeId + " for map: " + conceptMapId + ", updated rows: " + updateMapType.getUpdateCount());
            }
            if (source == prevSource && (sourceCode == prevSourceCode || (sourceCode != null && sourceCode.equals(prevSourceCode)))) {
                if (mapTypeId == null && comment != null && !comment.equals(prevComment)) {
                    log.warn("Lost comment '" + comment + "' for map " + conceptMapId + ". Preserved comment " + prevComment);
                }
                // We need to use the last inserted term.
                updateMapTerm.setInt(1, prevInsertedTerm);
                updateMapTerm.setInt(2, conceptMapId);
                updateMapTerm.execute();
                if (updateMapTerm.getUpdateCount() != 1) {
                    throw new CustomChangeException("Failed to set reference term: " + prevInsertedTerm + " for map: " + conceptMapId + ", updated rows: " + updateMapTerm.getUpdateCount());
                }
            } else {
                insertTerm.setInt(1, conceptMapId);
                // We need to guaranty that UUIDs are always the same when run on different systems.
                insertTerm.setString(2, UUID.nameUUIDFromBytes(uuid.getBytes(StandardCharsets.UTF_8)).toString());
                insertTerm.setInt(3, source);
                insertTerm.setString(4, sourceCode);
                insertTerm.setInt(5, creator);
                insertTerm.setDate(6, dateCreated);
                if (mapTypeId == null) {
                    insertTerm.setString(7, comment);
                } else {
                    insertTerm.setString(7, null);
                }
                insertTerm.execute();
                prevInsertedTerm = conceptMapId;
            }
            prevSource = source;
            prevSourceCode = sourceCode;
            prevComment = comment;
        }
        selectMap.close();
        updateMapType.close();
        updateMapTerm.close();
        insertTerm.close();
        connection.commit();
    } catch (Exception e) {
        try {
            if (connection != null) {
                connection.rollback();
            }
        } catch (Exception ex) {
            log.error("Failed to rollback", ex);
        }
        throw new CustomChangeException(e);
    } finally {
        closeStatementQuietly(selectTypes);
        closeStatementQuietly(batchUpdateMap);
        closeStatementQuietly(selectMap);
        closeStatementQuietly(updateMapTerm);
        closeStatementQuietly(insertTerm);
        closeStatementQuietly(updateMapType);
        if (connection != null && prevAutoCommit != null) {
            try {
                connection.setAutoCommit(prevAutoCommit);
            } catch (DatabaseException e) {
                log.error("Failed to reset auto commit", e);
            }
        }
    }
}
Also used : HashMap(java.util.HashMap) CustomChangeException(liquibase.exception.CustomChangeException) JdbcConnection(liquibase.database.jvm.JdbcConnection) PreparedStatement(java.sql.PreparedStatement) Date(java.sql.Date) DatabaseException(liquibase.exception.DatabaseException) CustomChangeException(liquibase.exception.CustomChangeException) SetupException(liquibase.exception.SetupException) SQLException(java.sql.SQLException) ResultSet(java.sql.ResultSet) DatabaseException(liquibase.exception.DatabaseException)

Example 87 with DatabaseException

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

the class MigrateDrugOrderUnitsToCodedDoseUnitsChangeset method migrateUnitsToCodedValue.

private void migrateUnitsToCodedValue(JdbcConnection connection, Set<String> uniqueUnits) throws CustomChangeException, SQLException, DatabaseException {
    PreparedStatement updateDrugOrderStatement = null;
    Boolean autoCommit = null;
    try {
        autoCommit = connection.getAutoCommit();
        connection.setAutoCommit(false);
        updateDrugOrderStatement = connection.prepareStatement("update drug_order set dose_units = ? where units = ?");
        updateDrugOrderStatement.setNull(1, Types.INTEGER);
        updateDrugOrderStatement.setNull(2, Types.VARCHAR);
        updateDrugOrderStatement.executeUpdate();
        updateDrugOrderStatement.clearParameters();
        for (String unit : uniqueUnits) {
            if (StringUtils.isBlank(unit)) {
                updateDrugOrderStatement.setNull(1, Types.INTEGER);
            } else {
                Integer conceptIdForUnit = UpgradeUtil.getConceptIdForUnits(unit);
                if (conceptIdForUnit == null) {
                    throw new CustomChangeException("No concept mapping found for unit: " + unit);
                }
                String dosingUnitsConceptSetUuid = UpgradeUtil.getGlobalProperty(connection.getUnderlyingConnection(), OpenmrsConstants.GP_DRUG_DOSING_UNITS_CONCEPT_UUID);
                List<Integer> dosingUnitsconceptIds = UpgradeUtil.getMemberSetIds(connection.getUnderlyingConnection(), dosingUnitsConceptSetUuid);
                if (!dosingUnitsconceptIds.contains(conceptIdForUnit)) {
                    throw new CustomChangeException("Dosing unit '" + unit + "' is not among valid concepts defined in global property " + OpenmrsConstants.GP_DRUG_DOSING_UNITS_CONCEPT_UUID);
                }
                updateDrugOrderStatement.setInt(1, conceptIdForUnit);
            }
            updateDrugOrderStatement.setString(2, unit);
            updateDrugOrderStatement.executeUpdate();
            updateDrugOrderStatement.clearParameters();
        }
        connection.commit();
    } catch (DatabaseException | SQLException e) {
        handleError(connection, e);
    } finally {
        if (autoCommit != null) {
            connection.setAutoCommit(autoCommit);
        }
        if (updateDrugOrderStatement != null) {
            updateDrugOrderStatement.close();
        }
    }
}
Also used : SQLException(java.sql.SQLException) CustomChangeException(liquibase.exception.CustomChangeException) PreparedStatement(java.sql.PreparedStatement) DatabaseException(liquibase.exception.DatabaseException)

Example 88 with DatabaseException

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

the class UpdateCohortMemberIdsChangeset method execute.

/**
 * @see CustomTaskChange#execute(Database)
 */
@Override
public void execute(Database database) throws CustomChangeException {
    JdbcConnection connection = (JdbcConnection) database.getConnection();
    Statement stmt = null;
    PreparedStatement pStmt = null;
    try {
        stmt = connection.createStatement();
        ResultSet rs = stmt.executeQuery("SELECT * FROM cohort_member");
        pStmt = connection.prepareStatement("UPDATE cohort_member SET cohort_member_id = ?" + " WHERE cohort_id = ? AND patient_id = ?");
        int i = 0;
        while (rs.next()) {
            int cohortId = rs.getInt("cohort_id");
            int patientId = rs.getInt("patient_id");
            pStmt.setInt(1, ++i);
            pStmt.setInt(2, cohortId);
            pStmt.setInt(3, patientId);
            pStmt.addBatch();
        }
        pStmt.executeBatch();
    } catch (DatabaseException | SQLException e) {
        log.warn("Error generated", e);
    } finally {
        if (stmt != null) {
            try {
                stmt.close();
            } catch (SQLException e) {
                log.warn("Failed to close the statement object");
            }
        }
        if (pStmt != null) {
            try {
                pStmt.close();
            } catch (SQLException e) {
                log.warn("Failed to close the prepared statement object");
            }
        }
    }
}
Also used : SQLException(java.sql.SQLException) PreparedStatement(java.sql.PreparedStatement) Statement(java.sql.Statement) ResultSet(java.sql.ResultSet) JdbcConnection(liquibase.database.jvm.JdbcConnection) PreparedStatement(java.sql.PreparedStatement) DatabaseException(liquibase.exception.DatabaseException)

Example 89 with DatabaseException

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

the class EncryptSecretAnswersChangeSet method execute.

/**
 * @see CustomTaskChange#execute(Database)
 */
@Override
public void execute(Database database) throws CustomChangeException {
    JdbcConnection connection = (JdbcConnection) database.getConnection();
    Statement stmt = null;
    PreparedStatement pStmt = null;
    try {
        stmt = connection.createStatement();
        ResultSet rs = stmt.executeQuery("SELECT user_id, salt, secret_answer FROM users WHERE secret_answer IS NOT NULL");
        pStmt = connection.prepareStatement("UPDATE users SET secret_answer = ? WHERE user_id = ?");
        while (rs.next()) {
            String answer = rs.getString("secret_answer");
            String salt = rs.getString("salt");
            String encryptedAnswer = Security.encodeString(answer.toLowerCase() + salt);
            pStmt.setString(1, encryptedAnswer);
            pStmt.setInt(2, rs.getInt("user_id"));
            pStmt.addBatch();
        }
        pStmt.executeBatch();
    } catch (DatabaseException | SQLException e) {
        throw new CustomChangeException("Failed to update secret answers: " + e);
    } finally {
        if (stmt != null) {
            try {
                stmt.close();
            } catch (SQLException e) {
                log.warn("Failed to close the statement object");
            }
        }
        if (pStmt != null) {
            try {
                pStmt.close();
            } catch (SQLException e) {
                log.warn("Failed to close the prepared statement object");
            }
        }
    }
}
Also used : SQLException(java.sql.SQLException) PreparedStatement(java.sql.PreparedStatement) Statement(java.sql.Statement) ResultSet(java.sql.ResultSet) CustomChangeException(liquibase.exception.CustomChangeException) JdbcConnection(liquibase.database.jvm.JdbcConnection) PreparedStatement(java.sql.PreparedStatement) DatabaseException(liquibase.exception.DatabaseException)

Example 90 with DatabaseException

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

the class FixDuplicatePoolsTask method getSubPoolMap.

/*
     * Builds a map of subid-subkey -> [ids, with, duplicates]
     */
private Map<SubPair, List<String>> getSubPoolMap() throws SQLException, DatabaseException {
    Statement stmt = connection.createStatement();
    Map<SubPair, List<String>> subPoolsMap = new HashMap<>();
    ResultSet rs = stmt.executeQuery("SELECT cp_pool.id, cp_pool.subscriptionid, " + "cp_pool.subscriptionsubkey, cp_pool.owner_id " + "FROM cp_pool, " + "(SELECT subscriptionid, subscriptionsubkey " + "FROM cp_pool " + "WHERE subscriptionid IS NOT NULL " + "AND subscriptionsubkey IS NOT NULL " + "GROUP BY subscriptionid, subscriptionsubkey " + "HAVING count(id) > 1) subs " + "WHERE subs.subscriptionid = cp_pool.subscriptionid " + "AND subs.subscriptionsubkey = cp_pool.subscriptionsubkey");
    // We need to be completely sure that we aren't moving subscriptions
    // from one owner to another.
    Map<SubPair, String> subOwners = new HashMap<>();
    while (rs.next()) {
        SubPair current = new SubPair(rs.getString(2), rs.getString(3));
        if (!subPoolsMap.containsKey(current)) {
            subPoolsMap.put(current, new LinkedList<>());
            subOwners.put(current, rs.getString(4));
        } else if (!subOwners.get(current).equals(rs.getString(4))) {
            // Make sure owners are the same
            logger.error(String.format("Owners '%s' and '%s' both have pools from subscription: %s", rs.getString(4), subOwners.get(current), current));
            throw new DatabaseException("Pools exist for subscription " + current + " within multiple " + "owners.");
        }
        subPoolsMap.get(current).add(rs.getString(1));
    }
    rs.close();
    return subPoolsMap;
}
Also used : HashMap(java.util.HashMap) Statement(java.sql.Statement) PreparedStatement(java.sql.PreparedStatement) ResultSet(java.sql.ResultSet) List(java.util.List) LinkedList(java.util.LinkedList) DatabaseException(liquibase.exception.DatabaseException)

Aggregations

DatabaseException (liquibase.exception.DatabaseException)139 SQLException (java.sql.SQLException)65 JdbcConnection (liquibase.database.jvm.JdbcConnection)34 PreparedStatement (java.sql.PreparedStatement)33 ResultSet (java.sql.ResultSet)28 Statement (java.sql.Statement)24 Database (liquibase.database.Database)24 UnexpectedLiquibaseException (liquibase.exception.UnexpectedLiquibaseException)24 CustomChangeException (liquibase.exception.CustomChangeException)22 CatalogAndSchema (liquibase.CatalogAndSchema)17 LiquibaseException (liquibase.exception.LiquibaseException)16 AbstractJdbcDatabase (liquibase.database.AbstractJdbcDatabase)14 InvalidExampleException (liquibase.snapshot.InvalidExampleException)14 RawSqlStatement (liquibase.statement.core.RawSqlStatement)14 MSSQLDatabase (liquibase.database.core.MSSQLDatabase)13 CachedRow (liquibase.snapshot.CachedRow)13 SqlStatement (liquibase.statement.SqlStatement)13 DatabaseConnection (liquibase.database.DatabaseConnection)12 JdbcDatabaseSnapshot (liquibase.snapshot.JdbcDatabaseSnapshot)12 ArrayList (java.util.ArrayList)11