예제 #1
0
  /*
   * 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()]);
  }
예제 #2
0
  /**
   * Implementation delegates logic to the {@link
   * liquibase.sqlgenerator.SqlGenerator#warn(liquibase.statement.SqlStatement,
   * liquibase.database.Database, liquibase.sqlgenerator.SqlGeneratorChain)} method on the {@link
   * SqlStatement} objects returned by {@link #generateStatements }. If a generated statement is not
   * supported for the given database, no warning will be added since that is a validation error. If
   * no or null SqlStatements are returned by generateStatements then this method returns no
   * warnings.
   */
  @Override
  public Warnings warn(Database database) {
    Warnings warnings = new Warnings();
    if (generateStatementsVolatile(database)) {
      return warnings;
    }

    SqlStatement[] statements = generateStatements(database);
    if (statements == null) {
      return warnings;
    }
    for (SqlStatement statement : statements) {
      if (SqlGeneratorFactory.getInstance().supports(statement, database)) {
        warnings.addAll(SqlGeneratorFactory.getInstance().warn(statement, database));
      } else if (statement.skipOnUnsupported()) {
        warnings.addWarning(
            statement.getClass().getName()
                + " is not supported on "
                + database.getShortName()
                + ", but "
                + ChangeFactory.getInstance().getChangeMetaData(this).getName()
                + " will still execute");
      }
    }

    return warnings;
  }
예제 #3
0
  /**
   * Implementation checks the ChangeParameterMetaData for declared required fields and also
   * delegates logic to the {@link
   * liquibase.sqlgenerator.SqlGenerator#validate(liquibase.statement.SqlStatement,
   * liquibase.database.Database, liquibase.sqlgenerator.SqlGeneratorChain)} method on the {@link
   * SqlStatement} objects returned by {@link #generateStatements }. If no or null SqlStatements are
   * returned by generateStatements then this method returns no errors. If there are no parameters
   * than this method returns no errors
   */
  @Override
  public ValidationErrors validate(Database database) {
    ValidationErrors changeValidationErrors = new ValidationErrors();

    for (ChangeParameterMetaData param :
        ChangeFactory.getInstance().getChangeMetaData(this).getParameters().values()) {
      if (param.isRequiredFor(database) && param.getCurrentValue(this) == null) {
        changeValidationErrors.addError(
            param.getParameterName()
                + " is required for "
                + ChangeFactory.getInstance().getChangeMetaData(this).getName()
                + " on "
                + database.getShortName());
      }
    }
    if (changeValidationErrors.hasErrors()) {
      return changeValidationErrors;
    }

    String unsupportedWarning =
        ChangeFactory.getInstance().getChangeMetaData(this).getName()
            + " is not supported on "
            + database.getShortName();
    if (!this.supports(database)) {
      changeValidationErrors.addError(unsupportedWarning);
    } else if (!generateStatementsVolatile(database)) {
      boolean sawUnsupportedError = false;
      SqlStatement[] statements;
      statements = generateStatements(database);
      if (statements != null) {
        for (SqlStatement statement : statements) {
          boolean supported = SqlGeneratorFactory.getInstance().supports(statement, database);
          if (!supported && !sawUnsupportedError) {
            if (!statement.skipOnUnsupported()) {
              changeValidationErrors.addError(unsupportedWarning);
              sawUnsupportedError = true;
            }
          } else {
            changeValidationErrors.addAll(
                SqlGeneratorFactory.getInstance().validate(statement, database));
          }
        }
      }
    }

    return changeValidationErrors;
  }
예제 #4
0
 @Override
 public SerializationType getSerializableFieldType(String field) {
   return ChangeFactory.getInstance()
       .getChangeMetaData(this)
       .getParameters()
       .get(field)
       .getSerializationType();
 }
예제 #5
0
 @Override
 public Object getSerializableFieldValue(String field) {
   return ChangeFactory.getInstance()
       .getChangeMetaData(this)
       .getParameters()
       .get(field)
       .getCurrentValue(this);
 }
예제 #6
0
  @Override
  public ParsedNode serialize() throws ParsedNodeException {
    ParsedNode node = new ParsedNode(null, getSerializedObjectName());
    ChangeMetaData metaData = ChangeFactory.getInstance().getChangeMetaData(this);
    for (ChangeParameterMetaData param : metaData.getSetParameters(this).values()) {
      Object currentValue = param.getCurrentValue(this);
      currentValue = serializeValue(currentValue);
      if (currentValue != null) {
        node.addChild(null, param.getParameterName(), currentValue);
      }
    }

    return node;
  }
예제 #7
0
  @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);
    }
  }
예제 #8
0
 @Override
 public String toString() {
   return ChangeFactory.getInstance().getChangeMetaData(this).getName();
 }
예제 #9
0
 @Override
 public String getSerializedObjectName() {
   return ChangeFactory.getInstance().getChangeMetaData(this).getName();
 }
예제 #10
0
 /** Returns the fields on this change that are serializable. */
 @Override
 public Set<String> getSerializableFields() {
   return ChangeFactory.getInstance().getChangeMetaData(this).getParameters().keySet();
 }