Search in sources :

Example 16 with Executor

use of liquibase.executor.Executor in project liquibase by liquibase.

the class StandardChangeLogHistoryService method init.

public void init() throws DatabaseException {
    if (serviceInitialized) {
        return;
    }
    Database database = getDatabase();
    Executor executor = ExecutorService.getInstance().getExecutor(database);
    Table changeLogTable = null;
    try {
        changeLogTable = SnapshotGeneratorFactory.getInstance().getDatabaseChangeLogTable(new SnapshotControl(database, false, Table.class, Column.class), database);
    } catch (LiquibaseException e) {
        throw new UnexpectedLiquibaseException(e);
    }
    List<SqlStatement> statementsToExecute = new ArrayList<SqlStatement>();
    boolean changeLogCreateAttempted = false;
    if (changeLogTable != null) {
        boolean hasDescription = changeLogTable.getColumn("DESCRIPTION") != null;
        boolean hasComments = changeLogTable.getColumn("COMMENTS") != null;
        boolean hasTag = changeLogTable.getColumn("TAG") != null;
        boolean hasLiquibase = changeLogTable.getColumn("LIQUIBASE") != null;
        boolean hasContexts = changeLogTable.getColumn("CONTEXTS") != null;
        boolean hasLabels = changeLogTable.getColumn("LABELS") != null;
        boolean liquibaseColumnNotRightSize = false;
        if (!(this.getDatabase() instanceof SQLiteDatabase)) {
            DataType type = changeLogTable.getColumn("LIQUIBASE").getType();
            if (type.getTypeName().toLowerCase().startsWith("varchar")) {
                Integer columnSize = type.getColumnSize();
                liquibaseColumnNotRightSize = columnSize != null && columnSize < 20;
            } else {
                liquibaseColumnNotRightSize = false;
            }
        }
        boolean hasOrderExecuted = changeLogTable.getColumn("ORDEREXECUTED") != null;
        boolean checksumNotRightSize = false;
        if (!(this.getDatabase() instanceof SQLiteDatabase)) {
            DataType type = changeLogTable.getColumn("MD5SUM").getType();
            if (type.getTypeName().toLowerCase().startsWith("varchar")) {
                Integer columnSize = type.getColumnSize();
                checksumNotRightSize = columnSize != null && columnSize < 35;
            } else {
                liquibaseColumnNotRightSize = false;
            }
        }
        boolean hasExecTypeColumn = changeLogTable.getColumn("EXECTYPE") != null;
        String charTypeName = getCharTypeName();
        boolean hasDeploymentIdColumn = changeLogTable.getColumn("DEPLOYMENT_ID") != null;
        if (!hasDescription) {
            executor.comment("Adding missing databasechangelog.description column");
            statementsToExecute.add(new AddColumnStatement(getLiquibaseCatalogName(), getLiquibaseSchemaName(), getDatabaseChangeLogTableName(), "DESCRIPTION", charTypeName + "(255)", null));
        }
        if (!hasTag) {
            executor.comment("Adding missing databasechangelog.tag column");
            statementsToExecute.add(new AddColumnStatement(getLiquibaseCatalogName(), getLiquibaseSchemaName(), getDatabaseChangeLogTableName(), "TAG", charTypeName + "(255)", null));
        }
        if (!hasComments) {
            executor.comment("Adding missing databasechangelog.comments column");
            statementsToExecute.add(new AddColumnStatement(getLiquibaseCatalogName(), getLiquibaseSchemaName(), getDatabaseChangeLogTableName(), "COMMENTS", charTypeName + "(255)", null));
        }
        if (!hasLiquibase) {
            executor.comment("Adding missing databasechangelog.liquibase column");
            statementsToExecute.add(new AddColumnStatement(getLiquibaseCatalogName(), getLiquibaseSchemaName(), getDatabaseChangeLogTableName(), "LIQUIBASE", charTypeName + "(20)", null));
        }
        if (!hasOrderExecuted) {
            executor.comment("Adding missing databasechangelog.orderexecuted column");
            statementsToExecute.add(new AddColumnStatement(getLiquibaseCatalogName(), getLiquibaseSchemaName(), getDatabaseChangeLogTableName(), "ORDEREXECUTED", "int", null));
            statementsToExecute.add(new UpdateStatement(getLiquibaseCatalogName(), getLiquibaseSchemaName(), getDatabaseChangeLogTableName()).addNewColumnValue("ORDEREXECUTED", -1));
            statementsToExecute.add(new SetNullableStatement(getLiquibaseCatalogName(), getLiquibaseSchemaName(), getDatabaseChangeLogTableName(), "ORDEREXECUTED", "int", false));
        }
        if (checksumNotRightSize) {
            executor.comment("Modifying size of databasechangelog.md5sum column");
            statementsToExecute.add(new ModifyDataTypeStatement(getLiquibaseCatalogName(), getLiquibaseSchemaName(), getDatabaseChangeLogTableName(), "MD5SUM", charTypeName + "(35)"));
        }
        if (liquibaseColumnNotRightSize) {
            executor.comment("Modifying size of databasechangelog.liquibase column");
            statementsToExecute.add(new ModifyDataTypeStatement(getLiquibaseCatalogName(), getLiquibaseSchemaName(), getDatabaseChangeLogTableName(), "LIQUIBASE", charTypeName + "(20)"));
        }
        if (!hasExecTypeColumn) {
            executor.comment("Adding missing databasechangelog.exectype column");
            statementsToExecute.add(new AddColumnStatement(getLiquibaseCatalogName(), getLiquibaseSchemaName(), getDatabaseChangeLogTableName(), "EXECTYPE", charTypeName + "(10)", null));
            statementsToExecute.add(new UpdateStatement(getLiquibaseCatalogName(), getLiquibaseSchemaName(), getDatabaseChangeLogTableName()).addNewColumnValue("EXECTYPE", "EXECUTED"));
            statementsToExecute.add(new SetNullableStatement(getLiquibaseCatalogName(), getLiquibaseSchemaName(), getDatabaseChangeLogTableName(), "EXECTYPE", charTypeName + "(10)", false));
        }
        if (hasContexts) {
            Integer columnSize = changeLogTable.getColumn("CONTEXTS").getType().getColumnSize();
            if (columnSize != null && columnSize < Integer.parseInt(getContextsSize())) {
                executor.comment("Modifying size of databasechangelog.contexts column");
                statementsToExecute.add(new ModifyDataTypeStatement(getLiquibaseCatalogName(), getLiquibaseSchemaName(), getDatabaseChangeLogTableName(), "CONTEXTS", charTypeName + "(" + getContextsSize() + ")"));
            }
        } else {
            executor.comment("Adding missing databasechangelog.contexts column");
            statementsToExecute.add(new AddColumnStatement(getLiquibaseCatalogName(), getLiquibaseSchemaName(), getDatabaseChangeLogTableName(), "CONTEXTS", charTypeName + "(" + getContextsSize() + ")", null));
        }
        if (hasLabels) {
            Integer columnSize = changeLogTable.getColumn("LABELS").getType().getColumnSize();
            if (columnSize != null && columnSize < Integer.parseInt(getLabelsSize())) {
                executor.comment("Modifying size of databasechangelog.labels column");
                statementsToExecute.add(new ModifyDataTypeStatement(getLiquibaseCatalogName(), getLiquibaseSchemaName(), getDatabaseChangeLogTableName(), "LABELS", charTypeName + "(" + getLabelsSize() + ")"));
            }
        } else {
            executor.comment("Adding missing databasechangelog.labels column");
            statementsToExecute.add(new AddColumnStatement(getLiquibaseCatalogName(), getLiquibaseSchemaName(), getDatabaseChangeLogTableName(), "LABELS", charTypeName + "(" + getLabelsSize() + ")", null));
        }
        if (!hasDeploymentIdColumn) {
            executor.comment("Adding missing databasechangelog.deployment_id column");
            statementsToExecute.add(new AddColumnStatement(getLiquibaseCatalogName(), getLiquibaseSchemaName(), getDatabaseChangeLogTableName(), "DEPLOYMENT_ID", "VARCHAR(10)", null));
            if (database instanceof DB2Database) {
                statementsToExecute.add(new ReorganizeTableStatement(getLiquibaseCatalogName(), getLiquibaseSchemaName(), getDatabaseChangeLogTableName()));
            }
        }
        List<Map<String, ?>> md5sumRS = ExecutorService.getInstance().getExecutor(database).queryForList(new SelectFromDatabaseChangeLogStatement(new SelectFromDatabaseChangeLogStatement.ByNotNullCheckSum(), new ColumnConfig().setName("MD5SUM")).setLimit(1));
        if (md5sumRS.size() > 0) {
            String md5sum = md5sumRS.get(0).get("MD5SUM").toString();
            if (!md5sum.startsWith(CheckSum.getCurrentVersion() + ":")) {
                executor.comment("DatabaseChangeLog checksums are an incompatible version.  Setting them to null so they will be updated on next database update");
                databaseChecksumsCompatible = false;
                statementsToExecute.add(new RawSqlStatement("UPDATE " + getDatabase().escapeTableName(getLiquibaseCatalogName(), getLiquibaseSchemaName(), getDatabaseChangeLogTableName()) + " " + "SET " + getDatabase().escapeObjectName("MD5SUM", Column.class) + " = NULL"));
            }
        }
    } else if (!changeLogCreateAttempted) {
        executor.comment("Create Database Change Log Table");
        SqlStatement createTableStatement = new CreateDatabaseChangeLogTableStatement();
        if (!canCreateChangeLogTable()) {
            throw new DatabaseException("Cannot create " + getDatabase().escapeTableName(getLiquibaseCatalogName(), getLiquibaseSchemaName(), getDatabaseChangeLogTableName()) + " table for your getDatabase().\n\n" + "Please construct it manually using the following SQL as a base and re-run Liquibase:\n\n" + createTableStatement);
        }
        // If there is no table in the database for recording change history create one.
        statementsToExecute.add(createTableStatement);
        LogFactory.getLogger().info("Creating database history table with name: " + getDatabase().escapeTableName(getLiquibaseCatalogName(), getLiquibaseSchemaName(), getDatabaseChangeLogTableName()));
    }
    for (SqlStatement sql : statementsToExecute) {
        if (SqlGeneratorFactory.getInstance().supports(sql, database)) {
            executor.execute(sql);
            getDatabase().commit();
        } else {
            LogFactory.getLogger().info("Cannot run " + sql.getClass().getSimpleName() + " on " + getDatabase().getShortName() + " when checking databasechangelog table");
        }
    }
    serviceInitialized = true;
}
Also used : DB2Database(liquibase.database.core.DB2Database) ColumnConfig(liquibase.change.ColumnConfig) SqlStatement(liquibase.statement.SqlStatement) Executor(liquibase.executor.Executor) SQLiteDatabase(liquibase.database.core.SQLiteDatabase) DB2Database(liquibase.database.core.DB2Database) MSSQLDatabase(liquibase.database.core.MSSQLDatabase) Database(liquibase.database.Database) DataType(liquibase.structure.core.DataType) SnapshotControl(liquibase.snapshot.SnapshotControl) Table(liquibase.structure.core.Table) SQLiteDatabase(liquibase.database.core.SQLiteDatabase) UnexpectedLiquibaseException(liquibase.exception.UnexpectedLiquibaseException) LiquibaseException(liquibase.exception.LiquibaseException) UnexpectedLiquibaseException(liquibase.exception.UnexpectedLiquibaseException) DatabaseException(liquibase.exception.DatabaseException)

Example 17 with Executor

use of liquibase.executor.Executor in project liquibase by liquibase.

the class StandardChangeLogHistoryService method tag.

/**
     * Tags the database changelog with the given string.
     */
@Override
public void tag(final String tagString) throws DatabaseException {
    Database database = getDatabase();
    Executor executor = ExecutorService.getInstance().getExecutor(database);
    try {
        int totalRows = ExecutorService.getInstance().getExecutor(database).queryForInt(new SelectFromDatabaseChangeLogStatement(new ColumnConfig().setName("COUNT(*)", true)));
        if (totalRows == 0) {
            ChangeSet emptyChangeSet = new ChangeSet(String.valueOf(new Date().getTime()), "liquibase", false, false, "liquibase-internal", null, null, getDatabase().getObjectQuotingStrategy(), null);
            this.setExecType(emptyChangeSet, ChangeSet.ExecType.EXECUTED);
        }
        //            Timestamp lastExecutedDate = (Timestamp) this.getExecutor().queryForObject(createChangeToTagSQL(), Timestamp.class);
        executor.execute(new TagDatabaseStatement(tagString));
        getDatabase().commit();
        if (this.ranChangeSetList != null) {
            ranChangeSetList.get(ranChangeSetList.size() - 1).setTag(tagString);
        }
    } catch (Exception e) {
        throw new DatabaseException(e);
    }
}
Also used : Executor(liquibase.executor.Executor) ColumnConfig(liquibase.change.ColumnConfig) SQLiteDatabase(liquibase.database.core.SQLiteDatabase) DB2Database(liquibase.database.core.DB2Database) MSSQLDatabase(liquibase.database.core.MSSQLDatabase) Database(liquibase.database.Database) DatabaseException(liquibase.exception.DatabaseException) UnexpectedLiquibaseException(liquibase.exception.UnexpectedLiquibaseException) DatabaseHistoryException(liquibase.exception.DatabaseHistoryException) ParseException(java.text.ParseException) InvalidExampleException(liquibase.snapshot.InvalidExampleException) DatabaseException(liquibase.exception.DatabaseException) LiquibaseException(liquibase.exception.LiquibaseException)

Example 18 with Executor

use of liquibase.executor.Executor in project liquibase by liquibase.

the class ExecuteSqlCommand method run.

@Override
protected CommandResult run() throws Exception {
    Executor executor = ExecutorService.getInstance().getExecutor(database);
    String sqlText;
    if (sqlFile == null) {
        sqlText = sql;
    } else {
        File file = new File(sqlFile);
        if (!file.exists()) {
            throw new LiquibaseException(String.format("The file '%s' does not exist", file.getCanonicalPath()));
        }
        sqlText = FileUtil.getContents(file);
    }
    String out = "";
    String[] sqlStrings = StringUtils.processMutliLineSQL(sqlText, true, true, delimiter);
    for (String sql : sqlStrings) {
        if (sql.toLowerCase().matches("\\s*select .*")) {
            List<Map<String, ?>> rows = executor.queryForList(new RawSqlStatement(sql));
            out += "Output of " + sql + ":\n";
            if (rows.size() == 0) {
                out += "-- Empty Resultset --\n";
            } else {
                SortedSet<String> keys = new TreeSet<String>();
                for (Map<String, ?> row : rows) {
                    keys.addAll(row.keySet());
                }
                out += StringUtils.join(keys, " | ") + " |\n";
                for (Map<String, ?> row : rows) {
                    for (String key : keys) {
                        out += row.get(key) + " | ";
                    }
                    out += "\n";
                }
            }
        } else {
            executor.execute(new RawSqlStatement(sql));
            out += "Successfully Executed: " + sql + "\n";
        }
        out += "\n";
    }
    database.commit();
    return new CommandResult(out.trim());
}
Also used : RawSqlStatement(liquibase.statement.core.RawSqlStatement) Executor(liquibase.executor.Executor) TreeSet(java.util.TreeSet) LiquibaseException(liquibase.exception.LiquibaseException) File(java.io.File) Map(java.util.Map) CommandResult(liquibase.command.CommandResult)

Example 19 with Executor

use of liquibase.executor.Executor in project liquibase by liquibase.

the class AbstractIntegrationTest method testRerunDiffChangeLogAltSchema.

@Test
public void testRerunDiffChangeLogAltSchema() throws Exception {
    if (database == null) {
        return;
    }
    if (!database.supportsSchemas()) {
        return;
    }
    Liquibase liquibase = createLiquibase(includedChangeLog);
    clearDatabase(liquibase);
    database.setDefaultSchemaName("lbcat2");
    LockService lockService = LockServiceFactory.getInstance().getLockService(database);
    lockService.forceReleaseLock();
    liquibase.update(includedChangeLog);
    DatabaseSnapshot originalSnapshot = SnapshotGeneratorFactory.getInstance().createSnapshot(database.getDefaultSchema(), database, new SnapshotControl(database));
    CompareControl compareControl = new CompareControl(new CompareControl.SchemaComparison[] { new CompareControl.SchemaComparison(CatalogAndSchema.DEFAULT, new CatalogAndSchema(null, "lbcat2")) }, originalSnapshot.getSnapshotControl().getTypesToInclude());
    DiffResult diffResult = DiffGeneratorFactory.getInstance().compare(database, null, compareControl);
    File tempFile = File.createTempFile("liquibase-test", ".xml");
    FileOutputStream output = new FileOutputStream(tempFile);
    try {
        new DiffToChangeLog(diffResult, new DiffOutputControl()).print(new PrintStream(output));
        output.flush();
    } finally {
        output.close();
    }
    liquibase = createLiquibase(tempFile.getName());
    clearDatabase(liquibase);
    //run again to test changelog testing logic
    Executor executor = ExecutorService.getInstance().getExecutor(database);
    try {
        executor.execute(new DropTableStatement("lbcat2", "lbcat2", database.getDatabaseChangeLogTableName(), false));
    } catch (DatabaseException e) {
    //ok
    }
    try {
        executor.execute(new DropTableStatement("lbcat2", "lbcat2", database.getDatabaseChangeLogLockTableName(), false));
    } catch (DatabaseException e) {
    //ok
    }
    database.commit();
    DatabaseConnection connection = DatabaseTestContext.getInstance().getConnection(url);
    database = DatabaseFactory.getInstance().findCorrectDatabaseImplementation(connection);
    database.setDefaultSchemaName("lbcat2");
    liquibase = createLiquibase(tempFile.getName());
    try {
        liquibase.update(this.contexts);
    } catch (ValidationFailedException e) {
        e.printDescriptiveError(System.out);
        throw e;
    }
    tempFile.deleteOnExit();
    DatabaseSnapshot finalSnapshot = SnapshotGeneratorFactory.getInstance().createSnapshot(database.getDefaultSchema(), database, new SnapshotControl(database));
    CompareControl finalCompareControl = new CompareControl();
    finalCompareControl.addSuppressedField(Column.class, "autoIncrementInformation");
    DiffResult finalDiffResult = DiffGeneratorFactory.getInstance().compare(originalSnapshot, finalSnapshot, finalCompareControl);
    new DiffToReport(finalDiffResult, System.out).print();
    assertTrue(finalDiffResult.areEqual());
}
Also used : LockService(liquibase.lockservice.LockService) DiffOutputControl(liquibase.diff.output.DiffOutputControl) CatalogAndSchema(liquibase.CatalogAndSchema) Liquibase(liquibase.Liquibase) Executor(liquibase.executor.Executor) ValidationFailedException(liquibase.exception.ValidationFailedException) DiffToReport(liquibase.diff.output.report.DiffToReport) CompareControl(liquibase.diff.compare.CompareControl) DiffToChangeLog(liquibase.diff.output.changelog.DiffToChangeLog) DatabaseConnection(liquibase.database.DatabaseConnection) DiffResult(liquibase.diff.DiffResult) DatabaseSnapshot(liquibase.snapshot.DatabaseSnapshot) SnapshotControl(liquibase.snapshot.SnapshotControl) DropTableStatement(liquibase.statement.core.DropTableStatement) DatabaseException(liquibase.exception.DatabaseException) Test(org.junit.Test)

Example 20 with Executor

use of liquibase.executor.Executor in project liquibase by liquibase.

the class StandardLockService method init.

@Override
public void init() throws DatabaseException {
    boolean createdTable = false;
    Executor executor = ExecutorService.getInstance().getExecutor(database);
    if (!hasDatabaseChangeLogLockTable()) {
        try {
            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()));
        } catch (DatabaseException e) {
            if (e.getMessage() != null && e.getMessage().contains("exists")) {
                //hit a race condition where the table got created by another node.
                LogFactory.getLogger().debug("Database lock table already appears to exist, due to exception: " + e.getMessage() + ". Continuing on");
            } else {
                throw e;
            }
        }
        this.hasDatabaseChangeLogLockTable = true;
        createdTable = true;
        hasDatabaseChangeLogLockTable = true;
    }
    if (!isDatabaseChangeLogLockTableInitialized(createdTable)) {
        executor.comment("Initialize Database Lock Table");
        executor.execute(new InitializeDatabaseChangeLogLockTableStatement());
        database.commit();
    }
    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());
        }
    }
}
Also used : Executor(liquibase.executor.Executor) DerbyDatabase(liquibase.database.core.DerbyDatabase) DatabaseException(liquibase.exception.DatabaseException)

Aggregations

Executor (liquibase.executor.Executor)27 UnexpectedLiquibaseException (liquibase.exception.UnexpectedLiquibaseException)16 LiquibaseException (liquibase.exception.LiquibaseException)15 LoggingExecutor (liquibase.executor.LoggingExecutor)13 DatabaseException (liquibase.exception.DatabaseException)9 MSSQLDatabase (liquibase.database.core.MSSQLDatabase)6 RawSqlStatement (liquibase.statement.core.RawSqlStatement)4 Map (java.util.Map)3 Change (liquibase.change.Change)3 RawSQLChange (liquibase.change.core.RawSQLChange)3 Database (liquibase.database.Database)3 DB2Database (liquibase.database.core.DB2Database)3 LockException (liquibase.exception.LockException)3 LockService (liquibase.lockservice.LockService)3 ParsedNodeException (liquibase.parser.core.ParsedNodeException)3 InvalidExampleException (liquibase.snapshot.InvalidExampleException)3 Sql (liquibase.sql.Sql)3 SqlStatement (liquibase.statement.SqlStatement)3 List (java.util.List)2 ColumnConfig (liquibase.change.ColumnConfig)2