@Override public Change[] fixMissing( DatabaseObject missingObject, DiffOutputControl control, Database referenceDatabase, Database comparisonDatabase, ChangeGeneratorChain chain) { List<Change> returnList = new ArrayList<Change>(); UniqueConstraint uc = (UniqueConstraint) missingObject; if (uc.getTable() == null) { return null; } AddUniqueConstraintChange change = new AddUniqueConstraintChange(); change.setTableName(uc.getTable().getName()); if (uc.getBackingIndex() != null && control.getIncludeTablespace()) { change.setTablespace(uc.getBackingIndex().getTablespace()); } if (control.getIncludeCatalog()) { change.setCatalogName(uc.getTable().getSchema().getCatalogName()); } if (control.getIncludeSchema()) { change.setSchemaName(uc.getTable().getSchema().getName()); } change.setConstraintName(uc.getName()); change.setColumnNames(uc.getColumnNames()); change.setDeferrable(uc.isDeferrable() ? Boolean.TRUE : null); change.setInitiallyDeferred(uc.isInitiallyDeferred() ? Boolean.TRUE : null); change.setDisabled(uc.isDisabled() ? Boolean.TRUE : null); if (comparisonDatabase instanceof OracleDatabase) { Index backingIndex = uc.getBackingIndex(); if (backingIndex != null && backingIndex.getName() != null) { Change[] changes = ChangeGeneratorFactory.getInstance() .fixMissing(backingIndex, control, referenceDatabase, comparisonDatabase); if (changes != null) { returnList.addAll(Arrays.asList(changes)); 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()); } } } } } Index backingIndex = uc.getBackingIndex(); // if (backingIndex == null) { // Index exampleIndex = new Index().setTable(uc.getTable()); // for (String col : uc.getColumns()) { // exampleIndex.getColumns().add(col); // } // control.setAlreadyHandledMissing(exampleIndex); // } else { control.setAlreadyHandledMissing(backingIndex); // } returnList.add(change); return returnList.toArray(new Change[returnList.size()]); }
@Override protected void readIndexes( DatabaseSnapshot snapshot, String schema, DatabaseMetaData databaseMetaData) throws DatabaseException, SQLException { Database database = snapshot.getDatabase(); updateListeners("Reading indexes for " + database.toString() + " ..."); String query = "select aic.index_name, 3 AS TYPE, aic.table_name, aic.column_name, aic.column_position AS ORDINAL_POSITION, null AS FILTER_CONDITION, ai.tablespace_name AS TABLESPACE, ai.uniqueness FROM all_ind_columns aic, all_indexes ai WHERE aic.table_owner='" + database.convertRequestedSchemaToSchema(schema) + "' and aic.index_name = ai.index_name ORDER BY INDEX_NAME, ORDINAL_POSITION"; Statement statement = null; ResultSet rs = null; Map<String, Index> indexMap = null; try { statement = ((JdbcConnection) database.getConnection()).getUnderlyingConnection().createStatement(); rs = statement.executeQuery(query); indexMap = new HashMap<String, Index>(); while (rs.next()) { String indexName = convertFromDatabaseName(rs.getString("INDEX_NAME")); String tableName = rs.getString("TABLE_NAME"); String tableSpace = rs.getString("TABLESPACE"); String columnName = convertFromDatabaseName(rs.getString("COLUMN_NAME")); if (columnName == null) { // nothing to index, not sure why these come through sometimes continue; } short type = rs.getShort("TYPE"); boolean nonUnique; String uniqueness = rs.getString("UNIQUENESS"); if ("UNIQUE".equals(uniqueness)) { nonUnique = false; } else { nonUnique = true; } short position = rs.getShort("ORDINAL_POSITION"); String filterCondition = rs.getString("FILTER_CONDITION"); if (type == DatabaseMetaData.tableIndexStatistic) { continue; } Index index; if (indexMap.containsKey(indexName)) { index = indexMap.get(indexName); } else { index = new Index(); Table table = snapshot.getTable(tableName); if (table == null) { continue; // probably different schema } index.setTable(table); index.setTablespace(tableSpace); index.setName(indexName); index.setUnique(!nonUnique); index.setFilterCondition(filterCondition); indexMap.put(indexName, index); } for (int i = index.getColumns().size(); i < position; i++) { index.getColumns().add(null); } index.getColumns().set(position - 1, columnName); } } finally { JdbcUtils.closeResultSet(rs); JdbcUtils.closeStatement(statement); } for (Map.Entry<String, Index> entry : indexMap.entrySet()) { snapshot.getIndexes().add(entry.getValue()); } /* * marks indexes as "associated with" instead of "remove it" * Index should have associations with: * foreignKey, primaryKey or uniqueConstraint * */ for (Index index : snapshot.getIndexes()) { for (PrimaryKey pk : snapshot.getPrimaryKeys()) { if (index.getTable().getName().equalsIgnoreCase(pk.getTable().getName()) && index.getColumnNames().equals(pk.getColumnNames())) { index.addAssociatedWith(Index.MARK_PRIMARY_KEY); } } for (ForeignKey fk : snapshot.getForeignKeys()) { if (index.getTable().getName().equalsIgnoreCase(fk.getForeignKeyTable().getName()) && index.getColumnNames().equals(fk.getForeignKeyColumns())) { index.addAssociatedWith(Index.MARK_FOREIGN_KEY); } } for (UniqueConstraint uc : snapshot.getUniqueConstraints()) { if (index.getTable().getName().equalsIgnoreCase(uc.getTable().getName()) && index.getColumnNames().equals(uc.getColumnNames())) { index.addAssociatedWith(Index.MARK_UNIQUE_CONSTRAINT); } } } }