@Override
  public Sql[] generateSql(
      final AddAutoIncrementStatement statement,
      Database database,
      SqlGeneratorChain sqlGeneratorChain) {
    List<Sql> statements = new ArrayList<Sql>();

    // define alter table logic
    SQLiteDatabase.AlterTableVisitor rename_alter_visitor =
        new SQLiteDatabase.AlterTableVisitor() {
          @Override
          public ColumnConfig[] getColumnsToAdd() {
            return new ColumnConfig[0];
          }

          @Override
          public boolean copyThisColumn(ColumnConfig column) {
            return true;
          }

          @Override
          public boolean createThisColumn(ColumnConfig column) {
            if (column.getName().equals(statement.getColumnName())) {
              column.setAutoIncrement(true);
              column.setType("INTEGER");
            }
            return true;
          }

          @Override
          public boolean createThisIndex(Index index) {
            return true;
          }
        };

    try {
      // alter table
      for (SqlStatement generatedStatement :
          SQLiteDatabase.getAlterTableStatements(
              rename_alter_visitor,
              database,
              statement.getCatalogName(),
              statement.getSchemaName(),
              statement.getTableName())) {
        statements.addAll(
            Arrays.asList(
                SqlGeneratorFactory.getInstance().generateSql(generatedStatement, database)));
      }
    } catch (DatabaseException e) {
      e.printStackTrace();
    }

    return statements.toArray(new Sql[statements.size()]);
  }
示例#2
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;
    }
  }
示例#3
0
  @Override
  public void init() throws DatabaseException {
    boolean createdTable = false;
    Executor executor = ExecutorService.getInstance().getExecutor(database);

    if (!hasDatabaseChangeLogLockTable()) {

      try {
        if (log.isTraceEnabled()) {
          log.trace("Create Database Lock Table");
        }
        executor.execute(new CreateDatabaseChangeLogLockTableStatement());
        database.commit();
      } catch (DatabaseException de) {
        log.warn(
            "Failed to create lock table. Maybe other transaction created in the meantime. Retrying...");
        if (log.isTraceEnabled()) {
          log.trace(de.getMessage(), de); // Log details at trace level
        }
        database.rollback();
        throw new LockRetryException(de);
      }

      log.debugf(
          "Created database lock table with name: %s",
          database.escapeTableName(
              database.getLiquibaseCatalogName(),
              database.getLiquibaseSchemaName(),
              database.getDatabaseChangeLogLockTableName()));

      try {
        Field field =
            Reflections.findDeclaredField(
                StandardLockService.class, "hasDatabaseChangeLogLockTable");
        Reflections.setAccessible(field);
        field.set(CustomLockService.this, true);
      } catch (IllegalAccessException iae) {
        throw new RuntimeException(iae);
      }

      createdTable = true;
    }

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

      } catch (DatabaseException de) {
        log.warn(
            "Failed to insert first record to the lock table. Maybe other transaction inserted in the meantime. Retrying...");
        if (log.isTraceEnabled()) {
          log.trace(de.getMessage(), de); // Log details at trace level
        }
        database.rollback();
        throw new LockRetryException(de);
      }

      log.debug("Initialized record in the database lock table");
    }

    // repeid doesn't support Derby, but keep it for sure...
    if (executor.updatesDatabase()
        && 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());
      }
    }
  }