@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()); } } }
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 Sql[] generateSql( CreateDatabaseChangeLogTableStatement statement, Database database, SqlGeneratorChain sqlGeneratorChain) { /* Because Informix has some limitations on the primary key column cumulative size (same is for unique indices), * the ID's column has been made the sole primary key, and also has a reduced size. * * The original configuration provided by the base class causes the database changelog table not to be created. */ CreateTableStatement createTableStatement = new CreateTableStatement( database.getLiquibaseCatalogName(), database.getLiquibaseSchemaName(), database.getDatabaseChangeLogTableName()) .addPrimaryKeyColumn( "ID", DataTypeFactory.getInstance().fromDescription("VARCHAR(" + getIdColumnSize() + ")"), null, null, null, new NotNullConstraint()) .addColumn( "AUTHOR", DataTypeFactory.getInstance() .fromDescription("VARCHAR(" + getAuthorColumnSize() + ")"), null, null, null, new NotNullConstraint()) .addColumn( "FILENAME", DataTypeFactory.getInstance() .fromDescription("VARCHAR(" + getFilenameColumnSize() + ")"), null, null, null, new NotNullConstraint()) .addColumn( "DATEEXECUTED", DataTypeFactory.getInstance().fromDescription("datetime"), null, new NotNullConstraint()) .addColumn( "ORDEREXECUTED", DataTypeFactory.getInstance().fromDescription("INT"), new NotNullConstraint()) .addColumn( "EXECTYPE", DataTypeFactory.getInstance().fromDescription("VARCHAR(10)"), new NotNullConstraint()) .addColumn("MD5SUM", DataTypeFactory.getInstance().fromDescription("VARCHAR(35)")) .addColumn("DESCRIPTION", DataTypeFactory.getInstance().fromDescription("VARCHAR(255)")) .addColumn("COMMENTS", DataTypeFactory.getInstance().fromDescription("VARCHAR(255)")) .addColumn("TAG", DataTypeFactory.getInstance().fromDescription("VARCHAR(255)")) .addColumn("LIQUIBASE", DataTypeFactory.getInstance().fromDescription("VARCHAR(20)")); return SqlGeneratorFactory.getInstance().generateSql(createTableStatement, database); }
@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); } }
@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); }