/**
  * After the change set has been ran against the database this method will update the change log
  * table with the information.
  */
 @Override
 public void markChangeSetExecStatus(final ChangeSet changeSet, final ChangeSet.ExecType execType)
     throws DatabaseException {
   ChangeLogHistoryServiceFactory.getInstance()
       .getChangeLogService(this)
       .setExecType(changeSet, execType);
 }
 @Override
 public Date getRanDate(final ChangeSet changeSet)
     throws DatabaseException, DatabaseHistoryException {
   return ChangeLogHistoryServiceFactory.getInstance()
       .getChangeLogService(this)
       .getRanDate(changeSet);
 }
  @Override
  public Sql[] generateSql(
      MarkChangeSetRanStatement statement, Database database, SqlGeneratorChain sqlGeneratorChain) {
    String dateValue = database.getCurrentDateTimeFunction();

    ChangeSet changeSet = statement.getChangeSet();

    SqlStatement runStatement;
    try {
      if (statement.getExecType().equals(ChangeSet.ExecType.FAILED)
          || statement.getExecType().equals(ChangeSet.ExecType.SKIPPED)) {
        return new Sql[0]; // don't mark
      } else if (statement.getExecType().ranBefore) {
        runStatement =
            new UpdateStatement(
                    database.getLiquibaseCatalogName(),
                    database.getLiquibaseSchemaName(),
                    database.getDatabaseChangeLogTableName())
                .addNewColumnValue("DATEEXECUTED", new DatabaseFunction(dateValue))
                .addNewColumnValue("MD5SUM", changeSet.generateCheckSum().toString())
                .addNewColumnValue("EXECTYPE", statement.getExecType().value)
                .setWhereClause("ID=? AND AUTHOR=? AND FILENAME=?")
                .addWhereParameters(
                    changeSet.getId(), changeSet.getAuthor(), changeSet.getFilePath());
      } else {
        runStatement =
            new InsertStatement(
                    database.getLiquibaseCatalogName(),
                    database.getLiquibaseSchemaName(),
                    database.getDatabaseChangeLogTableName())
                .addColumnValue("ID", changeSet.getId())
                .addColumnValue("AUTHOR", changeSet.getAuthor())
                .addColumnValue("FILENAME", changeSet.getFilePath())
                .addColumnValue("DATEEXECUTED", new DatabaseFunction(dateValue))
                .addColumnValue(
                    "ORDEREXECUTED",
                    ChangeLogHistoryServiceFactory.getInstance()
                        .getChangeLogService(database)
                        .getNextSequenceValue())
                .addColumnValue("MD5SUM", changeSet.generateCheckSum().toString())
                .addColumnValue("DESCRIPTION", limitSize(changeSet.getDescription()))
                .addColumnValue(
                    "COMMENTS",
                    limitSize(
                        database.escapeStringForDatabase(
                            StringUtils.trimToEmpty(changeSet.getComments()))))
                .addColumnValue("EXECTYPE", statement.getExecType().value)
                .addColumnValue(
                    "LIQUIBASE", LiquibaseUtil.getBuildVersion().replaceAll("SNAPSHOT", "SNP"));

        String tag = null;
        List<Change> changes = changeSet.getChanges();
        if (changes != null && changes.size() == 1) {
          Change change = changes.get(0);
          if (change instanceof TagDatabaseChange) {
            TagDatabaseChange tagChange = (TagDatabaseChange) change;
            tag = tagChange.getTag();
          }
        }
        if (tag != null) {
          ((InsertStatement) runStatement).addColumnValue("TAG", tag);
        }
      }
    } catch (LiquibaseException e) {
      throw new UnexpectedLiquibaseException(e);
    }

    return SqlGeneratorFactory.getInstance().generateSql(runStatement, database);
  }
 @Override
 public boolean doesTagExist(final String tag) throws DatabaseException {
   return ChangeLogHistoryServiceFactory.getInstance().getChangeLogService(this).tagExists(tag);
 }
 /** Tags the database changelog with the given string. */
 @Override
 public void tag(final String tagString) throws DatabaseException {
   ChangeLogHistoryServiceFactory.getInstance().getChangeLogService(this).tag(tagString);
 }
  /** Drops all objects owned by the connected user. */
  @Override
  public void dropDatabaseObjects(final CatalogAndSchema schemaToDrop) throws LiquibaseException {
    ObjectQuotingStrategy currentStrategy = this.getObjectQuotingStrategy();
    this.setObjectQuotingStrategy(ObjectQuotingStrategy.QUOTE_ALL_OBJECTS);
    try {
      DatabaseSnapshot snapshot;
      try {
        final SnapshotControl snapshotControl = new SnapshotControl(this);
        final Set<Class<? extends DatabaseObject>> typesToInclude =
            snapshotControl.getTypesToInclude();

        // We do not need to remove indexes and primary/unique keys explicitly. They should be
        // removed
        // as part of tables.
        typesToInclude.remove(Index.class);
        typesToInclude.remove(PrimaryKey.class);
        typesToInclude.remove(UniqueConstraint.class);

        if (supportsForeignKeyDisable()) {
          // We do not remove ForeignKey because they will be disabled and removed as parts of
          // tables.
          typesToInclude.remove(ForeignKey.class);
        }

        final long createSnapshotStarted = System.currentTimeMillis();
        snapshot =
            SnapshotGeneratorFactory.getInstance()
                .createSnapshot(schemaToDrop, this, snapshotControl);
        LogFactory.getLogger()
            .debug(
                String.format(
                    "Database snapshot generated in %d ms. Snapshot includes: %s",
                    System.currentTimeMillis() - createSnapshotStarted, typesToInclude));
      } catch (LiquibaseException e) {
        throw new UnexpectedLiquibaseException(e);
      }

      final long changeSetStarted = System.currentTimeMillis();
      DiffResult diffResult =
          DiffGeneratorFactory.getInstance()
              .compare(
                  new EmptyDatabaseSnapshot(this),
                  snapshot,
                  new CompareControl(snapshot.getSnapshotControl().getTypesToInclude()));
      List<ChangeSet> changeSets =
          new DiffToChangeLog(
                  diffResult,
                  new DiffOutputControl(true, true, false).addIncludedSchema(schemaToDrop))
              .generateChangeSets();
      LogFactory.getLogger()
          .debug(
              String.format(
                  "ChangeSet to Remove Database Objects generated in %d ms.",
                  System.currentTimeMillis() - changeSetStarted));

      boolean previousAutoCommit = this.getAutoCommitMode();
      this.commit(); // clear out currently executed statements
      this.setAutoCommit(false); // some DDL doesn't work in autocommit mode
      final boolean reEnableFK = supportsForeignKeyDisable() && disableForeignKeyChecks();
      try {
        for (ChangeSet changeSet : changeSets) {
          changeSet.setFailOnError(false);
          for (Change change : changeSet.getChanges()) {
            if (change instanceof DropTableChange) {
              ((DropTableChange) change).setCascadeConstraints(true);
            }
            SqlStatement[] sqlStatements = change.generateStatements(this);
            for (SqlStatement statement : sqlStatements) {
              ExecutorService.getInstance().getExecutor(this).execute(statement);
            }
          }
          this.commit();
        }
      } finally {
        if (reEnableFK) {
          enableForeignKeyChecks();
        }
      }

      ChangeLogHistoryServiceFactory.getInstance().getChangeLogService(this).destroy();
      LockServiceFactory.getInstance().getLockService(this).destroy();

      this.setAutoCommit(previousAutoCommit);

    } finally {
      this.setObjectQuotingStrategy(currentStrategy);
      this.commit();
    }
  }
 protected boolean canCreateChangeLogTable() throws DatabaseException {
   return ((StandardChangeLogHistoryService)
           ChangeLogHistoryServiceFactory.getInstance().getChangeLogService(this))
       .canCreateChangeLogTable();
 }
 @Override
 public void resetInternalState() {
   ChangeLogHistoryServiceFactory.getInstance().getChangeLogService(this).reset();
   LockServiceFactory.getInstance().getLockService(this).reset();
 }
 @Override
 public void removeRanStatus(final ChangeSet changeSet) throws DatabaseException {
   ChangeLogHistoryServiceFactory.getInstance()
       .getChangeLogService(this)
       .removeFromHistory(changeSet);
 }
 /** Returns the ChangeSets that have been run against the current database. */
 @Override
 public List<RanChangeSet> getRanChangeSetList() throws DatabaseException {
   return ChangeLogHistoryServiceFactory.getInstance()
       .getChangeLogService(this)
       .getRanChangeSets();
 }