public void check(Database database, DatabaseChangeLog changeLog, ChangeSet changeSet) throws PreconditionFailedException, PreconditionErrorException { Column example = new Column(); if (StringUtils.trimToNull(getTableName()) != null) { example.setRelation( new Table() .setName(database.correctObjectName(getTableName(), Table.class)) .setSchema(new Schema(getCatalogName(), getSchemaName()))); } example.setName(database.correctObjectName(getColumnName(), Column.class)); try { if (!SnapshotGeneratorFactory.getInstance().has(example, database)) { throw new PreconditionFailedException( "Column '" + database.escapeColumnName( catalogName, schemaName, getTableName(), getColumnName()) + "' does not exist", changeLog, this); } } catch (LiquibaseException e) { throw new PreconditionErrorException(e, changeLog, this); } }
@Override public void check(Database database, DatabaseChangeLog changeLog, ChangeSet changeSet) throws PreconditionFailedException, PreconditionErrorException { String currentSchemaName; String currentCatalogName; try { currentCatalogName = getCatalogName(); currentSchemaName = getSchemaName(); if (!SnapshotGeneratorFactory.getInstance() .has( new View() .setName(getViewName()) .setSchema(new Schema(currentCatalogName, currentSchemaName)), database)) { throw new PreconditionFailedException( "View " + database.escapeTableName(currentCatalogName, currentSchemaName, getViewName()) + " does not exist", changeLog, this); } } catch (PreconditionFailedException e) { throw e; } catch (Exception e) { throw new PreconditionErrorException(e, changeLog, this); } }
public boolean hasDatabaseChangeLogLockTable() throws DatabaseException { boolean hasTable = false; try { hasTable = SnapshotGeneratorFactory.getInstance().hasDatabaseChangeLogLockTable(database); } catch (LiquibaseException e) { throw new UnexpectedLiquibaseException(e); } return hasTable; }
@Override public ChangeStatus checkStatus(Database database) { ChangeStatus result = new ChangeStatus(); try { Column column = SnapshotGeneratorFactory.getInstance() .createSnapshot( new Column( Table.class, getCatalogName(), getSchemaName(), getTableName(), getColumnName()), database); if (column == null) { return result.unknown("Column " + getColumnName() + " does not exist"); } result.assertComplete( column.getDefaultValue() != null, "Column " + getColumnName() + " has no default value"); if (column.getDefaultValue() == null) { return result; } if (getDefaultValue() != null) { return result.assertCorrect( getDefaultValue().equals(column.getDefaultValue()), "Default value was " + column.getDefaultValue()); } else if (getDefaultValueDate() != null) { return result.assertCorrect( getDefaultValueDate() .equals(new ISODateFormat().format((Date) column.getDefaultValue())), "Default value was " + column.getDefaultValue()); } else if (getDefaultValueNumeric() != null) { return result.assertCorrect( getDefaultValueNumeric().equals(column.getDefaultValue().toString()), "Default value was " + column.getDefaultValue()); } else if (getDefaultValueBoolean() != null) { return result.assertCorrect( getDefaultValueBoolean().equals(column.getDefaultValue()), "Default value was " + column.getDefaultValue()); } else if (getDefaultValueComputed() != null) { return result.assertCorrect( getDefaultValueComputed().equals(column.getDefaultValue()), "Default value was " + column.getDefaultValue()); } else if (getDefaultValueSequenceNext() != null) { return result.assertCorrect( getDefaultValueSequenceNext().equals(column.getDefaultValue()), "Default value was " + column.getDefaultValue()); } else { return result.unknown("Unknown default value type"); } } catch (Exception e) { return result.unknown(e); } }
public static void main(String[] args) { VerticaDatabase verticaDatabase = new VerticaDatabase(); liquibase.database.DatabaseFactory.getInstance().register(verticaDatabase); liquibase.snapshot.SnapshotGeneratorFactory.getInstance() .unregister(UniqueConstraintSnapshotGenerator.class); ChangeGeneratorFactory.getInstance().unregister(MissingColumnChangeGenerator.class); Properties myProp = new Properties(); String defaultCatalogName = "yaron_secondary"; String defaultSchemaName = defaultCatalogName; String password = defaultCatalogName + "_123"; String changeLogFilePath = "c:\\liquibaseChangeSet.xml"; String dataOutputDirectory = "c:\\liquibase_output"; String connectionString = "jdbc:vertica://mydphdb0082.hpswlabs.adapps.hp.com:5433/eummobile"; String changeSetAuthor = "jony"; myProp.put("user", defaultCatalogName); myProp.put("password", password); Connection conn = null; try { File changeLogFile = new File(changeLogFilePath); changeLogFile.delete(); conn = DriverManager.getConnection(connectionString, myProp); conn.setAutoCommit(false); DatabaseConnection dc = new JdbcConnection(conn); verticaDatabase.setConnection(dc); String diffTypes = null; String changeSetContext = null; boolean includeCatalog = false; // Boolean.parseBoolean(getCommandParam("includeCatalog", "false")); boolean includeSchema = false; // Boolean.parseBoolean(getCommandParam("includeSchema", "false")); boolean includeTablespace = false; // Boolean.parseBoolean(getCommandParam("includeTablespace", "false")); DiffOutputControl diffOutputControl = new DiffOutputControl(includeCatalog, includeSchema, includeTablespace); CommandLineUtils.doGenerateChangeLog( changeLogFilePath, verticaDatabase, defaultCatalogName, defaultSchemaName, StringUtils.trimToNull(diffTypes), StringUtils.trimToNull(changeSetAuthor), StringUtils.trimToNull(changeSetContext), StringUtils.trimToNull(dataOutputDirectory), diffOutputControl); postChangeSetGenerationProcessing(changeLogFile); } catch (Exception e) { e.printStackTrace(); // To change body of catch statement use File | Settings | File // Templates. } }
@Override public ChangeStatus checkStatus(Database database) { try { return new ChangeStatus() .assertComplete( !SnapshotGeneratorFactory.getInstance() .has(new View(getCatalogName(), getSchemaName(), getViewName()), database), "View exists"); } catch (Exception e) { return new ChangeStatus().unknown(e); } }
@Test public void snapshot() throws Exception { if (getDatabase() == null) { return; } runCompleteChangeLog(); DatabaseSnapshot snapshot = SnapshotGeneratorFactory.getInstance() .createSnapshot( getDatabase().getDefaultSchema(), getDatabase(), new SnapshotControl(getDatabase())); System.out.println(snapshot); }
@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); } }
public static List<SqlStatement> getAlterTableStatements( AlterTableVisitor alterTableVisitor, Database database, String catalogName, String schemaName, String tableName) throws DatabaseException { DatabaseSnapshot snapshot = null; // todo List<SqlStatement> statements = new ArrayList<SqlStatement>(); Table table = null; try { table = SnapshotGeneratorFactory.getInstance() .createSnapshot( (Table) new Table().setName(tableName).setSchema(new Schema(new Catalog(null), null)), database); } catch (InvalidExampleException e) { throw new UnexpectedLiquibaseException(e); } List<ColumnConfig> createColumns = new Vector<ColumnConfig>(); List<ColumnConfig> copyColumns = new Vector<ColumnConfig>(); if (table != null) { for (Column column : table.getColumns()) { ColumnConfig new_column = new ColumnConfig(column); if (alterTableVisitor.createThisColumn(new_column)) { createColumns.add(new_column); } ColumnConfig copy_column = new ColumnConfig(column); if (alterTableVisitor.copyThisColumn(copy_column)) { copyColumns.add(copy_column); } } } for (ColumnConfig column : alterTableVisitor.getColumnsToAdd()) { if (alterTableVisitor.createThisColumn(column)) { createColumns.add(column); } if (alterTableVisitor.copyThisColumn(column)) { copyColumns.add(column); } } List<Index> newIndices = new Vector<Index>(); for (Index index : new ArrayList< Index>()) { // todo SnapshotGeneratorFactory.getInstance().getGenerator(Index.class, // database).get(new Schema(new Catalog(null), schemaName), database)) { if (index.getTable().getName().equalsIgnoreCase(tableName)) { if (alterTableVisitor.createThisIndex(index)) { newIndices.add(index); } } } // rename table String temp_table_name = tableName + "_temporary"; statements.add(new RenameTableStatement(catalogName, schemaName, tableName, temp_table_name)); // create temporary table CreateTableChange ct_change_tmp = new CreateTableChange(); ct_change_tmp.setSchemaName(schemaName); ct_change_tmp.setTableName(tableName); for (ColumnConfig column : createColumns) { ct_change_tmp.addColumn(column); } statements.addAll(Arrays.asList(ct_change_tmp.generateStatements(database))); // copy rows to temporary table statements.add(new CopyRowsStatement(temp_table_name, tableName, copyColumns)); // delete original table statements.add(new DropTableStatement(catalogName, schemaName, temp_table_name, false)); // validate indices statements.add(new ReindexStatement(catalogName, schemaName, tableName)); // add remaining indices for (Index index_config : newIndices) { statements.add( new CreateIndexStatement( index_config.getName(), catalogName, schemaName, tableName, index_config.isUnique(), index_config.getAssociatedWithAsString(), index_config.getColumns().toArray(new String[index_config.getColumns().size()]))); } return statements; }
@Override public void checkDatabaseChangeLogTable( final boolean updateExistingNullChecksums, final DatabaseChangeLog databaseChangeLog, final Contexts contexts) throws DatabaseException { if (updateExistingNullChecksums && databaseChangeLog == null) { throw new DatabaseException("changeLog parameter is required if updating existing checksums"); } Executor executor = ExecutorService.getInstance().getExecutor(this); Table changeLogTable = SnapshotGeneratorFactory.getInstance() .getDatabaseChangeLogTable(new SnapshotControl(this, Table.class, Column.class), this); 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 liquibaseColumnNotRightSize = false; if (!getConnection().getDatabaseProductName().equals("SQLite")) { liquibaseColumnNotRightSize = changeLogTable.getColumn("LIQUIBASE").getType().getColumnSize() != 20; } boolean hasOrderExecuted = changeLogTable.getColumn("ORDEREXECUTED") != null; boolean checksumNotRightSize = false; boolean hasExecTypeColumn = changeLogTable.getColumn("EXECTYPE") != null; if (!hasDescription) { executor.comment("Adding missing databasechangelog.description column"); statementsToExecute.add( new AddColumnStatement( getLiquibaseCatalogName(), getLiquibaseSchemaName(), getDatabaseChangeLogTableName(), "DESCRIPTION", "VARCHAR(255)", null)); } if (!hasTag) { executor.comment("Adding missing databasechangelog.tag column"); statementsToExecute.add( new AddColumnStatement( getLiquibaseCatalogName(), getLiquibaseSchemaName(), getDatabaseChangeLogTableName(), "TAG", "VARCHAR(255)", null)); } if (!hasComments) { executor.comment("Adding missing databasechangelog.comments column"); statementsToExecute.add( new AddColumnStatement( getLiquibaseCatalogName(), getLiquibaseSchemaName(), getDatabaseChangeLogTableName(), "COMMENTS", "VARCHAR(255)", null)); } if (!hasLiquibase) { executor.comment("Adding missing databasechangelog.liquibase column"); statementsToExecute.add( new AddColumnStatement( getLiquibaseCatalogName(), getLiquibaseSchemaName(), getDatabaseChangeLogTableName(), "LIQUIBASE", "VARCHAR(255)", 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", "VARCHAR(35)")); } if (liquibaseColumnNotRightSize) { executor.comment("Modifying size of databasechangelog.liquibase column"); statementsToExecute.add( new ModifyDataTypeStatement( getLiquibaseCatalogName(), getLiquibaseSchemaName(), getDatabaseChangeLogTableName(), "LIQUIBASE", "VARCHAR(20)")); } if (!hasExecTypeColumn) { executor.comment("Adding missing databasechangelog.exectype column"); statementsToExecute.add( new AddColumnStatement( getLiquibaseCatalogName(), getLiquibaseSchemaName(), getDatabaseChangeLogTableName(), "EXECTYPE", "VARCHAR(10)", null)); statementsToExecute.add( new UpdateStatement( getLiquibaseCatalogName(), getLiquibaseSchemaName(), getDatabaseChangeLogTableName()) .addNewColumnValue("EXECTYPE", "EXECUTED")); statementsToExecute.add( new SetNullableStatement( getLiquibaseCatalogName(), getLiquibaseSchemaName(), getDatabaseChangeLogTableName(), "EXECTYPE", "VARCHAR(10)", false)); } List<Map> md5sumRS = ExecutorService.getInstance() .getExecutor(this) .queryForList( new SelectFromDatabaseChangeLogStatement( new SelectFromDatabaseChangeLogStatement.ByNotNullCheckSum(), "MD5SUM")); 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"); statementsToExecute.add( new RawSqlStatement( "UPDATE " + escapeTableName( getLiquibaseCatalogName(), getLiquibaseSchemaName(), getDatabaseChangeLogTableName()) + " SET MD5SUM=null")); } } } else if (!changeLogCreateAttempted) { executor.comment("Create Database Change Log Table"); SqlStatement createTableStatement = new CreateDatabaseChangeLogTableStatement(); if (!canCreateChangeLogTable()) { throw new DatabaseException( "Cannot create " + escapeTableName( getLiquibaseCatalogName(), getLiquibaseSchemaName(), getDatabaseChangeLogTableName()) + " table for your database.\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: " + escapeTableName( getLiquibaseCatalogName(), getLiquibaseSchemaName(), getDatabaseChangeLogTableName())); // } } for (SqlStatement sql : statementsToExecute) { executor.execute(sql); this.commit(); } if (updateExistingNullChecksums) { for (RanChangeSet ranChangeSet : this.getRanChangeSetList()) { if (ranChangeSet.getLastCheckSum() == null) { ChangeSet changeSet = databaseChangeLog.getChangeSet(ranChangeSet); if (changeSet != null && new ContextChangeSetFilter(contexts).accepts(changeSet) && new DbmsChangeSetFilter(this).accepts(changeSet)) { LogFactory.getLogger() .info( "Updating null or out of date checksum on changeSet " + changeSet + " to correct value"); executor.execute(new UpdateChangeSetChecksumStatement(changeSet)); } } } commit(); resetRanChangeSetList(); } }
/** 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(); } }
@Override public Change[] fixMissing( DatabaseObject missingObject, DiffOutputControl control, Database referenceDatabase, Database comparisonDatabase, ChangeGeneratorChain chain) { List<Change> returnList = new ArrayList<Change>(); PrimaryKey pk = (PrimaryKey) missingObject; AddPrimaryKeyChange change = new AddPrimaryKeyChange(); change.setTableName(pk.getTable().getName()); if (control.getIncludeCatalog()) { change.setCatalogName(pk.getTable().getSchema().getCatalogName()); } if (control.getIncludeSchema()) { change.setSchemaName(pk.getTable().getSchema().getName()); } change.setConstraintName(pk.getName()); change.setColumnNames(pk.getColumnNames()); if (control.getIncludeTablespace()) { change.setTablespace(pk.getTablespace()); } if (referenceDatabase instanceof MSSQLDatabase && pk.getBackingIndex() != null && pk.getBackingIndex().getClustered() != null && !pk.getBackingIndex().getClustered()) { change.setClustered(false); } if (comparisonDatabase instanceof OracleDatabase || (comparisonDatabase instanceof DB2Database && pk.getBackingIndex() != null && !comparisonDatabase.isSystemObject(pk.getBackingIndex()))) { Index backingIndex = pk.getBackingIndex(); if (backingIndex != null && backingIndex.getName() != null) { try { if (!control.getIncludeCatalog() && !control.getIncludeSchema()) { CatalogAndSchema schema = comparisonDatabase.getDefaultSchema().customize(comparisonDatabase); backingIndex .getTable() .setSchema( schema.getCatalogName(), schema .getSchemaName()); // set table schema so it is found in the correct schema } if (referenceDatabase.equals(comparisonDatabase) || !SnapshotGeneratorFactory.getInstance().has(backingIndex, comparisonDatabase)) { Change[] fixes = ChangeGeneratorFactory.getInstance() .fixMissing(backingIndex, control, referenceDatabase, comparisonDatabase); if (fixes != null) { for (Change fix : fixes) { if (fix != null) { returnList.add(fix); } } } } } catch (Exception e) { throw new UnexpectedLiquibaseException(e); } change.setForIndexName(backingIndex.getName()); Schema schema = backingIndex.getSchema(); if (schema != null) { if (control.getIncludeCatalog()) { change.setForIndexCatalogName(schema.getCatalogName()); } if (control.getIncludeSchema()) { change.setForIndexSchemaName(schema.getName()); } } } } control.setAlreadyHandledMissing(pk.getBackingIndex()); returnList.add(change); return returnList.toArray(new Change[returnList.size()]); }