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);
}
}
}
}
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();
}
}
}
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");
}
}
}
}
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");
}
}
}
}
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;
}
Aggregations