private void generateChangeLog(final Database database, final CatalogAndSchema catalogAndSchema, final DiffToChangeLog changeLogWriter, PrintStream outputStream, final Set<Class<? extends DatabaseObject>> compareTypes) throws DatabaseException, IOException, ParserConfigurationException { @SuppressWarnings("unchecked") final SnapshotControl snapshotControl = new SnapshotControl(database, compareTypes.toArray(new Class[compareTypes.size()])); final CompareControl compareControl = new CompareControl(new CompareControl.SchemaComparison[]{ new CompareControl.SchemaComparison(catalogAndSchema, catalogAndSchema)}, compareTypes); final CatalogAndSchema[] compareControlSchemas = compareControl .getSchemas(CompareControl.DatabaseRole.REFERENCE); try { final DatabaseSnapshot referenceSnapshot = SnapshotGeneratorFactory.getInstance() .createSnapshot(compareControlSchemas, database, snapshotControl); final DatabaseSnapshot comparisonSnapshot = SnapshotGeneratorFactory.getInstance() .createSnapshot(compareControlSchemas, null, snapshotControl); final DiffResult diffResult = DiffGeneratorFactory.getInstance() .compare(referenceSnapshot, comparisonSnapshot, compareControl); changeLogWriter.setDiffResult(diffResult); changeLogWriter.print(outputStream); } catch (InvalidExampleException e) { throw new UnexpectedLiquibaseException(e); } }
protected String normalizeTableName(liquibase.structure.core.Table table, DatabaseSnapshot databaseSnapshot) { //Work around MySQL & case-insensitive dbs liquibase.structure.core.Table fkTable = databaseSnapshot.get(table); String fkTableName; if(fkTable != null) { fkTableName = fkTable.getName(); } else { logger.warn("Could not normalize table name: " + table.getName() + "; most probably this is a sign of a foreign key to another schema, which is not supported at the moment."); fkTableName = null; } return fkTableName; }
@Override protected DatabaseObject snapshotObject(DatabaseObject example, DatabaseSnapshot snapshot) throws DatabaseException, InvalidExampleException { return new Schema(snapshot.getDatabase().getDefaultCatalogName(), snapshot.getDatabase().getDefaultSchemaName()).setDefault(true); }
@Override public void check(Database database) throws CustomPreconditionFailedException, CustomPreconditionErrorException { Column column = new Column(this.columnNames); UniqueConstraint uniqueConstraint = new UniqueConstraint(this.constraintName, null, null, this.tableName, column); boolean markFailed = false; try { if (!SnapshotGeneratorFactory.getInstance().has(uniqueConstraint, database)) { markFailed = true; } } catch (Exception e) { throw new CustomPreconditionErrorException("custom precondition check errored", e); } if (markFailed) { throw new CustomPreconditionFailedException(this.constraintName + " doesn't exist"); } } }
@Override protected void addTo(DatabaseObject foundObject, DatabaseSnapshot snapshot) throws DatabaseException, InvalidExampleException { if (!snapshot.getSnapshotControl().shouldInclude(Table.class)) { return; } if (foundObject instanceof Schema) { Schema schema = (Schema) foundObject; HibernateDatabase database = (HibernateDatabase) snapshot.getDatabase(); Configuration cfg = database.getConfiguration(); Iterator<org.hibernate.mapping.Table> tableMappings = cfg.getTableMappings(); while (tableMappings.hasNext()) { org.hibernate.mapping.Table hibernateTable = tableMappings.next(); if (hibernateTable.isPhysicalTable()) { Table table = new Table().setName(hibernateTable.getName()); table.setSchema(schema); LOG.info("Found table " + table.getName()); schema.addDatabaseObject(table); } } } } }
@Override protected void addTo(DatabaseObject foundObject, DatabaseSnapshot snapshot) throws DatabaseException, InvalidExampleException { if (!snapshot.getSnapshotControl().shouldInclude(Index.class)) { return; } if (foundObject instanceof Table) { Table table = (Table) foundObject; org.hibernate.mapping.Table hibernateTable = findHibernateTable(table, snapshot); if (hibernateTable == null) { return; } Iterator indexIterator = hibernateTable.getIndexIterator(); while (indexIterator.hasNext()) { org.hibernate.mapping.Index hibernateIndex = (org.hibernate.mapping.Index) indexIterator.next(); Index index = new Index(); index.setTable(table); index.setName(hibernateIndex.getName()); Iterator columnIterator = hibernateIndex.getColumnIterator(); while (columnIterator.hasNext()) { org.hibernate.mapping.Column hibernateColumn = (org.hibernate.mapping.Column) columnIterator.next(); index.getColumns().add(new Column(hibernateColumn.getName()).setRelation(table)); } LOG.info("Found index " + index.getName()); table.getIndexes().add(index); } } }
@Override protected DatabaseObject snapshotObject(DatabaseObject example, DatabaseSnapshot snapshot) throws DatabaseException, InvalidExampleException { Column column = (Column) example; if (column.getType() == null) { //not the actual full version found with the table if (column.getRelation() == null) { throw new InvalidExampleException("No relation set on " + column); } Relation relation = snapshot.get(column.getRelation()); if (relation != null) { for (Column columnSnapshot : relation.getColumns()) { if (columnSnapshot.getName().equalsIgnoreCase(column.getName())) { return columnSnapshot; } } } snapshotColumn((Column) example, snapshot); return example; //did not find it } else { return example; } }
@Override public final DatabaseObject snapshot(DatabaseObject example, DatabaseSnapshot snapshot, SnapshotGeneratorChain chain) throws DatabaseException, InvalidExampleException { if (defaultFor != null && defaultFor.isAssignableFrom(example.getClass())) { DatabaseObject result = snapshotObject(example, snapshot); return result; } DatabaseObject chainResponse = chain.snapshot(example, snapshot); if (chainResponse == null) { return null; } if (addsTo() != null) { for (Class<? extends DatabaseObject> addType : addsTo()) { if (addType.isAssignableFrom(example.getClass())) { if (chainResponse != null) { addTo(chainResponse, snapshot); } } } } return chainResponse; }
public static String createDatabaseSnapshotAsString(DataSource ds) throws LiquibaseException, SQLException { try (Connection conn = ds.getConnection()) { Database database = DatabaseFactory.getInstance() .findCorrectDatabaseImplementation(new JdbcConnection(conn)); DatabaseSnapshot currentSnapshot = SnapshotGeneratorFactory .getInstance().createSnapshot(database.getDefaultSchema(), database, new SnapshotControl(database)); return SnapshotSerializerFactory.getInstance().getSerializer("json") .serialize(currentSnapshot, true); } } }
protected boolean isApplicable() throws CustomChangeException { try { String correctedTableName = database.correctObjectName("REALM", Table.class); if (SnapshotGeneratorFactory.getInstance().has(new Table().setName(correctedTableName), database)) { ResultSet resultSet = connection.createStatement().executeQuery("SELECT ID FROM " + getTableName(correctedTableName)); try { return (resultSet.next()); } finally { resultSet.close(); } } else { return false; } } catch (Exception e) { throw new CustomChangeException("Failed to check database availability", e); } }
@Override protected void addTo(DatabaseObject foundObject, DatabaseSnapshot snapshot) throws DatabaseException, InvalidExampleException { if (!snapshot.getSnapshotControl().shouldInclude(Sequence.class)) { return; HibernateDatabase database = (HibernateDatabase) snapshot.getDatabase(); MetadataImplementor metadata = (MetadataImplementor) database.getMetadata(); Iterator<PersistentClass> classMappings = metadata.getEntityBindings().iterator();
protected String normalizeTableName(liquibase.structure.core.Table table, DatabaseSnapshot databaseSnapshot) { //Work around MySQL & case-insensitive dbs liquibase.structure.core.Table fkTable = databaseSnapshot.get(table); String fkTableName; if(fkTable != null) { fkTableName = fkTable.getName(); } else { logger.warn("Could not normalize table name: " + table.getName() + "; most probably this is a sign of a foreign key to another schema, which is not supported at the moment."); fkTableName = null; } return fkTableName; }
@Override protected DatabaseObject snapshotObject(DatabaseObject example, DatabaseSnapshot snapshot) throws DatabaseException, InvalidExampleException { return new Catalog(snapshot.getDatabase().getDefaultCatalogName()).setDefault(true); }
private void generateChangeLog(final Database database, final CatalogAndSchema catalogAndSchema, final DiffToChangeLog changeLogWriter, PrintStream outputStream, final Set<Class<? extends DatabaseObject>> compareTypes) throws DatabaseException, IOException, ParserConfigurationException { @SuppressWarnings({"unchecked", "rawtypes"}) final SnapshotControl snapshotControl = new SnapshotControl(database, compareTypes.toArray(new Class[compareTypes.size()])); final CompareControl compareControl = new CompareControl(new CompareControl.SchemaComparison[]{ new CompareControl.SchemaComparison(catalogAndSchema, catalogAndSchema)}, compareTypes); final CatalogAndSchema[] compareControlSchemas = compareControl .getSchemas(CompareControl.DatabaseRole.REFERENCE); try { final DatabaseSnapshot referenceSnapshot = SnapshotGeneratorFactory.getInstance() .createSnapshot(compareControlSchemas, database, snapshotControl); final DatabaseSnapshot comparisonSnapshot = SnapshotGeneratorFactory.getInstance() .createSnapshot(compareControlSchemas, null, snapshotControl); final DiffResult diffResult = DiffGeneratorFactory.getInstance() .compare(referenceSnapshot, comparisonSnapshot, compareControl); changeLogWriter.setDiffResult(diffResult); changeLogWriter.print(outputStream); } catch (InvalidExampleException e) { throw new UnexpectedLiquibaseException(e); } }
protected boolean isApplicable() throws CustomChangeException { try { String correctedTableName = database.correctObjectName("REALM", Table.class); if (SnapshotGeneratorFactory.getInstance().has(new Table().setName(correctedTableName), database)) { ResultSet resultSet = connection.createStatement().executeQuery("SELECT ID FROM " + getTableName(correctedTableName)); try { return (resultSet.next()); } finally { resultSet.close(); } } else { return false; } } catch (Exception e) { throw new CustomChangeException("Failed to check database availability", e); } }
protected void syncTables(DatabaseSnapshot databaseSnapshot, Schema sourceSchema, Schema targetSchema) { logger.info("Synchronizing tables"); for (liquibase.structure.core.Table liquibaseTable : databaseSnapshot.get(liquibase.structure.core.Table.class)) { String tableName = liquibaseTable.getName(); logger.info("Processing table: {}", tableName); Table sourceTable = DatabaseLogic.findTableByNameIgnoreCase(sourceSchema, tableName); if(sourceTable == null) { logger.debug("Added new table: {}", tableName); sourceTable = new Table(); } Table targetTable = new Table(targetSchema); targetSchema.getTables().add(targetTable); targetTable.setTableName(tableName); logger.debug("Merging table attributes and annotations"); targetTable.setEntityName(sourceTable.getEntityName()); targetTable.setJavaClass(sourceTable.getJavaClass()); targetTable.setShortName(sourceTable.getShortName()); copyAnnotations(sourceTable, targetTable); syncColumns(liquibaseTable, sourceTable, targetTable); copySelectionProviders(sourceTable, targetTable); } }
protected org.hibernate.mapping.Table findHibernateTable(DatabaseObject example, DatabaseSnapshot snapshot) throws DatabaseException { HibernateDatabase database = (HibernateDatabase) snapshot.getDatabase(); MetadataImplementor metadata = (MetadataImplementor) database.getMetadata(); Collection<Table> tmapp = metadata.collectTableMappings(); Iterator<Table> tableMappings = tmapp.iterator(); while (tableMappings.hasNext()) { org.hibernate.mapping.Table hibernateTable = tableMappings.next(); if (hibernateTable.getName().equalsIgnoreCase(example.getName())) { return hibernateTable; } } return null; } }
List<Schema> schemas = connectionProvider.getDatabase().getSchemas(); SnapshotGeneratorFactory dsgf = SnapshotGeneratorFactory.getInstance(); catalog = sourceSchema.getCatalog(); SnapshotControl snapshotControl = new SnapshotControl(liquibaseDatabase); DatabaseSnapshot snapshot = dsgf.createSnapshot(new CatalogAndSchema(catalog, schemaName), liquibaseDatabase, snapshotControl);
protected void syncTables(DatabaseSnapshot databaseSnapshot, Schema sourceSchema, Schema targetSchema) { logger.info("Synchronizing tables"); for (liquibase.structure.core.Table liquibaseTable : databaseSnapshot.get(liquibase.structure.core.Table.class)) { String tableName = liquibaseTable.getName(); logger.info("Processing table: {}", tableName); Table sourceTable = DatabaseLogic.findTableByNameIgnoreCase(sourceSchema, tableName); if(sourceTable == null) { logger.debug("Added new table: {}", tableName); sourceTable = new Table(); } Table targetTable = new Table(targetSchema); targetSchema.getTables().add(targetTable); targetTable.setTableName(tableName); logger.debug("Merging table attributes and annotations"); targetTable.setEntityName(sourceTable.getEntityName()); targetTable.setJavaClass(sourceTable.getJavaClass()); targetTable.setShortName(sourceTable.getShortName()); copyAnnotations(sourceTable, targetTable); syncColumns(liquibaseTable, sourceTable, targetTable); copySelectionProviders(sourceTable, targetTable); } }
List<Schema> schemas = connectionProvider.getDatabase().getSchemas(); SnapshotGeneratorFactory dsgf = SnapshotGeneratorFactory.getInstance(); catalog = sourceSchema.getCatalog(); SnapshotControl snapshotControl = new SnapshotControl(liquibaseDatabase); DatabaseSnapshot snapshot = dsgf.createSnapshot(new CatalogAndSchema(catalog, schemaName), liquibaseDatabase, snapshotControl);