/** Tags the database changelog with the given string. */
  @Override
  public void tag(String tagString) throws DatabaseException {
    Executor executor = ExecutorService.getInstance().getExecutor(this);
    try {
      int totalRows =
          ExecutorService.getInstance()
              .getExecutor(this)
              .queryForInt(new SelectFromDatabaseChangeLogStatement("COUNT(*)"));
      if (totalRows == 0) {
        ChangeSet emptyChangeSet =
            new ChangeSet(
                String.valueOf(new Date().getTime()),
                "liquibase",
                false,
                false,
                "liquibase-internal",
                null,
                null);
        this.markChangeSetExecStatus(emptyChangeSet, ChangeSet.ExecType.EXECUTED);
      }

      // Timestamp lastExecutedDate = (Timestamp)
      // this.getExecutor().queryForObject(createChangeToTagSQL(),
      // Timestamp.class);
      executor.execute(new TagDatabaseStatement(tagString));
      this.commit();

      getRanChangeSetList().get(getRanChangeSetList().size() - 1).setTag(tagString);
    } catch (Exception e) {
      throw new DatabaseException(e);
    }
  }
  @Override
  public boolean acquireLock() throws LockException {
    if (hasChangeLogLock) {
      return true;
    }

    Executor executor = ExecutorService.getInstance().getExecutor(database);

    try {
      database.rollback();
      this.init();

      Boolean locked =
          (Boolean)
              ExecutorService.getInstance()
                  .getExecutor(database)
                  .queryForObject(
                      new SelectFromDatabaseChangeLogLockStatement("LOCKED"), Boolean.class);

      if (locked) {
        return false;
      } else {

        executor.comment("Lock Database");
        int rowsUpdated = executor.update(new LockDatabaseChangeLogStatement());
        if (rowsUpdated > 1) {
          throw new LockException("Did not update change log lock correctly");
        }
        if (rowsUpdated == 0) {
          // another node was faster
          return false;
        }
        database.commit();
        LogFactory.getLogger().info("Successfully acquired change log lock");

        hasChangeLogLock = true;

        database.setCanCacheLiquibaseTableInfo(true);
        return true;
      }
    } catch (Exception e) {
      throw new LockException(e);
    } finally {
      try {
        database.rollback();
      } catch (DatabaseException e) {;
      }
    }
  }
  public void releaseLock() throws DatabaseException, LockException {
    Executor executor = ExecutorService.getInstance().getExecutor(database);
    try {
      if (database.hasDatabaseChangeLogLockTable()) {
        executor.comment("Release Database Lock");
        database.rollback();
        int updatedRows = executor.update(new UnlockDatabaseChangeLogStatement());
        if (updatedRows != 1) {
          throw new LockException(
              "Did not update change log lock correctly.\n\n"
                  + updatedRows
                  + " rows were updated instead of the expected 1 row using executor "
                  + executor.getClass().getName()
                  + " there are "
                  + executor.queryForInt(
                      new RawSqlStatement(
                          "select count(*) from " + database.getDatabaseChangeLogLockTableName()))
                  + " rows in the table");
        }
        database.commit();
        hasChangeLogLock = false;

        instances.remove(this.database);

        database.setCanCacheLiquibaseTableInfo(false);

        LogFactory.getLogger().info("Successfully released change log lock");
      }
    } finally {
      database.rollback();
    }
  }
  /**
   * Generates the SQL statements required to run the change.
   *
   * @param database databasethe target {@link liquibase.database.Database} associated to this
   *     change's statements
   * @return an array of {@link String}s with the statements
   */
  public SqlStatement[] generateStatements(Database database) {
    final InsertStatement insertDefinition =
        new InsertStatement(database.getDefaultSchemaName(), "krim_attr_defn_t");
    final SqlStatement getId =
        new RuntimeStatement() {
          public Sql[] generate(Database database) {
            return new Sql[] {
              new UnparsedSql("insert into krim_attr_defn_id_s values(null)"),
              new UnparsedSql("select max(id) from krim_attr_defn_id_s")
            };
          }
        };

    try {
      final BigInteger id =
          (BigInteger)
              ExecutorService.getInstance()
                  .getExecutor(database)
                  .queryForObject(getId, BigInteger.class);

      insertDefinition.addColumnValue("KIM_ATTR_DEFN_ID", id);
      insertDefinition.addColumnValue("nmspc_cd", getNamespace());
      insertDefinition.addColumnValue("NM", getName());
      insertDefinition.addColumnValue("LBL", getLabel());
      insertDefinition.addColumnValue("actv_ind", getActive());
      insertDefinition.addColumnValue("CMPNT_NM", getComponent());
      insertDefinition.addColumnValue("ver_nbr", 1);
      insertDefinition.addColumnValue("obj_id", "sys_guid()");
    } catch (Exception e) {
      throw new RuntimeException(e);
    }

    return new SqlStatement[] {insertDefinition};
  }
  public DatabaseChangeLogLock[] listLocks() throws DatabaseException {
    try {
      if (!database.hasDatabaseChangeLogLockTable()) {
        return new DatabaseChangeLogLock[0];
      }

      List<DatabaseChangeLogLock> allLocks = new ArrayList<DatabaseChangeLogLock>();
      SqlStatement sqlStatement =
          new SelectFromDatabaseChangeLogLockStatement("ID", "LOCKED", "LOCKGRANTED", "LOCKEDBY");
      List<Map> rows =
          ExecutorService.getInstance().getExecutor(database).queryForList(sqlStatement);
      for (Map columnMap : rows) {
        Object lockedValue = columnMap.get("LOCKED");
        Boolean locked;
        if (lockedValue instanceof Number) {
          locked = ((Number) lockedValue).intValue() == 1;
        } else {
          locked = (Boolean) lockedValue;
        }
        if (locked != null && locked) {
          allLocks.add(
              new DatabaseChangeLogLock(
                  ((Number) columnMap.get("ID")).intValue(),
                  (Date) columnMap.get("LOCKGRANTED"),
                  (String) columnMap.get("LOCKEDBY")));
        }
      }
      return allLocks.toArray(new DatabaseChangeLogLock[allLocks.size()]);
    } finally {
      database
          .rollback(); // Rollback to make sure any database explicitly imposed lock from the above
                       // SELECT statement gets released. CORE-1219 incident.
    }
  }
  public boolean isDatabaseChangeLogLockTableInitialized(final boolean tableJustCreated)
      throws DatabaseException {
    if (!isDatabaseChangeLogLockTableInitialized) {
      Executor executor = ExecutorService.getInstance().getExecutor(database);

      try {
        isDatabaseChangeLogLockTableInitialized =
            executor.queryForInt(
                    new RawSqlStatement(
                        "select count(*) from "
                            + database.escapeTableName(
                                database.getLiquibaseCatalogName(),
                                database.getLiquibaseSchemaName(),
                                database.getDatabaseChangeLogLockTableName())))
                > 0;
      } catch (LiquibaseException e) {
        if (executor.updatesDatabase()) {
          throw new UnexpectedLiquibaseException(e);
        } else {
          // probably didn't actually create the table yet.
          isDatabaseChangeLogLockTableInitialized = !tableJustCreated;
        }
      }
    }
    return isDatabaseChangeLogLockTableInitialized;
  }
  @Override
  public DatabaseChangeLogLock[] listLocks() throws LockException {
    try {
      if (!this.hasDatabaseChangeLogLockTable()) {
        return new DatabaseChangeLogLock[0];
      }

      List<DatabaseChangeLogLock> allLocks = new ArrayList<DatabaseChangeLogLock>();
      SqlStatement sqlStatement =
          new SelectFromDatabaseChangeLogLockStatement("ID", "LOCKED", "LOCKGRANTED", "LOCKEDBY");
      List<Map<String, ?>> rows =
          ExecutorService.getInstance().getExecutor(database).queryForList(sqlStatement);
      for (Map columnMap : rows) {
        Object lockedValue = columnMap.get("LOCKED");
        Boolean locked;
        if (lockedValue instanceof Number) {
          locked = ((Number) lockedValue).intValue() == 1;
        } else {
          locked = (Boolean) lockedValue;
        }
        if (locked != null && locked) {
          allLocks.add(
              new DatabaseChangeLogLock(
                  ((Number) columnMap.get("ID")).intValue(),
                  (Date) columnMap.get("LOCKGRANTED"),
                  (String) columnMap.get("LOCKEDBY")));
        }
      }
      return allLocks.toArray(new DatabaseChangeLogLock[allLocks.size()]);
    } catch (Exception e) {
      throw new LockException(e);
    }
  }
  @Test
  public void accepts() throws DatabaseException {
    ArrayList<RanChangeSet> ranChanges = new ArrayList<RanChangeSet>();
    ranChanges.add(
        new RanChangeSet(
            "path/changelog", "1", "testAuthor", CheckSum.parse("12345"), new Date(), null, null));
    ranChanges.add(
        new RanChangeSet(
            "path/changelog", "2", "testAuthor", CheckSum.parse("12345"), new Date(), null, null));

    Database database = createMock(Database.class);
    expect(database.getRanChangeSetList()).andReturn(ranChanges);
    expect(database.getDatabaseChangeLogTableName()).andReturn("DATABASECHANGELOG").anyTimes();
    expect(database.getDefaultSchemaName()).andReturn(null).anyTimes();

    Executor template = createMock(Executor.class);
    expect(template.update(isA(UpdateStatement.class))).andReturn(1).anyTimes();
    //        template.comment("Lock Database");
    //        expectLastCall();

    replay(database);
    replay(template);
    ExecutorService.getInstance().setExecutor(database, template);

    ShouldRunChangeSetFilter filter = new ShouldRunChangeSetFilter(database);

    // everything same
    assertFalse(
        filter.accepts(
            new ChangeSet("1", "testAuthor", false, false, "path/changelog", null, null)));

    // alwaysRun
    assertTrue(
        filter.accepts(
            new ChangeSet("1", "testAuthor", true, false, "path/changelog", null, null)));

    // run on change
    assertTrue(
        filter.accepts(
            new ChangeSet("1", "testAuthor", false, true, "path/changelog", null, null)));

    // different id
    assertTrue(
        filter.accepts(
            new ChangeSet("3", "testAuthor", false, false, "path/changelog", null, null)));

    // different author
    assertTrue(
        filter.accepts(
            new ChangeSet("1", "otherAuthor", false, false, "path/changelog", null, null)));

    // different path
    assertTrue(
        filter.accepts(
            new ChangeSet("1", "testAuthor", false, false, "other/changelog", null, null)));
  }
 @Override
 public boolean doesTagExist(String tag) throws DatabaseException {
   int count =
       ExecutorService.getInstance()
           .getExecutor(this)
           .queryForInt(
               new SelectFromDatabaseChangeLogStatement(
                   new SelectFromDatabaseChangeLogStatement.ByTag("tag"), "COUNT(*)"));
   return count > 0;
 }
  /**
   * 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(ChangeSet changeSet, ChangeSet.ExecType execType)
      throws DatabaseException {

    ExecutorService.getInstance()
        .getExecutor(this)
        .execute(new MarkChangeSetRanStatement(changeSet, execType));
    commit();
    getRanChangeSetList().add(new RanChangeSet(changeSet, execType));
  }
  @Override
  public void removeRanStatus(ChangeSet changeSet) throws DatabaseException {

    ExecutorService.getInstance()
        .getExecutor(this)
        .execute(new RemoveChangeSetRanStatusStatement(changeSet));
    commit();

    getRanChangeSetList().remove(new RanChangeSet(changeSet));
  }
  /** Returns the run status for the given ChangeSet */
  @Override
  public ChangeSet.RunStatus getRunStatus(ChangeSet changeSet)
      throws DatabaseException, DatabaseHistoryException {
    if (!hasDatabaseChangeLogTable()) {
      return ChangeSet.RunStatus.NOT_RAN;
    }

    RanChangeSet foundRan = getRanChangeSet(changeSet);

    if (foundRan == null) {
      return ChangeSet.RunStatus.NOT_RAN;
    } else {
      if (foundRan.getLastCheckSum() == null) {
        try {
          LogFactory.getLogger().info("Updating NULL md5sum for " + changeSet.toString());
          ExecutorService.getInstance()
              .getExecutor(this)
              .execute(
                  new RawSqlStatement(
                      "UPDATE "
                          + escapeTableName(
                              getLiquibaseSchemaName(), getDatabaseChangeLogTableName())
                          + " SET MD5SUM='"
                          + changeSet.generateCheckSum().toString()
                          + "' WHERE ID='"
                          + changeSet.getId()
                          + "' AND AUTHOR='"
                          + changeSet.getAuthor()
                          + "' AND FILENAME='"
                          + changeSet.getFilePath()
                          + "'"));

          this.commit();
        } catch (DatabaseException e) {
          throw new DatabaseException(e);
        }

        return ChangeSet.RunStatus.ALREADY_RAN;
      } else {
        if (foundRan.getLastCheckSum().equals(changeSet.generateCheckSum())) {
          return ChangeSet.RunStatus.ALREADY_RAN;
        } else {
          if (changeSet.shouldRunOnChange()) {
            return ChangeSet.RunStatus.RUN_AGAIN;
          } else {
            return ChangeSet.RunStatus.INVALID_MD5SUM;
            // throw new DatabaseHistoryException("MD5 Check for " + changeSet.toString() + "
            // failed");
          }
        }
      }
    }
  }
 /*
  * Executes the statements passed
  *
  * @param statements an array containing the SQL statements to be issued
  * @param sqlVisitors a list of {@link SqlVisitor} objects to be applied to the executed statements
  * @throws DatabaseException if there were problems issuing the statements
  */
 @Override
 public void execute(final SqlStatement[] statements, final List<SqlVisitor> sqlVisitors)
     throws LiquibaseException {
   for (SqlStatement statement : statements) {
     if (statement.skipOnUnsupported()
         && !SqlGeneratorFactory.getInstance().supports(statement, this)) {
       continue;
     }
     LogFactory.getLogger().debug("Executing Statement: " + statement);
     ExecutorService.getInstance().getExecutor(this).execute(statement, sqlVisitors);
   }
 }
  @Override
  public void init() throws DatabaseException {

    boolean createdTable = false;
    Executor executor = ExecutorService.getInstance().getExecutor(database);
    if (!hasDatabaseChangeLogLockTable()) {

      executor.comment("Create Database Lock Table");
      executor.execute(new CreateDatabaseChangeLogLockTableStatement());
      database.commit();
      LogFactory.getLogger()
          .debug(
              "Created database lock table with name: "
                  + database.escapeTableName(
                      database.getLiquibaseCatalogName(),
                      database.getLiquibaseSchemaName(),
                      database.getDatabaseChangeLogLockTableName()));
      this.hasDatabaseChangeLogLockTable = true;
      createdTable = true;
    }

    if (!isDatabaseChangeLogLockTableInitialized(createdTable)) {
      executor.comment("Initialize Database Lock Table");
      executor.execute(new InitializeDatabaseChangeLogLockTableStatement());
      database.commit();
    }

    if (database instanceof DerbyDatabase
        && ((DerbyDatabase) database)
            .supportsBooleanDataType()) { // check if the changelog table is of an old smallint vs.
                                          // boolean format
      String lockTable =
          database.escapeTableName(
              database.getLiquibaseCatalogName(),
              database.getLiquibaseSchemaName(),
              database.getDatabaseChangeLogLockTableName());
      Object obj =
          executor.queryForObject(
              new RawSqlStatement(
                  "select min(locked) as test from " + lockTable + " fetch first row only"),
              Object.class);
      if (!(obj instanceof Boolean)) { // wrong type, need to recreate table
        executor.execute(
            new DropTableStatement(
                database.getLiquibaseCatalogName(),
                database.getLiquibaseSchemaName(),
                database.getDatabaseChangeLogLockTableName(),
                false));
        executor.execute(new CreateDatabaseChangeLogLockTableStatement());
        executor.execute(new InitializeDatabaseChangeLogLockTableStatement());
      }
    }
  }
  /** Returns the ChangeSets that have been run against the current database. */
  @Override
  public List<RanChangeSet> getRanChangeSetList() throws DatabaseException {
    if (this.ranChangeSetList != null) {
      return this.ranChangeSetList;
    }

    String databaseChangeLogTableName =
        escapeTableName(getLiquibaseSchemaName(), getDatabaseChangeLogTableName());
    ranChangeSetList = new ArrayList<RanChangeSet>();
    if (hasDatabaseChangeLogTable()) {
      LogFactory.getLogger().info("Reading from " + databaseChangeLogTableName);
      SqlStatement select =
          new SelectFromDatabaseChangeLogStatement(
                  "FILENAME",
                  "AUTHOR",
                  "ID",
                  "MD5SUM",
                  "DATEEXECUTED",
                  "ORDEREXECUTED",
                  "TAG",
                  "EXECTYPE")
              .setOrderBy("DATEEXECUTED ASC", "ORDEREXECUTED ASC");
      List<Map> results = ExecutorService.getInstance().getExecutor(this).queryForList(select);
      for (Map<?, ?> rs : results) {
        String fileName = rs.get("FILENAME").toString();
        String author = rs.get("AUTHOR").toString();
        String id = rs.get("ID").toString();
        String md5sum = rs.get("MD5SUM") == null ? null : rs.get("MD5SUM").toString();
        Date dateExecuted = (Date) rs.get("DATEEXECUTED");
        String tag = rs.get("TAG") == null ? null : rs.get("TAG").toString();
        String execType = rs.get("EXECTYPE") == null ? null : rs.get("EXECTYPE").toString();
        try {
          RanChangeSet ranChangeSet =
              new RanChangeSet(
                  fileName,
                  id,
                  author,
                  CheckSum.parse(md5sum),
                  dateExecuted,
                  tag,
                  ChangeSet.ExecType.valueOf(execType));
          ranChangeSetList.add(ranChangeSet);
        } catch (IllegalArgumentException e) {
          LogFactory.getLogger().severe("Unknown EXECTYPE from database: " + execType);
          throw e;
        }
      }
    }
    return ranChangeSetList;
  }
  /**
   * Overwrite this method to get the default schema name for the connection.
   *
   * @return
   */
  protected String getConnectionSchemaName() {
    if (connection == null || connection instanceof OfflineConnection) {
      return null;
    }
    try {
      return ExecutorService.getInstance()
          .getExecutor(this)
          .queryForObject(new RawCallStatement("call current_schema"), String.class);

    } catch (Exception e) {
      LogFactory.getLogger().info("Error getting default schema", e);
    }
    return null;
  }
  @Test
  public void testUpdateSQLNoAlterSqlDryMode() {
    ExecutorService.getInstance()
        .setExecutor(database, new LoggingExecutor(null, new StringWriter(), database));
    System.setProperty(Configuration.NO_ALTER_SQL_DRY_MODE, "true");

    SqlStatement[] statements = c.generateStatements(database);
    Assert.assertEquals(1, statements.length);
    Assert.assertEquals(CommentStatement.class, statements[0].getClass());
    Assert.assertEquals(
        "pt-online-schema-change --alter=\"DROP COLUMN col_test\" "
            + "--host=localhost --port=3306 --user=user --password=*** --execute D=testdb,t=person",
        ((CommentStatement) statements[0]).getText());
  }
 @Override
 public String getViewDefinition(String schemaName, String viewName) throws DatabaseException {
   if (schemaName == null) {
     schemaName = convertRequestedSchemaToSchema(null);
   }
   String definition =
       (String)
           ExecutorService.getInstance()
               .getExecutor(this)
               .queryForObject(new GetViewDefinitionStatement(schemaName, viewName), String.class);
   if (definition == null) {
     return null;
   }
   return CREATE_VIEW_AS_PATTERN.matcher(definition).replaceFirst("");
 }
  @Override
  public int getNextChangeSetSequenceValue() throws LiquibaseException {
    if (lastChangeSetSequenceValue == null) {
      if (getConnection() == null) {
        lastChangeSetSequenceValue = 0;
      } else {
        lastChangeSetSequenceValue =
            ExecutorService.getInstance()
                .getExecutor(this)
                .queryForInt(new GetNextChangeSetSequenceValueStatement());
      }
    }

    return ++lastChangeSetSequenceValue;
  }
  @Test
  public void testUpdateSQL() {
    ExecutorService.getInstance()
        .setExecutor(database, new LoggingExecutor(null, new StringWriter(), database));

    SqlStatement[] statements = c.generateStatements(database);
    Assert.assertEquals(3, statements.length);
    Assert.assertEquals(CommentStatement.class, statements[0].getClass());
    Assert.assertEquals(
        "pt-online-schema-change --alter=\"DROP COLUMN col_test\" "
            + "--host=localhost --port=3306 --user=user --password=*** --execute D=testdb,t=person",
        ((CommentStatement) statements[0]).getText());
    Assert.assertEquals(CommentStatement.class, statements[1].getClass());
    Assert.assertEquals(DropColumnStatement.class, statements[2].getClass());
  }
 @Override
 protected String getConnectionCatalogName() throws DatabaseException {
   if (getConnection() instanceof OfflineConnection) {
     return getConnection().getCatalog();
   }
   try {
     return ExecutorService.getInstance()
         .getExecutor(this)
         .queryForObject(
             new RawCallStatement("select sys_context( 'userenv', 'current_schema' ) from dual"),
             String.class);
   } catch (Exception e) {
     LogFactory.getLogger().info("Error getting default schema", e);
   }
   return null;
 }
  /**
   * This method will check the database ChangeLogLock table used to keep track of if a machine is
   * updating the database. If the table does not exist it will create one otherwise it will not do
   * anything besides outputting a log message.
   */
  @Override
  public void checkDatabaseChangeLogLockTable() throws DatabaseException {

    Executor executor = ExecutorService.getInstance().getExecutor(this);
    if (!hasDatabaseChangeLogLockTable()) {

      executor.comment("Create Database Lock Table");
      executor.execute(new CreateDatabaseChangeLogLockTableStatement());
      this.commit();
      LogFactory.getLogger()
          .debug(
              "Created database lock table with name: "
                  + escapeTableName(getLiquibaseSchemaName(), getDatabaseChangeLogLockTableName()));
      this.hasDatabaseChangeLogLockTable = true;
    }
  }
 @Override
 public String getViewDefinition(CatalogAndSchema schema, final String viewName)
     throws DatabaseException {
   schema = schema.customize(this);
   String definition =
       (String)
           ExecutorService.getInstance()
               .getExecutor(this)
               .queryForObject(
                   new GetViewDefinitionStatement(
                       schema.getCatalogName(), schema.getSchemaName(), viewName),
                   String.class);
   if (definition == null) {
     return null;
   }
   return CREATE_VIEW_AS_PATTERN.matcher(definition).replaceFirst("");
 }
 @Override
 public void setConnection(final DatabaseConnection connection) {
   super.setConnection(connection);
   try {
     /*
      * TODO Maybe there is a better place for this.
      * For each session this statement has to be executed,
      * to allow newlines in quoted strings
      */
     ExecutorService.getInstance()
         .getExecutor(this)
         .execute(new RawSqlStatement("EXECUTE PROCEDURE IFX_ALLOW_NEWLINE('T');"));
   } catch (Exception e) {
     throw new UnexpectedLiquibaseException(
         "Could not allow newline characters in quoted strings with IFX_ALLOW_NEWLINE", e);
   }
 }
  @Override
  public void close() throws DatabaseException {
    DatabaseConnection connection = getConnection();
    if (connection != null) {
      if (previousAutoCommit != null) {
        try {
          connection.setAutoCommit(previousAutoCommit);
        } catch (DatabaseException e) {
          LogFactory.getLogger()
              .warning("Failed to restore the auto commit to " + previousAutoCommit);

          throw e;
        }
      }
      connection.close();
    }
    ExecutorService.getInstance().clearExecutor(this);
  }
 @Override
 public String getViewDefinition(CatalogAndSchema schema, final String viewName)
     throws DatabaseException {
   schema = correctSchema(schema);
   List<Map> retList =
       ExecutorService.getInstance()
           .getExecutor(this)
           .queryForList(
               new GetViewDefinitionStatement(
                   schema.getCatalogName(), schema.getSchemaName(), viewName));
   // building the view definition from the multiple rows
   StringBuilder sb = new StringBuilder();
   for (Map rowMap : retList) {
     String s = (String) rowMap.get("VIEWTEXT");
     sb.append(s);
   }
   return CREATE_VIEW_AS_PATTERN.matcher(sb.toString()).replaceFirst("");
 }
  public Set<String> getUserDefinedTypes() {
    if (userDefinedTypes == null) {
      userDefinedTypes = new HashSet<String>();
      if (getConnection() != null && !(getConnection() instanceof OfflineConnection)) {
        try {
          userDefinedTypes.addAll(
              ExecutorService.getInstance()
                  .getExecutor(this)
                  .queryForList(
                      new RawSqlStatement("SELECT TYPE_NAME FROM USER_TYPES"), String.class));
        } catch (DatabaseException e) {
          // ignore error
        }
      }
    }

    return userDefinedTypes;
  }
  @Before
  public void setup() {
    c = new PerconaDropColumnChange();
    c.setColumnName("col_test");
    c.setTableName("person");
    c.getColumns().clear();

    DatabaseConnectionUtil.passwordForTests = "root";

    database = new MySQLDatabase();
    database.setLiquibaseSchemaName("testdb");
    DatabaseConnection conn =
        new MockDatabaseConnection("jdbc:mysql://user@localhost:3306/testdb", "user@localhost");
    database.setConnection(conn);
    ExecutorService.getInstance().setExecutor(database, new JdbcExecutor());

    PTOnlineSchemaChangeStatement.available = true;
    System.setProperty(Configuration.FAIL_IF_NO_PT, "false");
    System.setProperty(Configuration.NO_ALTER_SQL_DRY_MODE, "false");
  }
 @Override
 public void destroy() throws DatabaseException {
   try {
     if (SnapshotGeneratorFactory.getInstance()
         .has(
             new Table()
                 .setName(database.getDatabaseChangeLogLockTableName())
                 .setSchema(database.getLiquibaseCatalogName(), database.getLiquibaseSchemaName()),
             database)) {
       ExecutorService.getInstance()
           .getExecutor(database)
           .execute(
               new DropTableStatement(
                   database.getLiquibaseCatalogName(),
                   database.getLiquibaseSchemaName(),
                   database.getDatabaseChangeLogLockTableName(),
                   false));
     }
   } catch (InvalidExampleException e) {
     throw new UnexpectedLiquibaseException(e);
   }
 }
Exemple #30
0
  @Override
  public boolean acquireLock() {
    if (hasChangeLogLock) {
      // We already have a lock
      return true;
    }

    Executor executor = ExecutorService.getInstance().getExecutor(database);

    try {
      database.rollback();

      // Ensure table created and lock record inserted
      this.init();
    } catch (DatabaseException de) {
      throw new IllegalStateException("Failed to retrieve lock", de);
    }

    try {
      log.debug("Trying to lock database");
      executor.execute(new LockDatabaseChangeLogStatement());
      log.debug("Successfully acquired database lock");

      hasChangeLogLock = true;
      database.setCanCacheLiquibaseTableInfo(true);
      return true;

    } catch (DatabaseException de) {
      log.warn(
          "Lock didn't yet acquired. Will possibly retry to acquire lock. Details: "
              + de.getMessage());
      if (log.isTraceEnabled()) {
        log.debug(de.getMessage(), de);
      }
      return false;
    }
  }