/* * Generates rollback statements from the inverse changes returned by createInverses(). * Throws RollbackImpossibleException if the changes created by createInverses() is not supported for the passed database. * */ private SqlStatement[] generateRollbackStatementsFromInverse(Database database) throws RollbackImpossibleException { Change[] inverses = createInverses(); if (inverses == null) { throw new RollbackImpossibleException("No inverse to " + getClass().getName() + " created"); } List<SqlStatement> statements = new ArrayList<SqlStatement>(); try { for (Change inverse : inverses) { if (!inverse.supports(database)) { throw new RollbackImpossibleException( ChangeFactory.getInstance().getChangeMetaData(inverse).getName() + " is not supported on " + database.getShortName()); } statements.addAll(Arrays.asList(inverse.generateStatements(database))); } } catch (LiquibaseException e) { throw new RollbackImpossibleException(e); } return statements.toArray(new SqlStatement[statements.size()]); }
/** * Takes a list of SqlVisitors and returns a new list with only the SqlVisitors set to apply to * rollbacks */ protected List<SqlVisitor> filterRollbackVisitors(final List<SqlVisitor> visitors) { final List<SqlVisitor> rollbackVisitors = new ArrayList<SqlVisitor>(); if (visitors != null) { for (SqlVisitor visitor : visitors) { if (visitor.isApplyToRollback()) { rollbackVisitors.add(visitor); } } } return rollbackVisitors; }
public String getDescription() { List<Change> changes = getChanges(); if (changes.size() == 0) { return "empty"; } List<String> messages = new ArrayList<String>(); for (Change change : changes) { messages.add(change.getDescription()); } return StringUtils.limitSize(StringUtils.join(messages, "; "), 255); }
public void addChange(Change change) { if (change == null) { return; } changes.add(change); change.setChangeSet(this); }
protected Object serializeValue(Object value) throws ParsedNodeException { if (value instanceof Collection) { List returnList = new ArrayList(); for (Object obj : (Collection) value) { Object objValue = serializeValue(obj); if (objValue != null) { returnList.add(objValue); } } if (((Collection) value).size() == 0) { return null; } else { return returnList; } } else if (value instanceof LiquibaseSerializable) { return ((LiquibaseSerializable) value).serialize(); } else { return value; } }
@Override public void load(ParsedNode parsedNode, ResourceAccessor resourceAccessor) throws ParsedNodeException { ChangeMetaData metaData = ChangeFactory.getInstance().getChangeMetaData(this); this.setResourceAccessor(resourceAccessor); try { for (ChangeParameterMetaData param : metaData.getParameters().values()) { if (Collection.class.isAssignableFrom(param.getDataTypeClass())) { Class collectionType = (Class) param.getDataTypeClassParameters()[0]; if (param.getDataTypeClassParameters().length == 1) { if (ColumnConfig.class.isAssignableFrom(collectionType)) { List<ParsedNode> columnNodes = new ArrayList<ParsedNode>(parsedNode.getChildren(null, param.getParameterName())); columnNodes.addAll(parsedNode.getChildren(null, "column")); Object nodeValue = parsedNode.getValue(); if (nodeValue instanceof ParsedNode) { columnNodes.add((ParsedNode) nodeValue); } else if (nodeValue instanceof Collection) { for (Object nodeValueChild : ((Collection) nodeValue)) { if (nodeValueChild instanceof ParsedNode) { columnNodes.add((ParsedNode) nodeValueChild); } } } for (ParsedNode child : columnNodes) { if (child.getName().equals("column") || child.getName().equals("columns")) { List<ParsedNode> columnChildren = child.getChildren(null, "column"); if (columnChildren != null && columnChildren.size() > 0) { for (ParsedNode columnChild : columnChildren) { ColumnConfig columnConfig = (ColumnConfig) collectionType.newInstance(); columnConfig.load(columnChild, resourceAccessor); ((ChangeWithColumns) this).addColumn(columnConfig); } } else { ColumnConfig columnConfig = (ColumnConfig) collectionType.newInstance(); columnConfig.load(child, resourceAccessor); ((ChangeWithColumns) this).addColumn(columnConfig); } } } } else if (LiquibaseSerializable.class.isAssignableFrom(collectionType)) { List<ParsedNode> childNodes = new ArrayList<ParsedNode>(parsedNode.getChildren(null, param.getParameterName())); for (ParsedNode childNode : childNodes) { LiquibaseSerializable childObject = (LiquibaseSerializable) collectionType.newInstance(); childObject.load(childNode, resourceAccessor); ((Collection) param.getCurrentValue(this)).add(childObject); } } } } else if (LiquibaseSerializable.class.isAssignableFrom(param.getDataTypeClass())) { try { ParsedNode child = parsedNode.getChild(null, param.getParameterName()); if (child != null) { LiquibaseSerializable serializableChild = (LiquibaseSerializable) param.getDataTypeClass().newInstance(); serializableChild.load(child, resourceAccessor); param.setValue(this, serializableChild); } } catch (InstantiationException e) { throw new UnexpectedLiquibaseException(e); } catch (IllegalAccessException e) { throw new UnexpectedLiquibaseException(e); } } else { Object childValue = parsedNode.getChildValue(null, param.getParameterName(), param.getDataTypeClass()); if (childValue == null && param.getSerializationType() == SerializationType.DIRECT_VALUE) { childValue = parsedNode.getValue(); } param.setValue(this, childValue); } } } catch (InstantiationException e) { throw new UnexpectedLiquibaseException(e); } catch (IllegalAccessException e) { throw new UnexpectedLiquibaseException(e); } customLoadLogic(parsedNode, resourceAccessor); try { this.finishInitialization(); } catch (SetupException e) { throw new ParsedNodeException(e); } }
@Override public boolean dataTypeIsNotModifiable(final String typeName) { return unmodifiableDataTypes.contains(typeName.toLowerCase()); }
public void rollback(Database database) throws RollbackFailedException { try { Executor executor = ExecutorService.getInstance().getExecutor(database); executor.comment("Rolling Back ChangeSet: " + toString()); database.setObjectQuotingStrategy(objectQuotingStrategy); // set auto-commit based on runInTransaction if database supports DDL in transactions if (database.supportsDDLInTransaction()) { database.setAutoCommit(!runInTransaction); } RanChangeSet ranChangeSet = database.getRanChangeSet(this); if (hasCustomRollbackChanges()) { final List<SqlStatement> statements = new LinkedList<SqlStatement>(); for (Change change : rollback.getChanges()) { if (((change instanceof DbmsTargetedChange)) && !DatabaseList.definitionMatches( ((DbmsTargetedChange) change).getDbms(), database, true)) { continue; } SqlStatement[] changeStatements = change.generateStatements(database); if (changeStatements != null) { statements.addAll(Arrays.asList(changeStatements)); } } if (!statements.isEmpty()) { database.executeRollbackStatements( statements.toArray(new SqlStatement[] {}), sqlVisitors); } } else { List<Change> changes = getChanges(); for (int i = changes.size() - 1; i >= 0; i--) { Change change = changes.get(i); database.executeRollbackStatements(change, sqlVisitors); } } if (runInTransaction) { database.commit(); } log.debug("ChangeSet " + toString() + " has been successfully rolled back."); } catch (Exception e) { try { database.rollback(); } catch (DatabaseException e1) { // ok } throw new RollbackFailedException(e); } finally { // restore auto-commit to false if this ChangeSet was not run in a transaction, // but only if the database supports DDL in transactions if (!runInTransaction && database.supportsDDLInTransaction()) { try { database.setAutoCommit(false); } catch (DatabaseException e) { throw new RollbackFailedException("Could not resetInternalState autocommit", e); } } } }
public void addSqlVisitor(SqlVisitor sqlVisitor) { sqlVisitors.add(sqlVisitor); }