From 2fcc701e5fab7b1afdff647b82342c8d6965e295 Mon Sep 17 00:00:00 2001 From: Bruno Monteiro Date: Fri, 2 May 2025 10:33:25 +0100 Subject: [PATCH 01/11] First changes for PRF rename --- .../morf/metadata/AdditionalMetadata.java | 10 +++ .../upgrade/GraphBasedUpgradeBuilder.java | 1 + .../GraphBasedUpgradeSchemaChangeVisitor.java | 35 ++++++++- .../morf/upgrade/InlineTableUpgrader.java | 31 +++++++- .../alfasoftware/morf/upgrade/Upgrade.java | 2 +- ...tGraphBasedUpgradeSchemaChangeVisitor.java | 8 +- .../morf/upgrade/TestInlineTableUpgrader.java | 8 +- .../TestDatabaseUpgradeIntegration.java | 54 ++++++++++++- .../upgrade/v1_0_0/AddIndex.java | 17 +++++ .../jdbc/oracle/OracleMetaDataProvider.java | 76 +++++++++++++++++-- .../morf/testing/UpgradeTestHelper.java | 3 +- 11 files changed, 222 insertions(+), 23 deletions(-) create mode 100644 morf-integration-test/src/test/java/org/alfasoftware/morf/integration/testdatabaseupgradeintegration/upgrade/v1_0_0/AddIndex.java diff --git a/morf-core/src/main/java/org/alfasoftware/morf/metadata/AdditionalMetadata.java b/morf-core/src/main/java/org/alfasoftware/morf/metadata/AdditionalMetadata.java index 081b75688..46cc7bb2a 100644 --- a/morf-core/src/main/java/org/alfasoftware/morf/metadata/AdditionalMetadata.java +++ b/morf-core/src/main/java/org/alfasoftware/morf/metadata/AdditionalMetadata.java @@ -1,5 +1,6 @@ package org.alfasoftware.morf.metadata; +import java.util.List; import java.util.Map; import org.apache.commons.lang3.NotImplementedException; @@ -16,4 +17,13 @@ public interface AdditionalMetadata extends Schema { default Map primaryKeyIndexNames() { throw new NotImplementedException("Not implemented yet."); } + + /** + * The names of all the ignored indexes in the database, + * maps from table name into a List of Index. + * @return A collection of the names of all the ignored indexes. + */ + default Map> ignoredIndexes() { + return Map.of(); + } } diff --git a/morf-core/src/main/java/org/alfasoftware/morf/upgrade/GraphBasedUpgradeBuilder.java b/morf-core/src/main/java/org/alfasoftware/morf/upgrade/GraphBasedUpgradeBuilder.java index 9691e6b31..d4bfe6b2d 100644 --- a/morf-core/src/main/java/org/alfasoftware/morf/upgrade/GraphBasedUpgradeBuilder.java +++ b/morf-core/src/main/java/org/alfasoftware/morf/upgrade/GraphBasedUpgradeBuilder.java @@ -101,6 +101,7 @@ public GraphBasedUpgrade prepareGraphBasedUpgrade(List initialisationSql GraphBasedUpgradeSchemaChangeVisitor visitor = visitorFactory.create( sourceSchema, + connectionResources.openSchemaResource(), connectionResources.sqlDialect(), idTable, nodes.stream().collect(Collectors.toMap(GraphBasedUpgradeNode::getName, Function.identity()))); diff --git a/morf-core/src/main/java/org/alfasoftware/morf/upgrade/GraphBasedUpgradeSchemaChangeVisitor.java b/morf-core/src/main/java/org/alfasoftware/morf/upgrade/GraphBasedUpgradeSchemaChangeVisitor.java index 78709e01c..7b967face 100644 --- a/morf-core/src/main/java/org/alfasoftware/morf/upgrade/GraphBasedUpgradeSchemaChangeVisitor.java +++ b/morf-core/src/main/java/org/alfasoftware/morf/upgrade/GraphBasedUpgradeSchemaChangeVisitor.java @@ -1,11 +1,16 @@ package org.alfasoftware.morf.upgrade; import java.util.Collection; +import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.UUID; import org.alfasoftware.morf.jdbc.SqlDialect; +import org.alfasoftware.morf.metadata.AdditionalMetadata; +import org.alfasoftware.morf.metadata.Index; import org.alfasoftware.morf.metadata.Schema; +import org.alfasoftware.morf.metadata.SchemaResource; import org.alfasoftware.morf.metadata.Table; import org.alfasoftware.morf.sql.Statement; @@ -19,6 +24,7 @@ class GraphBasedUpgradeSchemaChangeVisitor implements SchemaChangeVisitor { private Schema sourceSchema; + private final SchemaResource schemaResource; private final SqlDialect sqlDialect; private final Table idTable; private final TableNameResolver tracker; @@ -30,13 +36,15 @@ class GraphBasedUpgradeSchemaChangeVisitor implements SchemaChangeVisitor { * Default constructor. * * @param sourceSchema schema prior to upgrade step. + * @param schemaResource schema resource * @param sqlDialect dialect to generate statements for the target database. * @param idTable table for id generation. * @param upgradeNodes all the {@link GraphBasedUpgradeNode} instances in the * upgrade for which the visitor will generate statements */ - GraphBasedUpgradeSchemaChangeVisitor(Schema sourceSchema, SqlDialect sqlDialect, Table idTable, Map upgradeNodes) { + GraphBasedUpgradeSchemaChangeVisitor(Schema sourceSchema, SchemaResource schemaResource, SqlDialect sqlDialect, Table idTable, Map upgradeNodes) { this.sourceSchema = sourceSchema; + this.schemaResource = schemaResource; this.sqlDialect = sqlDialect; this.idTable = idTable; this.upgradeNodes = upgradeNodes; @@ -77,7 +85,26 @@ public void visit(RemoveTable removeTable) { @Override public void visit(AddIndex addIndex) { sourceSchema = addIndex.apply(sourceSchema); - writeStatements(sqlDialect.addIndexStatements(sourceSchema.getTable(addIndex.getTableName()), addIndex.getNewIndex())); + Index foundIndex = null; + if (schemaResource != null && schemaResource.getAdditionalMetadata().isPresent()) { + AdditionalMetadata additionalMetadata = schemaResource.getAdditionalMetadata().get(); + String tableName = addIndex.getTableName().toUpperCase(Locale.ROOT); + if (additionalMetadata.ignoredIndexes().containsKey(tableName)) { + List tableIgnoredIndexes = additionalMetadata.ignoredIndexes().get(tableName); + for (Index index : tableIgnoredIndexes) { + if (index.columnNames().equals(addIndex.getNewIndex().columnNames())) { + foundIndex = index; + break; + } + } + } + } + + if (foundIndex != null) { + writeStatements(sqlDialect.renameIndexStatements(sourceSchema.getTable(addIndex.getTableName()), foundIndex.getName(), addIndex.getNewIndex().getName())); + } else { + writeStatements(sqlDialect.addIndexStatements(sourceSchema.getTable(addIndex.getTableName()), addIndex.getNewIndex())); + } } @@ -248,9 +275,9 @@ static class GraphBasedUpgradeSchemaChangeVisitorFactory { * which the visitor will generate statements * @return new {@link GraphBasedUpgradeSchemaChangeVisitor} instance */ - GraphBasedUpgradeSchemaChangeVisitor create(Schema sourceSchema, SqlDialect sqlDialect, Table idTable, + GraphBasedUpgradeSchemaChangeVisitor create(Schema sourceSchema, SchemaResource schemaResource, SqlDialect sqlDialect, Table idTable, Map upgradeNodes) { - return new GraphBasedUpgradeSchemaChangeVisitor(sourceSchema, sqlDialect, idTable, upgradeNodes); + return new GraphBasedUpgradeSchemaChangeVisitor(sourceSchema, schemaResource, sqlDialect, idTable, upgradeNodes); } } } diff --git a/morf-core/src/main/java/org/alfasoftware/morf/upgrade/InlineTableUpgrader.java b/morf-core/src/main/java/org/alfasoftware/morf/upgrade/InlineTableUpgrader.java index 0f4d9a96a..bd8cc61a2 100755 --- a/morf-core/src/main/java/org/alfasoftware/morf/upgrade/InlineTableUpgrader.java +++ b/morf-core/src/main/java/org/alfasoftware/morf/upgrade/InlineTableUpgrader.java @@ -17,10 +17,15 @@ import java.util.Collection; import java.util.Collections; +import java.util.List; +import java.util.Locale; import java.util.UUID; import org.alfasoftware.morf.jdbc.SqlDialect; +import org.alfasoftware.morf.metadata.AdditionalMetadata; +import org.alfasoftware.morf.metadata.Index; import org.alfasoftware.morf.metadata.Schema; +import org.alfasoftware.morf.metadata.SchemaResource; import org.alfasoftware.morf.metadata.Table; import org.alfasoftware.morf.sql.Statement; @@ -31,6 +36,7 @@ */ public class InlineTableUpgrader implements SchemaChangeVisitor { + private final SchemaResource schemaResource; private Schema currentSchema; private final SqlDialect sqlDialect; private final SqlStatementWriter sqlStatementWriter; @@ -42,11 +48,13 @@ public class InlineTableUpgrader implements SchemaChangeVisitor { * Default constructor. * * @param startSchema schema prior to upgrade step. + * @param schemaResource schema resource * @param sqlDialect Dialect to generate statements for the target database. * @param sqlStatementWriter recipient for all upgrade SQL statements. * @param idTable table for id generation. */ - public InlineTableUpgrader(Schema startSchema, SqlDialect sqlDialect, SqlStatementWriter sqlStatementWriter, Table idTable) { + public InlineTableUpgrader(Schema startSchema, SchemaResource schemaResource, SqlDialect sqlDialect, SqlStatementWriter sqlStatementWriter, Table idTable) { + this.schemaResource = schemaResource; this.currentSchema = startSchema; this.sqlDialect = sqlDialect; this.sqlStatementWriter = sqlStatementWriter; @@ -99,7 +107,26 @@ public void visit(RemoveTable removeTable) { @Override public void visit(AddIndex addIndex) { currentSchema = addIndex.apply(currentSchema); - writeStatements(sqlDialect.addIndexStatements(currentSchema.getTable(addIndex.getTableName()), addIndex.getNewIndex())); + Index foundIndex = null; + if (schemaResource != null && schemaResource.getAdditionalMetadata().isPresent()) { + AdditionalMetadata additionalMetadata = schemaResource.getAdditionalMetadata().get(); + String tableName = addIndex.getTableName().toUpperCase(Locale.ROOT); + if (additionalMetadata.ignoredIndexes().containsKey(tableName)) { + List tableIgnoredIndexes = additionalMetadata.ignoredIndexes().get(tableName); + for (Index index : tableIgnoredIndexes) { + if (index.columnNames().equals(addIndex.getNewIndex().columnNames())) { + foundIndex = index; + break; + } + } + } + } + + if (foundIndex != null) { + writeStatements(sqlDialect.renameIndexStatements(currentSchema.getTable(addIndex.getTableName()), foundIndex.getName(), addIndex.getNewIndex().getName())); + } else { + writeStatements(sqlDialect.addIndexStatements(currentSchema.getTable(addIndex.getTableName()), addIndex.getNewIndex())); + } } diff --git a/morf-core/src/main/java/org/alfasoftware/morf/upgrade/Upgrade.java b/morf-core/src/main/java/org/alfasoftware/morf/upgrade/Upgrade.java index 068b28805..ed3401e0d 100755 --- a/morf-core/src/main/java/org/alfasoftware/morf/upgrade/Upgrade.java +++ b/morf-core/src/main/java/org/alfasoftware/morf/upgrade/Upgrade.java @@ -249,7 +249,7 @@ else if (upgradeAuditCount != getUpgradeAuditRowCount(upgradeAuditRowProcessor)) // if (!schemaChangeSequence.getUpgradeSteps().isEmpty()) { // Run the upgrader over all the ElementarySchemaChanges in the upgrade steps - InlineTableUpgrader upgrader = new InlineTableUpgrader(sourceSchema, dialect, new SqlStatementWriter() { + InlineTableUpgrader upgrader = new InlineTableUpgrader(sourceSchema, connectionResources.openSchemaResource(), dialect, new SqlStatementWriter() { @Override public void writeSql(Collection sql) { upgradeStatements.addAll(sql); diff --git a/morf-core/src/test/java/org/alfasoftware/morf/upgrade/TestGraphBasedUpgradeSchemaChangeVisitor.java b/morf-core/src/test/java/org/alfasoftware/morf/upgrade/TestGraphBasedUpgradeSchemaChangeVisitor.java index c64d49592..252d72ae7 100644 --- a/morf-core/src/test/java/org/alfasoftware/morf/upgrade/TestGraphBasedUpgradeSchemaChangeVisitor.java +++ b/morf-core/src/test/java/org/alfasoftware/morf/upgrade/TestGraphBasedUpgradeSchemaChangeVisitor.java @@ -21,6 +21,7 @@ import org.alfasoftware.morf.metadata.Column; import org.alfasoftware.morf.metadata.Index; import org.alfasoftware.morf.metadata.Schema; +import org.alfasoftware.morf.metadata.SchemaResource; import org.alfasoftware.morf.metadata.Sequence; import org.alfasoftware.morf.metadata.Table; import org.alfasoftware.morf.sql.SelectStatement; @@ -49,6 +50,9 @@ public class TestGraphBasedUpgradeSchemaChangeVisitor { @Mock private SqlDialect sqlDialect; + @Mock + private SchemaResource schemaResource; + @Mock private Table idTable; @@ -70,7 +74,7 @@ public void setup() { nodes.put(U1.class.getName(), n1); nodes.put(U2.class.getName(), n2); - visitor = new GraphBasedUpgradeSchemaChangeVisitor(sourceSchema, sqlDialect, idTable, nodes); + visitor = new GraphBasedUpgradeSchemaChangeVisitor(sourceSchema, schemaResource, sqlDialect, idTable, nodes); } @@ -415,7 +419,7 @@ public void testFactory() { GraphBasedUpgradeSchemaChangeVisitorFactory factory = new GraphBasedUpgradeSchemaChangeVisitorFactory(); // when - GraphBasedUpgradeSchemaChangeVisitor created = factory.create(sourceSchema, sqlDialect, idTable, nodes); + GraphBasedUpgradeSchemaChangeVisitor created = factory.create(sourceSchema, schemaResource, sqlDialect, idTable, nodes); // then assertNotNull(created); diff --git a/morf-core/src/test/java/org/alfasoftware/morf/upgrade/TestInlineTableUpgrader.java b/morf-core/src/test/java/org/alfasoftware/morf/upgrade/TestInlineTableUpgrader.java index 80563869b..9b334cb0f 100755 --- a/morf-core/src/test/java/org/alfasoftware/morf/upgrade/TestInlineTableUpgrader.java +++ b/morf-core/src/test/java/org/alfasoftware/morf/upgrade/TestInlineTableUpgrader.java @@ -21,10 +21,10 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; -import static org.mockito.ArgumentMatchers.nullable; -import static org.mockito.BDDMockito.given; import static org.mockito.ArgumentMatchers.anyCollection; import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.ArgumentMatchers.nullable; +import static org.mockito.BDDMockito.given; import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; @@ -36,6 +36,7 @@ import org.alfasoftware.morf.metadata.Column; import org.alfasoftware.morf.metadata.Index; import org.alfasoftware.morf.metadata.Schema; +import org.alfasoftware.morf.metadata.SchemaResource; import org.alfasoftware.morf.metadata.Sequence; import org.alfasoftware.morf.metadata.Table; import org.alfasoftware.morf.sql.DeleteStatement; @@ -68,7 +69,8 @@ public void setUp() { schema = mock(Schema.class); sqlDialect = mock(SqlDialect.class); sqlStatementWriter = mock(SqlStatementWriter.class); - upgrader = new InlineTableUpgrader(schema, sqlDialect, sqlStatementWriter, SqlDialect.IdTable.withDeterministicName(ID_TABLE_NAME)); + SchemaResource schemaResource = mock(SchemaResource.class); + upgrader = new InlineTableUpgrader(schema, schemaResource, sqlDialect, sqlStatementWriter, SqlDialect.IdTable.withDeterministicName(ID_TABLE_NAME)); } diff --git a/morf-integration-test/src/test/java/org/alfasoftware/morf/integration/TestDatabaseUpgradeIntegration.java b/morf-integration-test/src/test/java/org/alfasoftware/morf/integration/TestDatabaseUpgradeIntegration.java index c569554a0..ce0674b52 100755 --- a/morf-integration-test/src/test/java/org/alfasoftware/morf/integration/TestDatabaseUpgradeIntegration.java +++ b/morf-integration-test/src/test/java/org/alfasoftware/morf/integration/TestDatabaseUpgradeIntegration.java @@ -49,7 +49,12 @@ import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Locale; +import java.util.Map; import java.util.stream.Collectors; import javax.sql.DataSource; @@ -66,6 +71,7 @@ import org.alfasoftware.morf.integration.testdatabaseupgradeintegration.upgrade.v1_0_0.AddColumnWithoutDropDefaultValue; import org.alfasoftware.morf.integration.testdatabaseupgradeintegration.upgrade.v1_0_0.AddDataToAutonumberedColumn; import org.alfasoftware.morf.integration.testdatabaseupgradeintegration.upgrade.v1_0_0.AddDataToIdColumn; +import org.alfasoftware.morf.integration.testdatabaseupgradeintegration.upgrade.v1_0_0.AddIndex; import org.alfasoftware.morf.integration.testdatabaseupgradeintegration.upgrade.v1_0_0.AddPrimaryKeyColumns; import org.alfasoftware.morf.integration.testdatabaseupgradeintegration.upgrade.v1_0_0.ChangeColumnDataType; import org.alfasoftware.morf.integration.testdatabaseupgradeintegration.upgrade.v1_0_0.ChangeColumnLengthAndCase; @@ -103,9 +109,9 @@ import org.alfasoftware.morf.metadata.DataType; import org.alfasoftware.morf.metadata.Schema; import org.alfasoftware.morf.metadata.SchemaHomology; -import org.alfasoftware.morf.metadata.Sequence; import org.alfasoftware.morf.metadata.SchemaHomology.CollectingDifferenceWriter; import org.alfasoftware.morf.metadata.SchemaUtils.TableBuilder; +import org.alfasoftware.morf.metadata.Sequence; import org.alfasoftware.morf.metadata.Table; import org.alfasoftware.morf.metadata.View; import org.alfasoftware.morf.sql.InsertStatement; @@ -114,11 +120,11 @@ import org.alfasoftware.morf.testing.DatabaseSchemaManager; import org.alfasoftware.morf.testing.DatabaseSchemaManager.TruncationBehavior; import org.alfasoftware.morf.testing.TestingDataSourceModule; -import org.alfasoftware.morf.upgrade.ViewDeploymentValidator; import org.alfasoftware.morf.upgrade.LoggingSqlScriptVisitor; import org.alfasoftware.morf.upgrade.Upgrade; import org.alfasoftware.morf.upgrade.UpgradePathFinder.NoUpgradePathExistsException; import org.alfasoftware.morf.upgrade.UpgradeStep; +import org.alfasoftware.morf.upgrade.ViewDeploymentValidator; import org.apache.commons.lang3.StringUtils; import org.junit.After; import org.junit.Before; @@ -351,7 +357,24 @@ public void before() { schemaManager.get().dropAllSequences(); schemaManager.get().dropAllViews(); schemaManager.get().dropAllTables(); - schemaManager.get().mutateToSupportSchema(schema, TruncationBehavior.ALWAYS); + + // add the PRF index - it isn't added in shared variable because then it wouldn't be possible to compare that + // schema with the one upgraded as the PRF index is ignored when reading the database definition. + // if left there, the comparison would expect to see a PRF index and it doesn't. + Table tableWithNewAddIndex = table("BasicTableWithIndex") + .columns( + column("stringCol", DataType.STRING, 20).primaryKey(), + column("nullableStringCol", DataType.STRING, 10).nullable(), + column("decimalTenZeroCol", DataType.DECIMAL, 10), + column("decimalNineFiveCol", DataType.DECIMAL, 9, 5), + column("bigIntegerCol", DataType.BIG_INTEGER), + column("nullableBigIntegerCol", DataType.BIG_INTEGER).nullable()) + .indexes( + index("WrongIndexName_1").columns("bigIntegerCol"), + index("BasicTableWithIndex_PRF1").columns("decimalTenZeroCol")); + Schema schema1 = replaceTablesInSchema(tableWithNewAddIndex); + + schemaManager.get().mutateToSupportSchema(schema1, TruncationBehavior.ALWAYS); new DataSetConnector(dataSet, databaseDataSetConsumer.get()).connect(); } @@ -526,6 +549,29 @@ public void testAddPrimaryKeyColumns() { } + /** + * Test that adding primary key columns to a table with no primary key columns work + */ + @Test + public void testAddIndexWithExistingPRFIndex() { + Table tableWithNewAddIndex = table("BasicTableWithIndex") + .columns( + column("stringCol", DataType.STRING, 20).primaryKey(), + column("nullableStringCol", DataType.STRING, 10).nullable(), + column("decimalTenZeroCol", DataType.DECIMAL, 10), + column("decimalNineFiveCol", DataType.DECIMAL, 9, 5), + column("bigIntegerCol", DataType.BIG_INTEGER), + column("nullableBigIntegerCol", DataType.BIG_INTEGER).nullable()) + .indexes( + index("WrongIndexName_1").columns("bigIntegerCol"), + index("BasicTableWithIndex_1").columns("decimalTenZeroCol")); + + Schema reAdded = replaceTablesInSchema(tableWithNewAddIndex); + + verifyUpgrade(reAdded, AddIndex.class); + } + + /** * Test that removing a column from a composite primary key works. * diff --git a/morf-integration-test/src/test/java/org/alfasoftware/morf/integration/testdatabaseupgradeintegration/upgrade/v1_0_0/AddIndex.java b/morf-integration-test/src/test/java/org/alfasoftware/morf/integration/testdatabaseupgradeintegration/upgrade/v1_0_0/AddIndex.java new file mode 100644 index 000000000..59411bf34 --- /dev/null +++ b/morf-integration-test/src/test/java/org/alfasoftware/morf/integration/testdatabaseupgradeintegration/upgrade/v1_0_0/AddIndex.java @@ -0,0 +1,17 @@ +package org.alfasoftware.morf.integration.testdatabaseupgradeintegration.upgrade.v1_0_0; + +import static org.alfasoftware.morf.metadata.SchemaUtils.index; + +import org.alfasoftware.morf.upgrade.DataEditor; +import org.alfasoftware.morf.upgrade.SchemaEditor; +import org.alfasoftware.morf.upgrade.Sequence; +import org.alfasoftware.morf.upgrade.UUID; + +@Sequence(1) +@UUID("1ade56c0-b1d7-11e2-9e96-080020011112") +public class AddIndex extends AbstractTestUpgradeStep { + @Override + public void execute(SchemaEditor schema, DataEditor data) { + schema.addIndex("BasicTableWithIndex", index("BasicTableWithIndex_1").columns("decimalTenZeroCol")); + } +} diff --git a/morf-oracle/src/main/java/org/alfasoftware/morf/jdbc/oracle/OracleMetaDataProvider.java b/morf-oracle/src/main/java/org/alfasoftware/morf/jdbc/oracle/OracleMetaDataProvider.java index 6a437f116..40ab584cb 100755 --- a/morf-oracle/src/main/java/org/alfasoftware/morf/jdbc/oracle/OracleMetaDataProvider.java +++ b/morf-oracle/src/main/java/org/alfasoftware/morf/jdbc/oracle/OracleMetaDataProvider.java @@ -85,7 +85,7 @@ public class OracleMetaDataProvider implements AdditionalMetadata { private final Connection connection; private final String schemaName; private Map primaryKeyIndexNames; - + private Map> ignoredIndexesMap; /** * Construct a new meta data provider. @@ -163,6 +163,16 @@ public Map primaryKeyIndexNames() { } + @Override + public Map> ignoredIndexes() { + if (ignoredIndexesMap != null) { + return ignoredIndexesMap; + } + tableMap(); + return ignoredIndexesMap; + } + + /** * A table name reading method which is more efficient than the Oracle driver meta-data version. * @@ -325,6 +335,7 @@ private void handleTableColumnRow(final Map> primaryKeys, // -- Stage 3: find the index names... // primaryKeyIndexNames = Maps.newHashMap(); + ignoredIndexesMap = Maps.newHashMap(); final String getIndexNamesSql = "select table_name, index_name, uniqueness, status from ALL_INDEXES where owner=? order by table_name, index_name"; runSQL(getIndexNamesSql, new ResultSetHandler() { @Override @@ -343,11 +354,6 @@ public void handle(ResultSet resultSet) throws SQLException { continue; } - if (DatabaseMetaDataProviderUtils.shouldIgnoreIndex(indexName)) { - log.info("Ignoring index: [" + indexName + "]"); - continue; - } - final boolean unique = "UNIQUE".equals(uniqueness); boolean isValid = isValid(status, indexName, indexPartitions); @@ -376,6 +382,41 @@ public void handle(ResultSet resultSet) throws SQLException { final String indexNameFinal = indexName; + if (DatabaseMetaDataProviderUtils.shouldIgnoreIndex(indexName)) { + Index ignoredIndex = new Index() { + private final List columnNames = new ArrayList<>(); + + @Override + public boolean isUnique() { + return unique; + } + + + @Override + public String getName() { + return indexNameFinal; + } + + + @Override + public List columnNames() { + return columnNames; + } + + + @Override + public String toString() { + return this.toStringHelper(); + } + }; + if (ignoredIndexesMap.containsKey(tableName)) { + ignoredIndexesMap.get(tableName).add(ignoredIndex); + } else { + ignoredIndexesMap.put(tableName, List.of(ignoredIndex)); + } + continue; + } + currentTable.indexes().add(new Index() { private final List columnNames = new ArrayList<>(); @@ -447,6 +488,29 @@ public void handle(ResultSet resultSet) throws SQLException { } if (DatabaseMetaDataProviderUtils.shouldIgnoreIndex(indexName)) { + Index lastIndex = null; + for (Index currentIndex : ignoredIndexesMap.get(tableName)) { + if (currentIndex.getName().equalsIgnoreCase(indexName)) { + lastIndex = currentIndex; + break; + } + } + + if (lastIndex == null) { + log.warn(String.format("Ignoring index details for index [%s] on table [%s] as no index definition exists", indexName, tableName)); + continue; + } + + // Correct the case on the column name + for (Column currentColumn : currentTable.columns()) { + if (currentColumn.getName().equalsIgnoreCase(columnName)) { + columnName = currentColumn.getName(); + break; + } + } + + lastIndex.columnNames().add(columnName); + continue; } diff --git a/morf-testsupport/src/main/java/org/alfasoftware/morf/testing/UpgradeTestHelper.java b/morf-testsupport/src/main/java/org/alfasoftware/morf/testing/UpgradeTestHelper.java index 712aab55d..786ad63c0 100755 --- a/morf-testsupport/src/main/java/org/alfasoftware/morf/testing/UpgradeTestHelper.java +++ b/morf-testsupport/src/main/java/org/alfasoftware/morf/testing/UpgradeTestHelper.java @@ -117,7 +117,8 @@ public void testUpgrades(Schema finalSchema, Iterable sqlScript = Lists.newLinkedList(); // Upgrader, which captures the SQL as a script - InlineTableUpgrader inlineTableUpgrader = new InlineTableUpgrader(fromSchema, connectionResources.sqlDialect(), new SqlStatementWriter() { + InlineTableUpgrader inlineTableUpgrader = new InlineTableUpgrader(fromSchema, connectionResources.openSchemaResource(), + connectionResources.sqlDialect(), new SqlStatementWriter() { @Override public void writeSql(Collection sql) { sqlScript.addAll(sql); From 7dbf733286e87ee5ac37a335a40f0293b3d6e4a3 Mon Sep 17 00:00:00 2001 From: Bruno Monteiro Date: Fri, 2 May 2025 17:41:04 +0100 Subject: [PATCH 02/11] Add coverage for new code to GraphBasedUpgradeSchemaChangeVisitor, InlineTableUpgrader, OracleMetaDataProvider. --- ...tGraphBasedUpgradeSchemaChangeVisitor.java | 45 +++++++++++++ .../morf/upgrade/TestInlineTableUpgrader.java | 46 ++++++++++++- .../oracle/TestOracleMetaDataProvider.java | 65 +++++++++++++++++++ 3 files changed, 155 insertions(+), 1 deletion(-) diff --git a/morf-core/src/test/java/org/alfasoftware/morf/upgrade/TestGraphBasedUpgradeSchemaChangeVisitor.java b/morf-core/src/test/java/org/alfasoftware/morf/upgrade/TestGraphBasedUpgradeSchemaChangeVisitor.java index 252d72ae7..665daa90f 100644 --- a/morf-core/src/test/java/org/alfasoftware/morf/upgrade/TestGraphBasedUpgradeSchemaChangeVisitor.java +++ b/morf-core/src/test/java/org/alfasoftware/morf/upgrade/TestGraphBasedUpgradeSchemaChangeVisitor.java @@ -6,18 +6,23 @@ import static org.mockito.ArgumentMatchers.anyList; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.ArgumentMatchers.nullable; +import static org.mockito.BDDMockito.given; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import java.util.Collections; import java.util.HashMap; import java.util.List; +import java.util.Locale; import java.util.Map; +import java.util.Optional; import java.util.UUID; import org.alfasoftware.morf.jdbc.DatabaseType; import org.alfasoftware.morf.jdbc.SqlDialect; +import org.alfasoftware.morf.metadata.AdditionalMetadata; import org.alfasoftware.morf.metadata.Column; import org.alfasoftware.morf.metadata.Index; import org.alfasoftware.morf.metadata.Schema; @@ -129,6 +134,46 @@ public void testAddIndexVisit() { } + /** + * Test method for {@link org.alfasoftware.morf.upgrade.InlineTableUpgrader#visit(org.alfasoftware.morf.upgrade.AddIndex)}. + */ + @Test + public void testVisitAddIndexWithPRFIndex() { + // given + visitor.startStep(U1.class); + + String ID_TABLE_NAME = "IdTableName"; + Index newIndex = mock(Index.class); + when(newIndex.getName()).thenReturn(ID_TABLE_NAME + "_1"); + when(newIndex.columnNames()).thenReturn(Collections.singletonList("column_1")); + + AddIndex addIndex = mock(AddIndex.class); + given(addIndex.apply(sourceSchema)).willReturn(sourceSchema); + when(addIndex.getTableName()).thenReturn(ID_TABLE_NAME); + when(addIndex.getNewIndex()).thenReturn(newIndex); + + AdditionalMetadata additionalMetadata = mock(AdditionalMetadata.class); + when(schemaResource.getAdditionalMetadata()).thenReturn(Optional.of(additionalMetadata)); + Index indexPrf = mock(Index.class); + when(indexPrf.getName()).thenReturn(ID_TABLE_NAME + "_PRF1"); + when(indexPrf.columnNames()).thenReturn(List.of("column_1")); + + Map> ignoredIndexes = new HashMap<>(); + ignoredIndexes.put(ID_TABLE_NAME.toUpperCase(Locale.ROOT), Collections.singletonList(indexPrf)); + when(additionalMetadata.ignoredIndexes()).thenReturn(ignoredIndexes); + + when(sqlDialect.renameIndexStatements(nullable(Table.class), eq(ID_TABLE_NAME + "_PRF1"), eq(ID_TABLE_NAME + "_1"))).thenReturn(STATEMENTS); + + // when + visitor.visit(addIndex); + + // then + verify(addIndex).apply(sourceSchema); + verify(sqlDialect).renameIndexStatements(nullable(Table.class), eq(ID_TABLE_NAME + "_PRF1"), eq(ID_TABLE_NAME + "_1")); + verify(n1).addAllUpgradeStatements(ArgumentMatchers.argThat(c-> c.containsAll(STATEMENTS))); + } + + @Test public void testAddColumnVisit() { // given diff --git a/morf-core/src/test/java/org/alfasoftware/morf/upgrade/TestInlineTableUpgrader.java b/morf-core/src/test/java/org/alfasoftware/morf/upgrade/TestInlineTableUpgrader.java index 9b334cb0f..8474e91fb 100755 --- a/morf-core/src/test/java/org/alfasoftware/morf/upgrade/TestInlineTableUpgrader.java +++ b/morf-core/src/test/java/org/alfasoftware/morf/upgrade/TestInlineTableUpgrader.java @@ -31,8 +31,16 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Optional; + import org.alfasoftware.morf.jdbc.DatabaseType; import org.alfasoftware.morf.jdbc.SqlDialect; +import org.alfasoftware.morf.metadata.AdditionalMetadata; import org.alfasoftware.morf.metadata.Column; import org.alfasoftware.morf.metadata.Index; import org.alfasoftware.morf.metadata.Schema; @@ -58,6 +66,7 @@ public class TestInlineTableUpgrader { private InlineTableUpgrader upgrader; private Schema schema; + private SchemaResource schemaResource; private SqlDialect sqlDialect; private SqlStatementWriter sqlStatementWriter; @@ -69,7 +78,7 @@ public void setUp() { schema = mock(Schema.class); sqlDialect = mock(SqlDialect.class); sqlStatementWriter = mock(SqlStatementWriter.class); - SchemaResource schemaResource = mock(SchemaResource.class); + schemaResource = mock(SchemaResource.class); upgrader = new InlineTableUpgrader(schema, schemaResource, sqlDialect, sqlStatementWriter, SqlDialect.IdTable.withDeterministicName(ID_TABLE_NAME)); } @@ -160,6 +169,41 @@ public void testVisitAddIndex() { } + /** + * Test method for {@link org.alfasoftware.morf.upgrade.InlineTableUpgrader#visit(org.alfasoftware.morf.upgrade.AddIndex)}. + */ + @Test + public void testVisitAddIndexWithPRFIndex() { + // given + Index newIndex = mock(Index.class); + when(newIndex.getName()).thenReturn(ID_TABLE_NAME + "_1"); + when(newIndex.columnNames()).thenReturn(Collections.singletonList("column_1")); + + AddIndex addIndex = mock(AddIndex.class); + given(addIndex.apply(schema)).willReturn(schema); + when(addIndex.getTableName()).thenReturn(ID_TABLE_NAME); + when(addIndex.getNewIndex()).thenReturn(newIndex); + + AdditionalMetadata additionalMetadata = mock(AdditionalMetadata.class); + when(schemaResource.getAdditionalMetadata()).thenReturn(Optional.of(additionalMetadata)); + Index indexPrf = mock(Index.class); + when(indexPrf.getName()).thenReturn(ID_TABLE_NAME + "_PRF1"); + when(indexPrf.columnNames()).thenReturn(List.of("column_1")); + + Map> ignoredIndexes = new HashMap<>(); + ignoredIndexes.put(ID_TABLE_NAME.toUpperCase(Locale.ROOT), Collections.singletonList(indexPrf)); + when(additionalMetadata.ignoredIndexes()).thenReturn(ignoredIndexes); + + // when + upgrader.visit(addIndex); + + // then + verify(addIndex).apply(schema); + verify(sqlDialect).renameIndexStatements(nullable(Table.class), eq(ID_TABLE_NAME + "_PRF1"), eq(ID_TABLE_NAME + "_1")); + verify(sqlStatementWriter).writeSql(anyCollection()); + } + + /** * Test method for {@link org.alfasoftware.morf.upgrade.InlineTableUpgrader#visit(org.alfasoftware.morf.upgrade.AddColumn)}. */ diff --git a/morf-oracle/src/test/java/org/alfasoftware/morf/jdbc/oracle/TestOracleMetaDataProvider.java b/morf-oracle/src/test/java/org/alfasoftware/morf/jdbc/oracle/TestOracleMetaDataProvider.java index 44006da5f..b0e3badb1 100755 --- a/morf-oracle/src/test/java/org/alfasoftware/morf/jdbc/oracle/TestOracleMetaDataProvider.java +++ b/morf-oracle/src/test/java/org/alfasoftware/morf/jdbc/oracle/TestOracleMetaDataProvider.java @@ -153,6 +153,71 @@ public void testPrimaryKeyIndexNames() throws SQLException { assertEquals("Primary key index names.", expectedPrimaryKeyIndexNames, oracleMetaDataProvider.primaryKeyIndexNames()); } + /** + * Checks the building of the collection of primary key index names. + * @throws SQLException + */ + @Test + public void testIgnoredIndexes() throws SQLException { + // Given + final PreparedStatement statement = mock(PreparedStatement.class, RETURNS_SMART_NULLS); + when(connection.prepareStatement(anyString())).thenReturn(statement); + + mockGetTableKeysQuery(0, false, false); + // This is the table that's returned. + when(statement.executeQuery()).thenAnswer(invocation -> { + final ResultSet resultSet = mock(ResultSet.class, RETURNS_SMART_NULLS); + when(resultSet.next()).thenReturn(true, false); + + // + when(resultSet.getString(1)).thenReturn("AREALTABLE"); + when(resultSet.getString(2)).thenReturn("TableComment"); + when(resultSet.getString(3)).thenReturn("ID"); + when(resultSet.getString(4)).thenReturn("IDComment"); + when(resultSet.getString(5)).thenReturn("VARCHAR2"); + when(resultSet.getString(6)).thenReturn("10"); + return resultSet; + }).thenAnswer(new ReturnTablesMockResultSet(4)); + + PreparedStatement statement1 = mock(PreparedStatement.class, RETURNS_SMART_NULLS); + when(connection.prepareStatement("select table_name, index_name, uniqueness, status from ALL_INDEXES where owner=? order by table_name, index_name")).thenReturn(statement1); + + // two indexes, one of which is an ignored index + when(statement1.executeQuery()).thenAnswer(answer -> { + ResultSet resultSet = mock(ResultSet.class, RETURNS_SMART_NULLS); + when(resultSet.next()).thenReturn(true, true, false); + when(resultSet.getString(1)).thenReturn("AREALTABLE", "AREALTABLE"); + when(resultSet.getString(2)).thenReturn("AREALTABLE_1", "AREALTABLE_PRF1"); + when(resultSet.getString(4)).thenReturn("VALID"); + return resultSet; + }); + + // "select table_name, INDEX_NAME, COLUMN_NAME from ALL_IND_COLUMNS where INDEX_OWNER=? order by table_name, index_name, column_position" + PreparedStatement statement2 = mock(PreparedStatement.class, RETURNS_SMART_NULLS); + when(connection.prepareStatement("select table_name, INDEX_NAME, COLUMN_NAME from ALL_IND_COLUMNS where INDEX_OWNER=? order by table_name, index_name, column_position")).thenReturn(statement2); + + // two indexes, one of which is an ignored index + when(statement2.executeQuery()).thenAnswer(answer -> { + ResultSet resultSet = mock(ResultSet.class, RETURNS_SMART_NULLS); + when(resultSet.next()).thenReturn(true, true, false); + when(resultSet.getString(1)).thenReturn("AREALTABLE", "AREALTABLE"); + when(resultSet.getString(2)).thenReturn("AREALTABLE_1", "AREALTABLE_PRF1"); + when(resultSet.getString(3)).thenReturn("column1", "column2"); + return resultSet; + }); + + + // When + final AdditionalMetadata oracleMetaDataProvider = (AdditionalMetadata) oracle.openSchema(connection, "TESTDATABASE", "TESTSCHEMA"); + + Map> actualIgnoredIndexes = oracleMetaDataProvider.ignoredIndexes(); + assertEquals("Ignored indexes map size.", 1, actualIgnoredIndexes.size()); + assertEquals("Ignored indexes map size.", 1, actualIgnoredIndexes.get("AREALTABLE").size()); + Index index = actualIgnoredIndexes.get("AREALTABLE").get(0); + assertEquals("Ignored index name.", "AREALTABLE_PRF1", index.getName()); + assertEquals("Ignored index column.", "column2", index.columnNames().get(0)); + } + @Test public void testIfCatchesWronglyNamedPrimaryKeyIndex() throws SQLException { mockGetTableKeysQuery(1, true, false); From 664a70d851d7ab7d8c6f7591e2a78c304f72d5c9 Mon Sep 17 00:00:00 2001 From: Bruno Monteiro Date: Fri, 2 May 2025 18:37:43 +0100 Subject: [PATCH 03/11] Add more coverage for new code to GraphBasedUpgradeSchemaChangeVisitor, InlineTableUpgrader, OracleMetaDataProvider. #2 Refactor duplicated code. --- .../GraphBasedUpgradeSchemaChangeVisitor.java | 14 +-- .../morf/upgrade/InlineTableUpgrader.java | 13 +-- .../morf/upgrade/SchemaChangeVisitorBase.java | 57 ++++++++++ ...tGraphBasedUpgradeSchemaChangeVisitor.java | 30 ++++- .../morf/upgrade/TestInlineTableUpgrader.java | 27 ++++- .../jdbc/oracle/OracleMetaDataProvider.java | 107 +++++++----------- .../oracle/TestOracleMetaDataProvider.java | 27 +++-- 7 files changed, 184 insertions(+), 91 deletions(-) create mode 100644 morf-core/src/main/java/org/alfasoftware/morf/upgrade/SchemaChangeVisitorBase.java diff --git a/morf-core/src/main/java/org/alfasoftware/morf/upgrade/GraphBasedUpgradeSchemaChangeVisitor.java b/morf-core/src/main/java/org/alfasoftware/morf/upgrade/GraphBasedUpgradeSchemaChangeVisitor.java index 7b967face..7e339158c 100644 --- a/morf-core/src/main/java/org/alfasoftware/morf/upgrade/GraphBasedUpgradeSchemaChangeVisitor.java +++ b/morf-core/src/main/java/org/alfasoftware/morf/upgrade/GraphBasedUpgradeSchemaChangeVisitor.java @@ -1,14 +1,10 @@ package org.alfasoftware.morf.upgrade; import java.util.Collection; -import java.util.List; -import java.util.Locale; import java.util.Map; import java.util.UUID; import org.alfasoftware.morf.jdbc.SqlDialect; -import org.alfasoftware.morf.metadata.AdditionalMetadata; -import org.alfasoftware.morf.metadata.Index; import org.alfasoftware.morf.metadata.Schema; import org.alfasoftware.morf.metadata.SchemaResource; import org.alfasoftware.morf.metadata.Table; @@ -21,7 +17,7 @@ * * @author Copyright (c) Alfa Financial Software Limited. 2022 */ -class GraphBasedUpgradeSchemaChangeVisitor implements SchemaChangeVisitor { +class GraphBasedUpgradeSchemaChangeVisitor extends SchemaChangeVisitorBase implements SchemaChangeVisitor { private Schema sourceSchema; private final SchemaResource schemaResource; @@ -43,6 +39,7 @@ class GraphBasedUpgradeSchemaChangeVisitor implements SchemaChangeVisitor { * upgrade for which the visitor will generate statements */ GraphBasedUpgradeSchemaChangeVisitor(Schema sourceSchema, SchemaResource schemaResource, SqlDialect sqlDialect, Table idTable, Map upgradeNodes) { + super(sourceSchema, schemaResource, sqlDialect); this.sourceSchema = sourceSchema; this.schemaResource = schemaResource; this.sqlDialect = sqlDialect; @@ -55,7 +52,8 @@ class GraphBasedUpgradeSchemaChangeVisitor implements SchemaChangeVisitor { /** * Write statements to the current node */ - private void writeStatements(Collection statements) { + @Override + protected void writeStatements(Collection statements) { currentNode.addAllUpgradeStatements(statements); } @@ -81,7 +79,7 @@ public void visit(RemoveTable removeTable) { writeStatements(sqlDialect.dropStatements(removeTable.getTable())); } - + /* @Override public void visit(AddIndex addIndex) { sourceSchema = addIndex.apply(sourceSchema); @@ -105,7 +103,7 @@ public void visit(AddIndex addIndex) { } else { writeStatements(sqlDialect.addIndexStatements(sourceSchema.getTable(addIndex.getTableName()), addIndex.getNewIndex())); } - } + }*/ @Override diff --git a/morf-core/src/main/java/org/alfasoftware/morf/upgrade/InlineTableUpgrader.java b/morf-core/src/main/java/org/alfasoftware/morf/upgrade/InlineTableUpgrader.java index bd8cc61a2..566aa4f55 100755 --- a/morf-core/src/main/java/org/alfasoftware/morf/upgrade/InlineTableUpgrader.java +++ b/morf-core/src/main/java/org/alfasoftware/morf/upgrade/InlineTableUpgrader.java @@ -17,13 +17,9 @@ import java.util.Collection; import java.util.Collections; -import java.util.List; -import java.util.Locale; import java.util.UUID; import org.alfasoftware.morf.jdbc.SqlDialect; -import org.alfasoftware.morf.metadata.AdditionalMetadata; -import org.alfasoftware.morf.metadata.Index; import org.alfasoftware.morf.metadata.Schema; import org.alfasoftware.morf.metadata.SchemaResource; import org.alfasoftware.morf.metadata.Table; @@ -34,7 +30,7 @@ * * @author Copyright (c) Alfa Financial Software 2010 */ -public class InlineTableUpgrader implements SchemaChangeVisitor { +public class InlineTableUpgrader extends SchemaChangeVisitorBase implements SchemaChangeVisitor { private final SchemaResource schemaResource; private Schema currentSchema; @@ -54,6 +50,7 @@ public class InlineTableUpgrader implements SchemaChangeVisitor { * @param idTable table for id generation. */ public InlineTableUpgrader(Schema startSchema, SchemaResource schemaResource, SqlDialect sqlDialect, SqlStatementWriter sqlStatementWriter, Table idTable) { + super(startSchema, schemaResource, sqlDialect); this.schemaResource = schemaResource; this.currentSchema = startSchema; this.sqlDialect = sqlDialect; @@ -104,6 +101,7 @@ public void visit(RemoveTable removeTable) { /** * @see org.alfasoftware.morf.upgrade.SchemaChangeVisitor#visit(org.alfasoftware.morf.upgrade.AddIndex) */ + /* @Override public void visit(AddIndex addIndex) { currentSchema = addIndex.apply(currentSchema); @@ -127,7 +125,7 @@ public void visit(AddIndex addIndex) { } else { writeStatements(sqlDialect.addIndexStatements(currentSchema.getTable(addIndex.getTableName()), addIndex.getNewIndex())); } - } + } */ /** @@ -253,7 +251,8 @@ private void visitStatement(Statement statement) { /** * Write out SQL */ - private void writeStatements(Collection statements) { + @Override + protected void writeStatements(Collection statements) { sqlStatementWriter.writeSql(statements); } diff --git a/morf-core/src/main/java/org/alfasoftware/morf/upgrade/SchemaChangeVisitorBase.java b/morf-core/src/main/java/org/alfasoftware/morf/upgrade/SchemaChangeVisitorBase.java new file mode 100644 index 000000000..84da63765 --- /dev/null +++ b/morf-core/src/main/java/org/alfasoftware/morf/upgrade/SchemaChangeVisitorBase.java @@ -0,0 +1,57 @@ +package org.alfasoftware.morf.upgrade; + +import java.util.Collection; +import java.util.List; +import java.util.Locale; + +import org.alfasoftware.morf.jdbc.SqlDialect; +import org.alfasoftware.morf.metadata.AdditionalMetadata; +import org.alfasoftware.morf.metadata.Index; +import org.alfasoftware.morf.metadata.Schema; +import org.alfasoftware.morf.metadata.SchemaResource; + +/** + * Common code between SchemaChangeVisitor implementors + */ +public abstract class SchemaChangeVisitorBase implements SchemaChangeVisitor { + + protected Schema sourceSchema; + protected SchemaResource schemaResource; + protected SqlDialect sqlDialect; + + protected abstract void writeStatements(Collection statements); + + + public SchemaChangeVisitorBase(Schema sourceSchema, SchemaResource schemaResource, SqlDialect sqlDialect) { + this.sourceSchema = sourceSchema; + this.schemaResource = schemaResource; + this.sqlDialect = sqlDialect; + } + + + @Override + public void visit(AddIndex addIndex) { + sourceSchema = addIndex.apply(sourceSchema); + Index foundIndex = null; + if (schemaResource != null && schemaResource.getAdditionalMetadata().isPresent()) { + AdditionalMetadata additionalMetadata = schemaResource.getAdditionalMetadata().get(); + String tableName = addIndex.getTableName().toUpperCase(Locale.ROOT); + if (additionalMetadata.ignoredIndexes().containsKey(tableName)) { + List tableIgnoredIndexes = additionalMetadata.ignoredIndexes().get(tableName); + for (Index index : tableIgnoredIndexes) { + if (index.columnNames().equals(addIndex.getNewIndex().columnNames())) { + foundIndex = index; + break; + } + } + } + } + + if (foundIndex != null) { + writeStatements(sqlDialect.renameIndexStatements(sourceSchema.getTable(addIndex.getTableName()), foundIndex.getName(), addIndex.getNewIndex().getName())); + } else { + writeStatements(sqlDialect.addIndexStatements(sourceSchema.getTable(addIndex.getTableName()), addIndex.getNewIndex())); + } + } + +} diff --git a/morf-core/src/test/java/org/alfasoftware/morf/upgrade/TestGraphBasedUpgradeSchemaChangeVisitor.java b/morf-core/src/test/java/org/alfasoftware/morf/upgrade/TestGraphBasedUpgradeSchemaChangeVisitor.java index 665daa90f..82d1bced9 100644 --- a/morf-core/src/test/java/org/alfasoftware/morf/upgrade/TestGraphBasedUpgradeSchemaChangeVisitor.java +++ b/morf-core/src/test/java/org/alfasoftware/morf/upgrade/TestGraphBasedUpgradeSchemaChangeVisitor.java @@ -158,19 +158,45 @@ public void testVisitAddIndexWithPRFIndex() { when(indexPrf.getName()).thenReturn(ID_TABLE_NAME + "_PRF1"); when(indexPrf.columnNames()).thenReturn(List.of("column_1")); + Index indexPrf1 = mock(Index.class); + when(indexPrf1.getName()).thenReturn(ID_TABLE_NAME + "_PRF2"); + when(indexPrf1.columnNames()).thenReturn(List.of("column_2")); + Map> ignoredIndexes = new HashMap<>(); - ignoredIndexes.put(ID_TABLE_NAME.toUpperCase(Locale.ROOT), Collections.singletonList(indexPrf)); + ignoredIndexes.put(ID_TABLE_NAME.toUpperCase(Locale.ROOT), List.of(indexPrf, indexPrf1)); when(additionalMetadata.ignoredIndexes()).thenReturn(ignoredIndexes); when(sqlDialect.renameIndexStatements(nullable(Table.class), eq(ID_TABLE_NAME + "_PRF1"), eq(ID_TABLE_NAME + "_1"))).thenReturn(STATEMENTS); + when(sqlDialect.renameIndexStatements(nullable(Table.class), eq(ID_TABLE_NAME + "_PRF2"), eq(ID_TABLE_NAME + "_2"))).thenReturn(STATEMENTS); + when(sqlDialect.addIndexStatements(nullable(Table.class), nullable(Index.class))).thenReturn(STATEMENTS); + + Index newIndex1 = mock(Index.class); + when(newIndex1.getName()).thenReturn(ID_TABLE_NAME + "_2"); + when(newIndex1.columnNames()).thenReturn(Collections.singletonList("column_2")); + AddIndex addIndex1 = mock(AddIndex.class); + given(addIndex1.apply(sourceSchema)).willReturn(sourceSchema); + when(addIndex1.getTableName()).thenReturn(ID_TABLE_NAME); + when(addIndex1.getNewIndex()).thenReturn(newIndex1); + + Index newIndex2 = mock(Index.class); + when(newIndex2.getName()).thenReturn(ID_TABLE_NAME + "_3"); + when(newIndex2.columnNames()).thenReturn(Collections.singletonList("column_3")); + AddIndex addIndex2 = mock(AddIndex.class); + given(addIndex2.apply(sourceSchema)).willReturn(sourceSchema); + when(addIndex2.getTableName()).thenReturn(ID_TABLE_NAME); + when(addIndex2.getNewIndex()).thenReturn(newIndex2); // when visitor.visit(addIndex); + visitor.visit(addIndex1); + visitor.visit(addIndex2); // then verify(addIndex).apply(sourceSchema); verify(sqlDialect).renameIndexStatements(nullable(Table.class), eq(ID_TABLE_NAME + "_PRF1"), eq(ID_TABLE_NAME + "_1")); - verify(n1).addAllUpgradeStatements(ArgumentMatchers.argThat(c-> c.containsAll(STATEMENTS))); + verify(sqlDialect).renameIndexStatements(nullable(Table.class), eq(ID_TABLE_NAME + "_PRF2"), eq(ID_TABLE_NAME + "_2")); + verify(sqlDialect).addIndexStatements(nullable(Table.class), nullable(Index.class)); + verify(n1, times(3)).addAllUpgradeStatements(ArgumentMatchers.argThat(c-> c.containsAll(STATEMENTS))); } diff --git a/morf-core/src/test/java/org/alfasoftware/morf/upgrade/TestInlineTableUpgrader.java b/morf-core/src/test/java/org/alfasoftware/morf/upgrade/TestInlineTableUpgrader.java index 8474e91fb..fd414d245 100755 --- a/morf-core/src/test/java/org/alfasoftware/morf/upgrade/TestInlineTableUpgrader.java +++ b/morf-core/src/test/java/org/alfasoftware/morf/upgrade/TestInlineTableUpgrader.java @@ -189,18 +189,41 @@ public void testVisitAddIndexWithPRFIndex() { Index indexPrf = mock(Index.class); when(indexPrf.getName()).thenReturn(ID_TABLE_NAME + "_PRF1"); when(indexPrf.columnNames()).thenReturn(List.of("column_1")); + Index indexPrf1 = mock(Index.class); + when(indexPrf1.getName()).thenReturn(ID_TABLE_NAME + "_PRF2"); + when(indexPrf1.columnNames()).thenReturn(List.of("column_2")); Map> ignoredIndexes = new HashMap<>(); - ignoredIndexes.put(ID_TABLE_NAME.toUpperCase(Locale.ROOT), Collections.singletonList(indexPrf)); + ignoredIndexes.put(ID_TABLE_NAME.toUpperCase(Locale.ROOT), List.of(indexPrf, indexPrf1)); when(additionalMetadata.ignoredIndexes()).thenReturn(ignoredIndexes); + Index newIndex1 = mock(Index.class); + when(newIndex1.getName()).thenReturn(ID_TABLE_NAME + "_2"); + when(newIndex1.columnNames()).thenReturn(Collections.singletonList("column_2")); + AddIndex addIndex1 = mock(AddIndex.class); + given(addIndex1.apply(schema)).willReturn(schema); + when(addIndex1.getTableName()).thenReturn(ID_TABLE_NAME); + when(addIndex1.getNewIndex()).thenReturn(newIndex1); + + Index newIndex2 = mock(Index.class); + when(newIndex2.getName()).thenReturn(ID_TABLE_NAME + "_3"); + when(newIndex2.columnNames()).thenReturn(Collections.singletonList("column_3")); + AddIndex addIndex2 = mock(AddIndex.class); + given(addIndex2.apply(schema)).willReturn(schema); + when(addIndex2.getTableName()).thenReturn(ID_TABLE_NAME); + when(addIndex2.getNewIndex()).thenReturn(newIndex2); + // when upgrader.visit(addIndex); + upgrader.visit(addIndex1); + upgrader.visit(addIndex2); // then verify(addIndex).apply(schema); verify(sqlDialect).renameIndexStatements(nullable(Table.class), eq(ID_TABLE_NAME + "_PRF1"), eq(ID_TABLE_NAME + "_1")); - verify(sqlStatementWriter).writeSql(anyCollection()); + verify(sqlDialect).renameIndexStatements(nullable(Table.class), eq(ID_TABLE_NAME + "_PRF2"), eq(ID_TABLE_NAME + "_2")); + verify(sqlDialect).addIndexStatements(nullable(Table.class), nullable(Index.class)); + verify(sqlStatementWriter, times(3)).writeSql(anyCollection()); } diff --git a/morf-oracle/src/main/java/org/alfasoftware/morf/jdbc/oracle/OracleMetaDataProvider.java b/morf-oracle/src/main/java/org/alfasoftware/morf/jdbc/oracle/OracleMetaDataProvider.java index 40ab584cb..3468861d1 100755 --- a/morf-oracle/src/main/java/org/alfasoftware/morf/jdbc/oracle/OracleMetaDataProvider.java +++ b/morf-oracle/src/main/java/org/alfasoftware/morf/jdbc/oracle/OracleMetaDataProvider.java @@ -383,72 +383,53 @@ public void handle(ResultSet resultSet) throws SQLException { final String indexNameFinal = indexName; if (DatabaseMetaDataProviderUtils.shouldIgnoreIndex(indexName)) { - Index ignoredIndex = new Index() { - private final List columnNames = new ArrayList<>(); - - @Override - public boolean isUnique() { - return unique; - } - - - @Override - public String getName() { - return indexNameFinal; - } - - - @Override - public List columnNames() { - return columnNames; - } - - - @Override - public String toString() { - return this.toStringHelper(); - } - }; + Index ignoredIndex = getAssembledIndex(unique, indexNameFinal); if (ignoredIndexesMap.containsKey(tableName)) { - ignoredIndexesMap.get(tableName).add(ignoredIndex); + List indexList = new ArrayList<>(ignoredIndexesMap.get(tableName)); + indexList.add(ignoredIndex); + ignoredIndexesMap.put(tableName, indexList); } else { ignoredIndexesMap.put(tableName, List.of(ignoredIndex)); } continue; } - currentTable.indexes().add(new Index() { - private final List columnNames = new ArrayList<>(); + currentTable.indexes().add(getAssembledIndex(unique, indexNameFinal)); + indexCount++; + } - @Override - public boolean isUnique() { - return unique; - } + if (log.isDebugEnabled()) { + log.debug(String.format("Loaded %d indexes", indexCount)); + } + } + private Index getAssembledIndex(boolean unique, String indexNameFinal) { + return new Index() { + private final List columnNames = new ArrayList<>(); - @Override - public String getName() { - return indexNameFinal; - } + @Override + public boolean isUnique() { + return unique; + } - @Override - public List columnNames() { - return columnNames; - } + @Override + public String getName() { + return indexNameFinal; + } - @Override - public String toString() { - return this.toStringHelper(); - } - }); - indexCount++; - } + @Override + public List columnNames() { + return columnNames; + } - if (log.isDebugEnabled()) { - log.debug(String.format("Loaded %d indexes", indexCount)); - } + + @Override + public String toString() { + return this.toStringHelper(); + } + }; } @@ -502,12 +483,7 @@ public void handle(ResultSet resultSet) throws SQLException { } // Correct the case on the column name - for (Column currentColumn : currentTable.columns()) { - if (currentColumn.getName().equalsIgnoreCase(columnName)) { - columnName = currentColumn.getName(); - break; - } - } + columnName = getColumnCorrectCase(currentTable, columnName); lastIndex.columnNames().add(columnName); @@ -528,16 +504,21 @@ public void handle(ResultSet resultSet) throws SQLException { } // Correct the case on the column name - for (Column currentColumn : currentTable.columns()) { - if (currentColumn.getName().equalsIgnoreCase(columnName)) { - columnName = currentColumn.getName(); - break; - } - } + columnName = getColumnCorrectCase(currentTable, columnName); lastIndex.columnNames().add(columnName); } } + + private String getColumnCorrectCase(Table currentTable, String columnName) { + for (Column currentColumn : currentTable.columns()) { + if (currentColumn.getName().equalsIgnoreCase(columnName)) { + columnName = currentColumn.getName(); + break; + } + } + return columnName; + } }); long end = System.currentTimeMillis(); diff --git a/morf-oracle/src/test/java/org/alfasoftware/morf/jdbc/oracle/TestOracleMetaDataProvider.java b/morf-oracle/src/test/java/org/alfasoftware/morf/jdbc/oracle/TestOracleMetaDataProvider.java index b0e3badb1..6c38de8d2 100755 --- a/morf-oracle/src/test/java/org/alfasoftware/morf/jdbc/oracle/TestOracleMetaDataProvider.java +++ b/morf-oracle/src/test/java/org/alfasoftware/morf/jdbc/oracle/TestOracleMetaDataProvider.java @@ -185,10 +185,11 @@ public void testIgnoredIndexes() throws SQLException { // two indexes, one of which is an ignored index when(statement1.executeQuery()).thenAnswer(answer -> { ResultSet resultSet = mock(ResultSet.class, RETURNS_SMART_NULLS); - when(resultSet.next()).thenReturn(true, true, false); - when(resultSet.getString(1)).thenReturn("AREALTABLE", "AREALTABLE"); - when(resultSet.getString(2)).thenReturn("AREALTABLE_1", "AREALTABLE_PRF1"); - when(resultSet.getString(4)).thenReturn("VALID"); + when(resultSet.next()).thenReturn(true, true, true, false); + when(resultSet.getString(1)).thenReturn("AREALTABLE", "AREALTABLE", "AREALTABLE"); + when(resultSet.getString(2)).thenReturn("AREALTABLE_1", "AREALTABLE_PRF1", "AREALTABLE_PRF2"); + when(resultSet.getString(3)).thenReturn("", "", "UNIQUE"); + when(resultSet.getString(4)).thenReturn("VALID", "VALID"); return resultSet; }); @@ -199,10 +200,10 @@ public void testIgnoredIndexes() throws SQLException { // two indexes, one of which is an ignored index when(statement2.executeQuery()).thenAnswer(answer -> { ResultSet resultSet = mock(ResultSet.class, RETURNS_SMART_NULLS); - when(resultSet.next()).thenReturn(true, true, false); - when(resultSet.getString(1)).thenReturn("AREALTABLE", "AREALTABLE"); - when(resultSet.getString(2)).thenReturn("AREALTABLE_1", "AREALTABLE_PRF1"); - when(resultSet.getString(3)).thenReturn("column1", "column2"); + when(resultSet.next()).thenReturn(true, true, true, false); + when(resultSet.getString(1)).thenReturn("AREALTABLE", "AREALTABLE", "AREALTABLE"); + when(resultSet.getString(2)).thenReturn("AREALTABLE_1", "AREALTABLE_PRF1", "AREALTABLE_PRF2"); + when(resultSet.getString(3)).thenReturn("column1", "column2", "column3"); return resultSet; }); @@ -212,10 +213,18 @@ public void testIgnoredIndexes() throws SQLException { Map> actualIgnoredIndexes = oracleMetaDataProvider.ignoredIndexes(); assertEquals("Ignored indexes map size.", 1, actualIgnoredIndexes.size()); - assertEquals("Ignored indexes map size.", 1, actualIgnoredIndexes.get("AREALTABLE").size()); + assertEquals("Ignored AREALTABLE table indexes size.", 2, actualIgnoredIndexes.get("AREALTABLE").size()); Index index = actualIgnoredIndexes.get("AREALTABLE").get(0); assertEquals("Ignored index name.", "AREALTABLE_PRF1", index.getName()); assertEquals("Ignored index column.", "column2", index.columnNames().get(0)); + assertFalse("Ignored index uniqueness.", index.isUnique()); + assertEquals("Index-AREALTABLE_PRF1--column2", index.toStringHelper()); + + Index index2 = actualIgnoredIndexes.get("AREALTABLE").get(1); + assertEquals("Ignored index name.", "AREALTABLE_PRF2", index2.getName()); + assertEquals("Ignored index column.", "column3", index2.columnNames().get(0)); + assertTrue("Ignored index uniqueness.", index2.isUnique()); + assertEquals("Index-AREALTABLE_PRF2-unique-column3", index2.toStringHelper()); } @Test From ac3c65f640a53370a7d9e89f97e70caf929d0025 Mon Sep 17 00:00:00 2001 From: Bruno Monteiro Date: Fri, 2 May 2025 18:50:58 +0100 Subject: [PATCH 04/11] Solve reliability issue due to Sonar misunderstanding code. --- .../alfasoftware/morf/upgrade/SchemaChangeVisitorBase.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/morf-core/src/main/java/org/alfasoftware/morf/upgrade/SchemaChangeVisitorBase.java b/morf-core/src/main/java/org/alfasoftware/morf/upgrade/SchemaChangeVisitorBase.java index 84da63765..04086e192 100644 --- a/morf-core/src/main/java/org/alfasoftware/morf/upgrade/SchemaChangeVisitorBase.java +++ b/morf-core/src/main/java/org/alfasoftware/morf/upgrade/SchemaChangeVisitorBase.java @@ -3,6 +3,7 @@ import java.util.Collection; import java.util.List; import java.util.Locale; +import java.util.Optional; import org.alfasoftware.morf.jdbc.SqlDialect; import org.alfasoftware.morf.metadata.AdditionalMetadata; @@ -33,8 +34,9 @@ public SchemaChangeVisitorBase(Schema sourceSchema, SchemaResource schemaResourc public void visit(AddIndex addIndex) { sourceSchema = addIndex.apply(sourceSchema); Index foundIndex = null; - if (schemaResource != null && schemaResource.getAdditionalMetadata().isPresent()) { - AdditionalMetadata additionalMetadata = schemaResource.getAdditionalMetadata().get(); + Optional optionalMetadata = schemaResource.getAdditionalMetadata(); + if (optionalMetadata.isPresent()) { + AdditionalMetadata additionalMetadata = optionalMetadata.get(); String tableName = addIndex.getTableName().toUpperCase(Locale.ROOT); if (additionalMetadata.ignoredIndexes().containsKey(tableName)) { List tableIgnoredIndexes = additionalMetadata.ignoredIndexes().get(tableName); From 74aa7461690f8dcfe9556bb93db51c42bad10c7a Mon Sep 17 00:00:00 2001 From: Bruno Monteiro Date: Mon, 5 May 2025 09:07:58 +0100 Subject: [PATCH 05/11] Remove commented code --- .../GraphBasedUpgradeSchemaChangeVisitor.java | 26 ---------------- .../morf/upgrade/InlineTableUpgrader.java | 30 ------------------- 2 files changed, 56 deletions(-) diff --git a/morf-core/src/main/java/org/alfasoftware/morf/upgrade/GraphBasedUpgradeSchemaChangeVisitor.java b/morf-core/src/main/java/org/alfasoftware/morf/upgrade/GraphBasedUpgradeSchemaChangeVisitor.java index 7e339158c..6b0afef63 100644 --- a/morf-core/src/main/java/org/alfasoftware/morf/upgrade/GraphBasedUpgradeSchemaChangeVisitor.java +++ b/morf-core/src/main/java/org/alfasoftware/morf/upgrade/GraphBasedUpgradeSchemaChangeVisitor.java @@ -79,32 +79,6 @@ public void visit(RemoveTable removeTable) { writeStatements(sqlDialect.dropStatements(removeTable.getTable())); } - /* - @Override - public void visit(AddIndex addIndex) { - sourceSchema = addIndex.apply(sourceSchema); - Index foundIndex = null; - if (schemaResource != null && schemaResource.getAdditionalMetadata().isPresent()) { - AdditionalMetadata additionalMetadata = schemaResource.getAdditionalMetadata().get(); - String tableName = addIndex.getTableName().toUpperCase(Locale.ROOT); - if (additionalMetadata.ignoredIndexes().containsKey(tableName)) { - List tableIgnoredIndexes = additionalMetadata.ignoredIndexes().get(tableName); - for (Index index : tableIgnoredIndexes) { - if (index.columnNames().equals(addIndex.getNewIndex().columnNames())) { - foundIndex = index; - break; - } - } - } - } - - if (foundIndex != null) { - writeStatements(sqlDialect.renameIndexStatements(sourceSchema.getTable(addIndex.getTableName()), foundIndex.getName(), addIndex.getNewIndex().getName())); - } else { - writeStatements(sqlDialect.addIndexStatements(sourceSchema.getTable(addIndex.getTableName()), addIndex.getNewIndex())); - } - }*/ - @Override public void visit(AddColumn addColumn) { diff --git a/morf-core/src/main/java/org/alfasoftware/morf/upgrade/InlineTableUpgrader.java b/morf-core/src/main/java/org/alfasoftware/morf/upgrade/InlineTableUpgrader.java index 566aa4f55..9aea13f27 100755 --- a/morf-core/src/main/java/org/alfasoftware/morf/upgrade/InlineTableUpgrader.java +++ b/morf-core/src/main/java/org/alfasoftware/morf/upgrade/InlineTableUpgrader.java @@ -98,36 +98,6 @@ public void visit(RemoveTable removeTable) { } - /** - * @see org.alfasoftware.morf.upgrade.SchemaChangeVisitor#visit(org.alfasoftware.morf.upgrade.AddIndex) - */ - /* - @Override - public void visit(AddIndex addIndex) { - currentSchema = addIndex.apply(currentSchema); - Index foundIndex = null; - if (schemaResource != null && schemaResource.getAdditionalMetadata().isPresent()) { - AdditionalMetadata additionalMetadata = schemaResource.getAdditionalMetadata().get(); - String tableName = addIndex.getTableName().toUpperCase(Locale.ROOT); - if (additionalMetadata.ignoredIndexes().containsKey(tableName)) { - List tableIgnoredIndexes = additionalMetadata.ignoredIndexes().get(tableName); - for (Index index : tableIgnoredIndexes) { - if (index.columnNames().equals(addIndex.getNewIndex().columnNames())) { - foundIndex = index; - break; - } - } - } - } - - if (foundIndex != null) { - writeStatements(sqlDialect.renameIndexStatements(currentSchema.getTable(addIndex.getTableName()), foundIndex.getName(), addIndex.getNewIndex().getName())); - } else { - writeStatements(sqlDialect.addIndexStatements(currentSchema.getTable(addIndex.getTableName()), addIndex.getNewIndex())); - } - } */ - - /** * @see org.alfasoftware.morf.upgrade.SchemaChangeVisitor#visit(org.alfasoftware.morf.upgrade.AddColumn) */ From c1ffd1a67abda7ad360c7c186fd47415341d3998 Mon Sep 17 00:00:00 2001 From: Bruno Monteiro Date: Mon, 5 May 2025 11:42:58 +0100 Subject: [PATCH 06/11] AdditionalMetadata - remove ignoredIndexes() Changes that apply to more than one file: - Remove ignoredIndexesMap - Remove schemaResources from constructor - Use Table.ignoredIndexes instead of a map for all tables Files: - AbstractSchemaChangeVisitor - DatabaseMetaDataProvider - also add support for ignored indexes at table loading level - GraphBasedUpgradeBuilder - GraphBasedUpgradeSchemaChangeVisitor - InlineTableUpgrader - OracleMetaDataProvider - Upgrade - UpgradeTestHelper Add ignoredIndexes() property: - SchemaUtils.TableBuilder / Impl - Table - TableBean Update tests to pass. --- .../morf/jdbc/DatabaseMetaDataProvider.java | 32 ++++++++---- .../morf/metadata/AdditionalMetadata.java | 10 ---- .../morf/metadata/SchemaUtils.java | 49 +++++++++++++++++-- .../org/alfasoftware/morf/metadata/Table.java | 8 +++ .../alfasoftware/morf/metadata/TableBean.java | 24 ++++++++- ....java => AbstractSchemaChangeVisitor.java} | 21 +++----- .../upgrade/GraphBasedUpgradeBuilder.java | 1 - .../GraphBasedUpgradeSchemaChangeVisitor.java | 16 +++--- .../morf/upgrade/InlineTableUpgrader.java | 10 ++-- .../alfasoftware/morf/upgrade/Upgrade.java | 2 +- ...tGraphBasedUpgradeSchemaChangeVisitor.java | 25 +++++----- .../morf/upgrade/TestInlineTableUpgrader.java | 29 +++++------ .../jdbc/TestDatabaseMetaDataProvider.java | 29 +++++++++-- .../jdbc/oracle/OracleMetaDataProvider.java | 22 +-------- .../oracle/TestOracleMetaDataProvider.java | 10 ++-- .../morf/testing/UpgradeTestHelper.java | 2 +- 16 files changed, 171 insertions(+), 119 deletions(-) rename morf-core/src/main/java/org/alfasoftware/morf/upgrade/{SchemaChangeVisitorBase.java => AbstractSchemaChangeVisitor.java} (57%) diff --git a/morf-core/src/main/java/org/alfasoftware/morf/jdbc/DatabaseMetaDataProvider.java b/morf-core/src/main/java/org/alfasoftware/morf/jdbc/DatabaseMetaDataProvider.java index b3c7a9165..ebec5ba46 100755 --- a/morf-core/src/main/java/org/alfasoftware/morf/jdbc/DatabaseMetaDataProvider.java +++ b/morf-core/src/main/java/org/alfasoftware/morf/jdbc/DatabaseMetaDataProvider.java @@ -117,7 +117,6 @@ public abstract class DatabaseMetaDataProvider implements Schema { private final Supplier> databaseInformation = Suppliers.memoize(this::loadDatabaseInformation); - /** * @param connection The database connection from which meta data should be provided. * @param schemaName The name of the schema in which the data is stored. This might be null. @@ -677,7 +676,8 @@ protected Table loadTable(AName tableName) { final Map primaryKey = loadTablePrimaryKey(realTableName); final Supplier> columns = Suppliers.memoize(() -> loadTableColumns(realTableName, primaryKey)); - final Supplier> indexes = Suppliers.memoize(() -> loadTableIndexes(realTableName)); + final Supplier> indexes = Suppliers.memoize(() -> loadTableIndexes(realTableName, false)); + final Supplier> ignoredIndexes = Suppliers.memoize(() -> loadTableIndexes(realTableName, true)); return new Table() { @Override @@ -695,6 +695,11 @@ public List indexes() { return indexes.get(); } + @Override + public List ignoredIndexes() { + return ignoredIndexes.get(); + } + @Override public boolean isTemporary() { return false; @@ -789,10 +794,12 @@ protected static List createColumnsFrom(Collection origin * Loads the indexes for the given table name, except for the primary key index. * * @param tableName Name of the table. + * @param returnIgnored if true return ignored indexes, when false return all the non ignored. * @return List of table indexes. */ - protected List loadTableIndexes(RealName tableName) { + protected List loadTableIndexes(RealName tableName, boolean returnIgnored) { final Map> indexColumns = new HashMap<>(); + final Map> ignoredIndexColumns = new HashMap<>(); final Map indexUniqueness = new HashMap<>(); if (log.isTraceEnabled()) log.trace("Reading table indexes for " + tableName); @@ -811,10 +818,6 @@ protected List loadTableIndexes(RealName tableName) { if (isPrimaryKeyIndex(indexName)) { continue; } - if (DatabaseMetaDataProviderUtils.shouldIgnoreIndex(indexName.getDbName())) { - log.info("Ignoring index: ["+indexName.getDbName()+"]"); - continue; - } String dbColumnName = indexResultSet.getString(INDEX_COLUMN_NAME); String realColumnName = allColumns.get().get(tableName).get(named(dbColumnName)).getName(); @@ -827,8 +830,13 @@ protected List loadTableIndexes(RealName tableName) { indexUniqueness.put(indexName, unique); - indexColumns.computeIfAbsent(indexName, k -> ImmutableList.builder()) + if (DatabaseMetaDataProviderUtils.shouldIgnoreIndex(indexName.getDbName())) { + ignoredIndexColumns.computeIfAbsent(indexName, k -> ImmutableList.builder()) .add(columnName); + } else { + indexColumns.computeIfAbsent(indexName, k -> ImmutableList.builder()) + .add(columnName); + } } catch (SQLException e) { throw new RuntimeSqlException("Error reading metadata for index ["+indexName+"] on table ["+tableName+"]", e); @@ -838,9 +846,15 @@ protected List loadTableIndexes(RealName tableName) { long end = System.currentTimeMillis(); if (log.isTraceEnabled()) log.trace(String.format("Read table indexes for %s in %dms; %d indexes; %d unique", tableName, end-start, indexColumns.size(), indexUniqueness.size())); - return indexColumns.entrySet().stream() + if (returnIgnored) { + return ignoredIndexColumns.entrySet().stream() .map(e -> createIndexFrom(e.getKey(), indexUniqueness.get(e.getKey()), e.getValue().build())) .collect(Collectors.toList()); + } else { + return indexColumns.entrySet().stream() + .map(e -> createIndexFrom(e.getKey(), indexUniqueness.get(e.getKey()), e.getValue().build())) + .collect(Collectors.toList()); + } } } catch (SQLException e) { diff --git a/morf-core/src/main/java/org/alfasoftware/morf/metadata/AdditionalMetadata.java b/morf-core/src/main/java/org/alfasoftware/morf/metadata/AdditionalMetadata.java index 46cc7bb2a..081b75688 100644 --- a/morf-core/src/main/java/org/alfasoftware/morf/metadata/AdditionalMetadata.java +++ b/morf-core/src/main/java/org/alfasoftware/morf/metadata/AdditionalMetadata.java @@ -1,6 +1,5 @@ package org.alfasoftware.morf.metadata; -import java.util.List; import java.util.Map; import org.apache.commons.lang3.NotImplementedException; @@ -17,13 +16,4 @@ public interface AdditionalMetadata extends Schema { default Map primaryKeyIndexNames() { throw new NotImplementedException("Not implemented yet."); } - - /** - * The names of all the ignored indexes in the database, - * maps from table name into a List of Index. - * @return A collection of the names of all the ignored indexes. - */ - default Map> ignoredIndexes() { - return Map.of(); - } } diff --git a/morf-core/src/main/java/org/alfasoftware/morf/metadata/SchemaUtils.java b/morf-core/src/main/java/org/alfasoftware/morf/metadata/SchemaUtils.java index 8aaa9744a..dcee14b20 100755 --- a/morf-core/src/main/java/org/alfasoftware/morf/metadata/SchemaUtils.java +++ b/morf-core/src/main/java/org/alfasoftware/morf/metadata/SchemaUtils.java @@ -517,6 +517,26 @@ public interface TableBuilder extends Table { public TableBuilder indexes(Iterable indexes); + /** + * Sets the indexes for the table. + * + * @param ignoredIndexes The ignored indexes to set, probably provided by calls to + * {@link SchemaUtils#index(String)} + * @return this table builder, for method chaining. + */ + public TableBuilder ignoredIndexes(Index... ignoredIndexes); + + + /** + * Sets the indexes for the table. + * + * @param ignoredIndexes The ignored indexes to set, probably provided by calls to + * {@link SchemaUtils#index(String)} + * @return this table builder, for method chaining. + */ + public TableBuilder ignoredIndexes(Iterable ignoredIndexes); + + /** * Creates a temporary table. * @@ -653,8 +673,9 @@ private TableBuilderImpl(String name) { } - private TableBuilderImpl(String name, Iterable columns, Iterable indexes, boolean isTemporary) { - super(name, columns, indexes, isTemporary); + private TableBuilderImpl(String name, Iterable columns, Iterable indexes, + Iterable ignoredIndexes, boolean isTemporary) { + super(name, columns, indexes, ignoredIndexes, isTemporary); } @@ -672,7 +693,7 @@ public TableBuilder columns(Column... columns) { */ @Override public TableBuilder columns(Iterable columns) { - return new TableBuilderImpl(getName(), columns, indexes(), isTemporary()); + return new TableBuilderImpl(getName(), columns, indexes(), ignoredIndexes(), isTemporary()); } @@ -685,12 +706,30 @@ public TableBuilder indexes(Index... indexes) { } + /** + * @see org.alfasoftware.morf.metadata.SchemaUtils.TableBuilder#ignoredIndexes(java.lang.Iterable) + */ + @Override + public TableBuilder ignoredIndexes(Iterable ignoredIndexes) { + return new TableBuilderImpl(getName(), columns(), indexes(), ignoredIndexes, isTemporary()); + } + + + /** + * @see org.alfasoftware.morf.metadata.SchemaUtils.TableBuilder#ignoredIndexes(org.alfasoftware.morf.metadata.Index[]) + */ + @Override + public TableBuilder ignoredIndexes(Index... ignoredIndexes) { + return ignoredIndexes(Arrays.asList(ignoredIndexes)); + } + + /** * @see org.alfasoftware.morf.metadata.SchemaUtils.TableBuilder#indexes(java.lang.Iterable) */ @Override public TableBuilder indexes(Iterable indexes) { - return new TableBuilderImpl(getName(), columns(), indexes, isTemporary()); + return new TableBuilderImpl(getName(), columns(), indexes, ignoredIndexes(), isTemporary()); } @@ -699,7 +738,7 @@ public TableBuilder indexes(Iterable indexes) { */ @Override public TableBuilder temporary() { - return new TableBuilderImpl(getName(), columns(), indexes(), true); + return new TableBuilderImpl(getName(), columns(), indexes(), ignoredIndexes(), true); } } diff --git a/morf-core/src/main/java/org/alfasoftware/morf/metadata/Table.java b/morf-core/src/main/java/org/alfasoftware/morf/metadata/Table.java index 99d80d462..9bc4e45f7 100755 --- a/morf-core/src/main/java/org/alfasoftware/morf/metadata/Table.java +++ b/morf-core/src/main/java/org/alfasoftware/morf/metadata/Table.java @@ -61,6 +61,14 @@ public default List primaryKey() { public List indexes(); + /** + * @return The ignored indexes on this table. + */ + public default List ignoredIndexes() { + return List.of(); + } + + /** * @return Indicates whether the table is temporary */ diff --git a/morf-core/src/main/java/org/alfasoftware/morf/metadata/TableBean.java b/morf-core/src/main/java/org/alfasoftware/morf/metadata/TableBean.java index 8c896267e..22db48597 100755 --- a/morf-core/src/main/java/org/alfasoftware/morf/metadata/TableBean.java +++ b/morf-core/src/main/java/org/alfasoftware/morf/metadata/TableBean.java @@ -18,7 +18,6 @@ import java.util.ArrayList; import java.util.List; - import com.google.common.collect.Iterables; @@ -44,6 +43,11 @@ class TableBean implements Table { */ private final List indexes = new ArrayList<>(); + /** + * Stores the ordered list of ignored indexes. + */ + private final List ignoredIndexes = new ArrayList<>(); + /** * Indicates whether the table is temporary. */ @@ -77,13 +81,16 @@ private TableBean(String tableName, boolean isTemporary) { * @param tableName Name of the table to represent. * @param columns Columns for the table * @param indexes indexes for the table; + * @param ignoredIndexes ignored indexes for the table * @param isTemporary Whether the table is a temporary table. */ - TableBean(String tableName, Iterable columns, Iterable indexes, boolean isTemporary) { + TableBean(String tableName, Iterable columns, Iterable indexes, + Iterable ignoredIndexes, boolean isTemporary) { this(tableName, isTemporary); Iterables.addAll(this.columns, columns); Iterables.addAll(this.indexes, indexes); + Iterables.addAll(this.ignoredIndexes, ignoredIndexes); } @@ -106,6 +113,10 @@ private TableBean(String tableName, boolean isTemporary) { for (Index index : toCopy.indexes()) { indexes.add(new IndexBean(index)); } + + for (Index index : toCopy.ignoredIndexes()) { + ignoredIndexes.add(new IndexBean(index)); + } } @@ -136,6 +147,15 @@ public List indexes() { } + /** + * @see org.alfasoftware.morf.metadata.Table#ignoredIndexes() + */ + @Override + public List ignoredIndexes() { + return ignoredIndexes; + } + + /** * Finds a column with the specified name * diff --git a/morf-core/src/main/java/org/alfasoftware/morf/upgrade/SchemaChangeVisitorBase.java b/morf-core/src/main/java/org/alfasoftware/morf/upgrade/AbstractSchemaChangeVisitor.java similarity index 57% rename from morf-core/src/main/java/org/alfasoftware/morf/upgrade/SchemaChangeVisitorBase.java rename to morf-core/src/main/java/org/alfasoftware/morf/upgrade/AbstractSchemaChangeVisitor.java index 04086e192..d99821521 100644 --- a/morf-core/src/main/java/org/alfasoftware/morf/upgrade/SchemaChangeVisitorBase.java +++ b/morf-core/src/main/java/org/alfasoftware/morf/upgrade/AbstractSchemaChangeVisitor.java @@ -2,30 +2,25 @@ import java.util.Collection; import java.util.List; -import java.util.Locale; -import java.util.Optional; import org.alfasoftware.morf.jdbc.SqlDialect; -import org.alfasoftware.morf.metadata.AdditionalMetadata; import org.alfasoftware.morf.metadata.Index; import org.alfasoftware.morf.metadata.Schema; -import org.alfasoftware.morf.metadata.SchemaResource; +import org.alfasoftware.morf.metadata.Table; /** * Common code between SchemaChangeVisitor implementors */ -public abstract class SchemaChangeVisitorBase implements SchemaChangeVisitor { +public abstract class AbstractSchemaChangeVisitor implements SchemaChangeVisitor { protected Schema sourceSchema; - protected SchemaResource schemaResource; protected SqlDialect sqlDialect; protected abstract void writeStatements(Collection statements); - public SchemaChangeVisitorBase(Schema sourceSchema, SchemaResource schemaResource, SqlDialect sqlDialect) { + public AbstractSchemaChangeVisitor(Schema sourceSchema, SqlDialect sqlDialect) { this.sourceSchema = sourceSchema; - this.schemaResource = schemaResource; this.sqlDialect = sqlDialect; } @@ -34,19 +29,15 @@ public SchemaChangeVisitorBase(Schema sourceSchema, SchemaResource schemaResourc public void visit(AddIndex addIndex) { sourceSchema = addIndex.apply(sourceSchema); Index foundIndex = null; - Optional optionalMetadata = schemaResource.getAdditionalMetadata(); - if (optionalMetadata.isPresent()) { - AdditionalMetadata additionalMetadata = optionalMetadata.get(); - String tableName = addIndex.getTableName().toUpperCase(Locale.ROOT); - if (additionalMetadata.ignoredIndexes().containsKey(tableName)) { - List tableIgnoredIndexes = additionalMetadata.ignoredIndexes().get(tableName); + Table table = sourceSchema.getTable(addIndex.getTableName()); + if (!table.ignoredIndexes().isEmpty()) { + List tableIgnoredIndexes = table.ignoredIndexes(); for (Index index : tableIgnoredIndexes) { if (index.columnNames().equals(addIndex.getNewIndex().columnNames())) { foundIndex = index; break; } } - } } if (foundIndex != null) { diff --git a/morf-core/src/main/java/org/alfasoftware/morf/upgrade/GraphBasedUpgradeBuilder.java b/morf-core/src/main/java/org/alfasoftware/morf/upgrade/GraphBasedUpgradeBuilder.java index d4bfe6b2d..9691e6b31 100644 --- a/morf-core/src/main/java/org/alfasoftware/morf/upgrade/GraphBasedUpgradeBuilder.java +++ b/morf-core/src/main/java/org/alfasoftware/morf/upgrade/GraphBasedUpgradeBuilder.java @@ -101,7 +101,6 @@ public GraphBasedUpgrade prepareGraphBasedUpgrade(List initialisationSql GraphBasedUpgradeSchemaChangeVisitor visitor = visitorFactory.create( sourceSchema, - connectionResources.openSchemaResource(), connectionResources.sqlDialect(), idTable, nodes.stream().collect(Collectors.toMap(GraphBasedUpgradeNode::getName, Function.identity()))); diff --git a/morf-core/src/main/java/org/alfasoftware/morf/upgrade/GraphBasedUpgradeSchemaChangeVisitor.java b/morf-core/src/main/java/org/alfasoftware/morf/upgrade/GraphBasedUpgradeSchemaChangeVisitor.java index 6b0afef63..3983fbb22 100644 --- a/morf-core/src/main/java/org/alfasoftware/morf/upgrade/GraphBasedUpgradeSchemaChangeVisitor.java +++ b/morf-core/src/main/java/org/alfasoftware/morf/upgrade/GraphBasedUpgradeSchemaChangeVisitor.java @@ -6,7 +6,6 @@ import org.alfasoftware.morf.jdbc.SqlDialect; import org.alfasoftware.morf.metadata.Schema; -import org.alfasoftware.morf.metadata.SchemaResource; import org.alfasoftware.morf.metadata.Table; import org.alfasoftware.morf.sql.Statement; @@ -17,10 +16,9 @@ * * @author Copyright (c) Alfa Financial Software Limited. 2022 */ -class GraphBasedUpgradeSchemaChangeVisitor extends SchemaChangeVisitorBase implements SchemaChangeVisitor { +class GraphBasedUpgradeSchemaChangeVisitor extends AbstractSchemaChangeVisitor implements SchemaChangeVisitor { private Schema sourceSchema; - private final SchemaResource schemaResource; private final SqlDialect sqlDialect; private final Table idTable; private final TableNameResolver tracker; @@ -32,16 +30,14 @@ class GraphBasedUpgradeSchemaChangeVisitor extends SchemaChangeVisitorBase imple * Default constructor. * * @param sourceSchema schema prior to upgrade step. - * @param schemaResource schema resource * @param sqlDialect dialect to generate statements for the target database. * @param idTable table for id generation. * @param upgradeNodes all the {@link GraphBasedUpgradeNode} instances in the * upgrade for which the visitor will generate statements */ - GraphBasedUpgradeSchemaChangeVisitor(Schema sourceSchema, SchemaResource schemaResource, SqlDialect sqlDialect, Table idTable, Map upgradeNodes) { - super(sourceSchema, schemaResource, sqlDialect); + GraphBasedUpgradeSchemaChangeVisitor(Schema sourceSchema, SqlDialect sqlDialect, Table idTable, Map upgradeNodes) { + super(sourceSchema, sqlDialect); this.sourceSchema = sourceSchema; - this.schemaResource = schemaResource; this.sqlDialect = sqlDialect; this.idTable = idTable; this.upgradeNodes = upgradeNodes; @@ -247,9 +243,9 @@ static class GraphBasedUpgradeSchemaChangeVisitorFactory { * which the visitor will generate statements * @return new {@link GraphBasedUpgradeSchemaChangeVisitor} instance */ - GraphBasedUpgradeSchemaChangeVisitor create(Schema sourceSchema, SchemaResource schemaResource, SqlDialect sqlDialect, Table idTable, - Map upgradeNodes) { - return new GraphBasedUpgradeSchemaChangeVisitor(sourceSchema, schemaResource, sqlDialect, idTable, upgradeNodes); + GraphBasedUpgradeSchemaChangeVisitor create(Schema sourceSchema, SqlDialect sqlDialect, Table idTable, + Map upgradeNodes) { + return new GraphBasedUpgradeSchemaChangeVisitor(sourceSchema, sqlDialect, idTable, upgradeNodes); } } } diff --git a/morf-core/src/main/java/org/alfasoftware/morf/upgrade/InlineTableUpgrader.java b/morf-core/src/main/java/org/alfasoftware/morf/upgrade/InlineTableUpgrader.java index 9aea13f27..bb9257dff 100755 --- a/morf-core/src/main/java/org/alfasoftware/morf/upgrade/InlineTableUpgrader.java +++ b/morf-core/src/main/java/org/alfasoftware/morf/upgrade/InlineTableUpgrader.java @@ -21,7 +21,6 @@ import org.alfasoftware.morf.jdbc.SqlDialect; import org.alfasoftware.morf.metadata.Schema; -import org.alfasoftware.morf.metadata.SchemaResource; import org.alfasoftware.morf.metadata.Table; import org.alfasoftware.morf.sql.Statement; @@ -30,9 +29,8 @@ * * @author Copyright (c) Alfa Financial Software 2010 */ -public class InlineTableUpgrader extends SchemaChangeVisitorBase implements SchemaChangeVisitor { +public class InlineTableUpgrader extends AbstractSchemaChangeVisitor implements SchemaChangeVisitor { - private final SchemaResource schemaResource; private Schema currentSchema; private final SqlDialect sqlDialect; private final SqlStatementWriter sqlStatementWriter; @@ -44,14 +42,12 @@ public class InlineTableUpgrader extends SchemaChangeVisitorBase implements Sche * Default constructor. * * @param startSchema schema prior to upgrade step. - * @param schemaResource schema resource * @param sqlDialect Dialect to generate statements for the target database. * @param sqlStatementWriter recipient for all upgrade SQL statements. * @param idTable table for id generation. */ - public InlineTableUpgrader(Schema startSchema, SchemaResource schemaResource, SqlDialect sqlDialect, SqlStatementWriter sqlStatementWriter, Table idTable) { - super(startSchema, schemaResource, sqlDialect); - this.schemaResource = schemaResource; + public InlineTableUpgrader(Schema startSchema, SqlDialect sqlDialect, SqlStatementWriter sqlStatementWriter, Table idTable) { + super(startSchema, sqlDialect); this.currentSchema = startSchema; this.sqlDialect = sqlDialect; this.sqlStatementWriter = sqlStatementWriter; diff --git a/morf-core/src/main/java/org/alfasoftware/morf/upgrade/Upgrade.java b/morf-core/src/main/java/org/alfasoftware/morf/upgrade/Upgrade.java index ed3401e0d..068b28805 100755 --- a/morf-core/src/main/java/org/alfasoftware/morf/upgrade/Upgrade.java +++ b/morf-core/src/main/java/org/alfasoftware/morf/upgrade/Upgrade.java @@ -249,7 +249,7 @@ else if (upgradeAuditCount != getUpgradeAuditRowCount(upgradeAuditRowProcessor)) // if (!schemaChangeSequence.getUpgradeSteps().isEmpty()) { // Run the upgrader over all the ElementarySchemaChanges in the upgrade steps - InlineTableUpgrader upgrader = new InlineTableUpgrader(sourceSchema, connectionResources.openSchemaResource(), dialect, new SqlStatementWriter() { + InlineTableUpgrader upgrader = new InlineTableUpgrader(sourceSchema, dialect, new SqlStatementWriter() { @Override public void writeSql(Collection sql) { upgradeStatements.addAll(sql); diff --git a/morf-core/src/test/java/org/alfasoftware/morf/upgrade/TestGraphBasedUpgradeSchemaChangeVisitor.java b/morf-core/src/test/java/org/alfasoftware/morf/upgrade/TestGraphBasedUpgradeSchemaChangeVisitor.java index 82d1bced9..9bec99869 100644 --- a/morf-core/src/test/java/org/alfasoftware/morf/upgrade/TestGraphBasedUpgradeSchemaChangeVisitor.java +++ b/morf-core/src/test/java/org/alfasoftware/morf/upgrade/TestGraphBasedUpgradeSchemaChangeVisitor.java @@ -15,18 +15,14 @@ import java.util.Collections; import java.util.HashMap; import java.util.List; -import java.util.Locale; import java.util.Map; -import java.util.Optional; import java.util.UUID; import org.alfasoftware.morf.jdbc.DatabaseType; import org.alfasoftware.morf.jdbc.SqlDialect; -import org.alfasoftware.morf.metadata.AdditionalMetadata; import org.alfasoftware.morf.metadata.Column; import org.alfasoftware.morf.metadata.Index; import org.alfasoftware.morf.metadata.Schema; -import org.alfasoftware.morf.metadata.SchemaResource; import org.alfasoftware.morf.metadata.Sequence; import org.alfasoftware.morf.metadata.Table; import org.alfasoftware.morf.sql.SelectStatement; @@ -55,9 +51,6 @@ public class TestGraphBasedUpgradeSchemaChangeVisitor { @Mock private SqlDialect sqlDialect; - @Mock - private SchemaResource schemaResource; - @Mock private Table idTable; @@ -79,7 +72,7 @@ public void setup() { nodes.put(U1.class.getName(), n1); nodes.put(U2.class.getName(), n2); - visitor = new GraphBasedUpgradeSchemaChangeVisitor(sourceSchema, schemaResource, sqlDialect, idTable, nodes); + visitor = new GraphBasedUpgradeSchemaChangeVisitor(sourceSchema, sqlDialect, idTable, nodes); } @@ -121,9 +114,14 @@ public void testRemoveTableVisit() { public void testAddIndexVisit() { // given visitor.startStep(U1.class); + String ID_TABLE_NAME = "IdTableName"; AddIndex addIndex = mock(AddIndex.class); when(addIndex.apply(sourceSchema)).thenReturn(sourceSchema); + when(addIndex.getTableName()).thenReturn(ID_TABLE_NAME); when(sqlDialect.addIndexStatements(nullable(Table.class), nullable(Index.class))).thenReturn(STATEMENTS); + when(idTable.getName()).thenReturn(ID_TABLE_NAME); + when(idTable.ignoredIndexes()).thenReturn(Collections.emptyList()); + when(sourceSchema.getTable(ID_TABLE_NAME)).thenReturn(idTable); // when visitor.visit(addIndex); @@ -152,8 +150,6 @@ public void testVisitAddIndexWithPRFIndex() { when(addIndex.getTableName()).thenReturn(ID_TABLE_NAME); when(addIndex.getNewIndex()).thenReturn(newIndex); - AdditionalMetadata additionalMetadata = mock(AdditionalMetadata.class); - when(schemaResource.getAdditionalMetadata()).thenReturn(Optional.of(additionalMetadata)); Index indexPrf = mock(Index.class); when(indexPrf.getName()).thenReturn(ID_TABLE_NAME + "_PRF1"); when(indexPrf.columnNames()).thenReturn(List.of("column_1")); @@ -162,9 +158,10 @@ public void testVisitAddIndexWithPRFIndex() { when(indexPrf1.getName()).thenReturn(ID_TABLE_NAME + "_PRF2"); when(indexPrf1.columnNames()).thenReturn(List.of("column_2")); - Map> ignoredIndexes = new HashMap<>(); - ignoredIndexes.put(ID_TABLE_NAME.toUpperCase(Locale.ROOT), List.of(indexPrf, indexPrf1)); - when(additionalMetadata.ignoredIndexes()).thenReturn(ignoredIndexes); + Table newTable = mock(Table.class); + when(newTable.getName()).thenReturn(ID_TABLE_NAME); + when(newTable.ignoredIndexes()).thenReturn(Lists.newArrayList(indexPrf, indexPrf1)); + when(sourceSchema.getTable(ID_TABLE_NAME)).thenReturn(newTable); when(sqlDialect.renameIndexStatements(nullable(Table.class), eq(ID_TABLE_NAME + "_PRF1"), eq(ID_TABLE_NAME + "_1"))).thenReturn(STATEMENTS); when(sqlDialect.renameIndexStatements(nullable(Table.class), eq(ID_TABLE_NAME + "_PRF2"), eq(ID_TABLE_NAME + "_2"))).thenReturn(STATEMENTS); @@ -490,7 +487,7 @@ public void testFactory() { GraphBasedUpgradeSchemaChangeVisitorFactory factory = new GraphBasedUpgradeSchemaChangeVisitorFactory(); // when - GraphBasedUpgradeSchemaChangeVisitor created = factory.create(sourceSchema, schemaResource, sqlDialect, idTable, nodes); + GraphBasedUpgradeSchemaChangeVisitor created = factory.create(sourceSchema, sqlDialect, idTable, nodes); // then assertNotNull(created); diff --git a/morf-core/src/test/java/org/alfasoftware/morf/upgrade/TestInlineTableUpgrader.java b/morf-core/src/test/java/org/alfasoftware/morf/upgrade/TestInlineTableUpgrader.java index fd414d245..02bb5723d 100755 --- a/morf-core/src/test/java/org/alfasoftware/morf/upgrade/TestInlineTableUpgrader.java +++ b/morf-core/src/test/java/org/alfasoftware/morf/upgrade/TestInlineTableUpgrader.java @@ -32,19 +32,13 @@ import static org.mockito.Mockito.when; import java.util.Collections; -import java.util.HashMap; import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Optional; import org.alfasoftware.morf.jdbc.DatabaseType; import org.alfasoftware.morf.jdbc.SqlDialect; -import org.alfasoftware.morf.metadata.AdditionalMetadata; import org.alfasoftware.morf.metadata.Column; import org.alfasoftware.morf.metadata.Index; import org.alfasoftware.morf.metadata.Schema; -import org.alfasoftware.morf.metadata.SchemaResource; import org.alfasoftware.morf.metadata.Sequence; import org.alfasoftware.morf.metadata.Table; import org.alfasoftware.morf.sql.DeleteStatement; @@ -57,6 +51,8 @@ import org.mockito.ArgumentCaptor; import org.mockito.Mockito; +import com.google.common.collect.Lists; + /** * */ @@ -66,7 +62,6 @@ public class TestInlineTableUpgrader { private InlineTableUpgrader upgrader; private Schema schema; - private SchemaResource schemaResource; private SqlDialect sqlDialect; private SqlStatementWriter sqlStatementWriter; @@ -78,8 +73,7 @@ public void setUp() { schema = mock(Schema.class); sqlDialect = mock(SqlDialect.class); sqlStatementWriter = mock(SqlStatementWriter.class); - schemaResource = mock(SchemaResource.class); - upgrader = new InlineTableUpgrader(schema, schemaResource, sqlDialect, sqlStatementWriter, SqlDialect.IdTable.withDeterministicName(ID_TABLE_NAME)); + upgrader = new InlineTableUpgrader(schema, sqlDialect, sqlStatementWriter, SqlDialect.IdTable.withDeterministicName(ID_TABLE_NAME)); } @@ -158,6 +152,12 @@ public void testVisitAddIndex() { // given AddIndex addIndex = mock(AddIndex.class); given(addIndex.apply(schema)).willReturn(schema); + when(addIndex.getTableName()).thenReturn(ID_TABLE_NAME); + + Table newTable = mock(Table.class); + when(newTable.getName()).thenReturn(ID_TABLE_NAME); + when(newTable.ignoredIndexes()).thenReturn(Lists.newArrayList()); + when(schema.getTable(ID_TABLE_NAME)).thenReturn(newTable); // when upgrader.visit(addIndex); @@ -184,8 +184,6 @@ public void testVisitAddIndexWithPRFIndex() { when(addIndex.getTableName()).thenReturn(ID_TABLE_NAME); when(addIndex.getNewIndex()).thenReturn(newIndex); - AdditionalMetadata additionalMetadata = mock(AdditionalMetadata.class); - when(schemaResource.getAdditionalMetadata()).thenReturn(Optional.of(additionalMetadata)); Index indexPrf = mock(Index.class); when(indexPrf.getName()).thenReturn(ID_TABLE_NAME + "_PRF1"); when(indexPrf.columnNames()).thenReturn(List.of("column_1")); @@ -193,9 +191,10 @@ public void testVisitAddIndexWithPRFIndex() { when(indexPrf1.getName()).thenReturn(ID_TABLE_NAME + "_PRF2"); when(indexPrf1.columnNames()).thenReturn(List.of("column_2")); - Map> ignoredIndexes = new HashMap<>(); - ignoredIndexes.put(ID_TABLE_NAME.toUpperCase(Locale.ROOT), List.of(indexPrf, indexPrf1)); - when(additionalMetadata.ignoredIndexes()).thenReturn(ignoredIndexes); + Table newTable = mock(Table.class); + when(newTable.getName()).thenReturn(ID_TABLE_NAME); + when(newTable.ignoredIndexes()).thenReturn(Lists.newArrayList(indexPrf, indexPrf1)); + when(schema.getTable(ID_TABLE_NAME)).thenReturn(newTable); Index newIndex1 = mock(Index.class); when(newIndex1.getName()).thenReturn(ID_TABLE_NAME + "_2"); @@ -213,6 +212,8 @@ public void testVisitAddIndexWithPRFIndex() { when(addIndex2.getTableName()).thenReturn(ID_TABLE_NAME); when(addIndex2.getNewIndex()).thenReturn(newIndex2); + when(newTable.indexes()).thenReturn(Lists.newArrayList(newIndex1, newIndex2)); + // when upgrader.visit(addIndex); upgrader.visit(addIndex1); diff --git a/morf-integration-test/src/test/java/org/alfasoftware/morf/jdbc/TestDatabaseMetaDataProvider.java b/morf-integration-test/src/test/java/org/alfasoftware/morf/jdbc/TestDatabaseMetaDataProvider.java index 1bf088389..6b7a803f8 100755 --- a/morf-integration-test/src/test/java/org/alfasoftware/morf/jdbc/TestDatabaseMetaDataProvider.java +++ b/morf-integration-test/src/test/java/org/alfasoftware/morf/jdbc/TestDatabaseMetaDataProvider.java @@ -16,7 +16,12 @@ package org.alfasoftware.morf.jdbc; import static java.util.stream.Collectors.toList; -import static org.alfasoftware.morf.metadata.SchemaUtils.*; +import static org.alfasoftware.morf.metadata.SchemaUtils.column; +import static org.alfasoftware.morf.metadata.SchemaUtils.index; +import static org.alfasoftware.morf.metadata.SchemaUtils.schema; +import static org.alfasoftware.morf.metadata.SchemaUtils.sequence; +import static org.alfasoftware.morf.metadata.SchemaUtils.table; +import static org.alfasoftware.morf.metadata.SchemaUtils.view; import static org.alfasoftware.morf.sql.SqlUtils.field; import static org.alfasoftware.morf.sql.SqlUtils.select; import static org.alfasoftware.morf.sql.SqlUtils.tableRef; @@ -37,10 +42,16 @@ import java.util.List; import java.util.function.Function; -import net.jcip.annotations.NotThreadSafe; - import org.alfasoftware.morf.guicesupport.InjectMembersRule; -import org.alfasoftware.morf.metadata.*; +import org.alfasoftware.morf.metadata.Column; +import org.alfasoftware.morf.metadata.DataType; +import org.alfasoftware.morf.metadata.Index; +import org.alfasoftware.morf.metadata.Schema; +import org.alfasoftware.morf.metadata.SchemaResource; +import org.alfasoftware.morf.metadata.SchemaUtils; +import org.alfasoftware.morf.metadata.Sequence; +import org.alfasoftware.morf.metadata.Table; +import org.alfasoftware.morf.metadata.View; import org.alfasoftware.morf.sql.SelectStatement; import org.alfasoftware.morf.testing.DatabaseSchemaManager; import org.alfasoftware.morf.testing.DatabaseSchemaManager.TruncationBehavior; @@ -58,6 +69,8 @@ import com.google.common.collect.Iterables; import com.google.inject.Inject; +import net.jcip.annotations.NotThreadSafe; + /** * Tests for {@link DatabaseMetaDataProvider}. * @@ -102,7 +115,8 @@ public class TestDatabaseMetaDataProvider { column("nullableDateCol", DataType.DATE).nullable()) .indexes( index("WithTypes_1").columns("booleanCol", "dateCol"), - index("NaturalKey").columns("decimalElevenCol").unique()), + index("NaturalKey").columns("decimalElevenCol").unique(), + index("WithTypes_PRF1").columns("decimalNineFiveCol", "bigIntegerCol")), table("WithLobs") .columns( SchemaUtils.autonumber("autonumfield", 17), @@ -268,6 +282,11 @@ public void testTableWithTypes() throws SQLException { indexMatcher( index("NaturalKey").columns("decimalElevenCol").unique())) )); + + assertThat(table.ignoredIndexes(), + containsInAnyOrder(ImmutableList.of( + indexMatcher(index("WithTypes_PRF1").columns("decimalNineFiveCol", "bigIntegerCol")) + ))); } } diff --git a/morf-oracle/src/main/java/org/alfasoftware/morf/jdbc/oracle/OracleMetaDataProvider.java b/morf-oracle/src/main/java/org/alfasoftware/morf/jdbc/oracle/OracleMetaDataProvider.java index 3468861d1..e1a7c4f2b 100755 --- a/morf-oracle/src/main/java/org/alfasoftware/morf/jdbc/oracle/OracleMetaDataProvider.java +++ b/morf-oracle/src/main/java/org/alfasoftware/morf/jdbc/oracle/OracleMetaDataProvider.java @@ -85,7 +85,6 @@ public class OracleMetaDataProvider implements AdditionalMetadata { private final Connection connection; private final String schemaName; private Map primaryKeyIndexNames; - private Map> ignoredIndexesMap; /** * Construct a new meta data provider. @@ -163,16 +162,6 @@ public Map primaryKeyIndexNames() { } - @Override - public Map> ignoredIndexes() { - if (ignoredIndexesMap != null) { - return ignoredIndexesMap; - } - tableMap(); - return ignoredIndexesMap; - } - - /** * A table name reading method which is more efficient than the Oracle driver meta-data version. * @@ -335,7 +324,6 @@ private void handleTableColumnRow(final Map> primaryKeys, // -- Stage 3: find the index names... // primaryKeyIndexNames = Maps.newHashMap(); - ignoredIndexesMap = Maps.newHashMap(); final String getIndexNamesSql = "select table_name, index_name, uniqueness, status from ALL_INDEXES where owner=? order by table_name, index_name"; runSQL(getIndexNamesSql, new ResultSetHandler() { @Override @@ -384,13 +372,7 @@ public void handle(ResultSet resultSet) throws SQLException { if (DatabaseMetaDataProviderUtils.shouldIgnoreIndex(indexName)) { Index ignoredIndex = getAssembledIndex(unique, indexNameFinal); - if (ignoredIndexesMap.containsKey(tableName)) { - List indexList = new ArrayList<>(ignoredIndexesMap.get(tableName)); - indexList.add(ignoredIndex); - ignoredIndexesMap.put(tableName, indexList); - } else { - ignoredIndexesMap.put(tableName, List.of(ignoredIndex)); - } + currentTable.ignoredIndexes().add(ignoredIndex); continue; } @@ -470,7 +452,7 @@ public void handle(ResultSet resultSet) throws SQLException { if (DatabaseMetaDataProviderUtils.shouldIgnoreIndex(indexName)) { Index lastIndex = null; - for (Index currentIndex : ignoredIndexesMap.get(tableName)) { + for (Index currentIndex : currentTable.ignoredIndexes()) { if (currentIndex.getName().equalsIgnoreCase(indexName)) { lastIndex = currentIndex; break; diff --git a/morf-oracle/src/test/java/org/alfasoftware/morf/jdbc/oracle/TestOracleMetaDataProvider.java b/morf-oracle/src/test/java/org/alfasoftware/morf/jdbc/oracle/TestOracleMetaDataProvider.java index 6c38de8d2..af9aba9f8 100755 --- a/morf-oracle/src/test/java/org/alfasoftware/morf/jdbc/oracle/TestOracleMetaDataProvider.java +++ b/morf-oracle/src/test/java/org/alfasoftware/morf/jdbc/oracle/TestOracleMetaDataProvider.java @@ -211,16 +211,16 @@ public void testIgnoredIndexes() throws SQLException { // When final AdditionalMetadata oracleMetaDataProvider = (AdditionalMetadata) oracle.openSchema(connection, "TESTDATABASE", "TESTSCHEMA"); - Map> actualIgnoredIndexes = oracleMetaDataProvider.ignoredIndexes(); - assertEquals("Ignored indexes map size.", 1, actualIgnoredIndexes.size()); - assertEquals("Ignored AREALTABLE table indexes size.", 2, actualIgnoredIndexes.get("AREALTABLE").size()); - Index index = actualIgnoredIndexes.get("AREALTABLE").get(0); + List actualIgnoredIndexes = oracleMetaDataProvider.getTable("AREALTABLE").ignoredIndexes(); + assertEquals("Ignored indexes size.", 2, actualIgnoredIndexes.size()); + assertEquals("Ignored AREALTABLE table indexes size.", 2, actualIgnoredIndexes.size()); + Index index = actualIgnoredIndexes.get(0); assertEquals("Ignored index name.", "AREALTABLE_PRF1", index.getName()); assertEquals("Ignored index column.", "column2", index.columnNames().get(0)); assertFalse("Ignored index uniqueness.", index.isUnique()); assertEquals("Index-AREALTABLE_PRF1--column2", index.toStringHelper()); - Index index2 = actualIgnoredIndexes.get("AREALTABLE").get(1); + Index index2 = actualIgnoredIndexes.get(1); assertEquals("Ignored index name.", "AREALTABLE_PRF2", index2.getName()); assertEquals("Ignored index column.", "column3", index2.columnNames().get(0)); assertTrue("Ignored index uniqueness.", index2.isUnique()); diff --git a/morf-testsupport/src/main/java/org/alfasoftware/morf/testing/UpgradeTestHelper.java b/morf-testsupport/src/main/java/org/alfasoftware/morf/testing/UpgradeTestHelper.java index 786ad63c0..91ef6cd83 100755 --- a/morf-testsupport/src/main/java/org/alfasoftware/morf/testing/UpgradeTestHelper.java +++ b/morf-testsupport/src/main/java/org/alfasoftware/morf/testing/UpgradeTestHelper.java @@ -117,7 +117,7 @@ public void testUpgrades(Schema finalSchema, Iterable sqlScript = Lists.newLinkedList(); // Upgrader, which captures the SQL as a script - InlineTableUpgrader inlineTableUpgrader = new InlineTableUpgrader(fromSchema, connectionResources.openSchemaResource(), + InlineTableUpgrader inlineTableUpgrader = new InlineTableUpgrader(fromSchema, connectionResources.sqlDialect(), new SqlStatementWriter() { @Override public void writeSql(Collection sql) { From 94fe49d727ab1f0a4d81aa18d840c52ae998d1b9 Mon Sep 17 00:00:00 2001 From: Bruno Monteiro Date: Mon, 5 May 2025 14:23:00 +0100 Subject: [PATCH 07/11] Changes that apply to more than one file: - Re-add schemaResources for constructor of InlineTableUpgrader and GraphBasedUpgradeSchemaChangeVisitor Files: - AbstractSchemaChangeVisitor - GraphBasedUpgradeBuilder - GraphBasedUpgradeSchemaChangeVisitor - InlineTableUpgrader - OracleMetaDataProvider - Upgrade - UpgradeTestHelper Update tests to pass. --- .../morf/upgrade/AbstractSchemaChangeVisitor.java | 7 +++++-- .../morf/upgrade/GraphBasedUpgradeBuilder.java | 1 + .../GraphBasedUpgradeSchemaChangeVisitor.java | 12 ++++++++---- .../morf/upgrade/InlineTableUpgrader.java | 6 ++++-- .../java/org/alfasoftware/morf/upgrade/Upgrade.java | 2 +- .../TestGraphBasedUpgradeSchemaChangeVisitor.java | 12 ++++++++---- .../morf/upgrade/TestInlineTableUpgrader.java | 9 ++++++--- .../alfasoftware/morf/testing/UpgradeTestHelper.java | 2 +- 8 files changed, 34 insertions(+), 17 deletions(-) diff --git a/morf-core/src/main/java/org/alfasoftware/morf/upgrade/AbstractSchemaChangeVisitor.java b/morf-core/src/main/java/org/alfasoftware/morf/upgrade/AbstractSchemaChangeVisitor.java index d99821521..2764f278d 100644 --- a/morf-core/src/main/java/org/alfasoftware/morf/upgrade/AbstractSchemaChangeVisitor.java +++ b/morf-core/src/main/java/org/alfasoftware/morf/upgrade/AbstractSchemaChangeVisitor.java @@ -6,6 +6,7 @@ import org.alfasoftware.morf.jdbc.SqlDialect; import org.alfasoftware.morf.metadata.Index; import org.alfasoftware.morf.metadata.Schema; +import org.alfasoftware.morf.metadata.SchemaResource; import org.alfasoftware.morf.metadata.Table; /** @@ -15,12 +16,14 @@ public abstract class AbstractSchemaChangeVisitor implements SchemaChangeVisitor protected Schema sourceSchema; protected SqlDialect sqlDialect; + protected final SchemaResource schemaResource; protected abstract void writeStatements(Collection statements); - public AbstractSchemaChangeVisitor(Schema sourceSchema, SqlDialect sqlDialect) { + public AbstractSchemaChangeVisitor(Schema sourceSchema, SchemaResource schemaResource, SqlDialect sqlDialect) { this.sourceSchema = sourceSchema; + this.schemaResource = schemaResource; this.sqlDialect = sqlDialect; } @@ -29,7 +32,7 @@ public AbstractSchemaChangeVisitor(Schema sourceSchema, SqlDialect sqlDialect) { public void visit(AddIndex addIndex) { sourceSchema = addIndex.apply(sourceSchema); Index foundIndex = null; - Table table = sourceSchema.getTable(addIndex.getTableName()); + Table table = schemaResource.getTable(addIndex.getTableName()); if (!table.ignoredIndexes().isEmpty()) { List tableIgnoredIndexes = table.ignoredIndexes(); for (Index index : tableIgnoredIndexes) { diff --git a/morf-core/src/main/java/org/alfasoftware/morf/upgrade/GraphBasedUpgradeBuilder.java b/morf-core/src/main/java/org/alfasoftware/morf/upgrade/GraphBasedUpgradeBuilder.java index 9691e6b31..d4bfe6b2d 100644 --- a/morf-core/src/main/java/org/alfasoftware/morf/upgrade/GraphBasedUpgradeBuilder.java +++ b/morf-core/src/main/java/org/alfasoftware/morf/upgrade/GraphBasedUpgradeBuilder.java @@ -101,6 +101,7 @@ public GraphBasedUpgrade prepareGraphBasedUpgrade(List initialisationSql GraphBasedUpgradeSchemaChangeVisitor visitor = visitorFactory.create( sourceSchema, + connectionResources.openSchemaResource(), connectionResources.sqlDialect(), idTable, nodes.stream().collect(Collectors.toMap(GraphBasedUpgradeNode::getName, Function.identity()))); diff --git a/morf-core/src/main/java/org/alfasoftware/morf/upgrade/GraphBasedUpgradeSchemaChangeVisitor.java b/morf-core/src/main/java/org/alfasoftware/morf/upgrade/GraphBasedUpgradeSchemaChangeVisitor.java index 3983fbb22..7c24c680c 100644 --- a/morf-core/src/main/java/org/alfasoftware/morf/upgrade/GraphBasedUpgradeSchemaChangeVisitor.java +++ b/morf-core/src/main/java/org/alfasoftware/morf/upgrade/GraphBasedUpgradeSchemaChangeVisitor.java @@ -6,6 +6,7 @@ import org.alfasoftware.morf.jdbc.SqlDialect; import org.alfasoftware.morf.metadata.Schema; +import org.alfasoftware.morf.metadata.SchemaResource; import org.alfasoftware.morf.metadata.Table; import org.alfasoftware.morf.sql.Statement; @@ -19,6 +20,7 @@ class GraphBasedUpgradeSchemaChangeVisitor extends AbstractSchemaChangeVisitor implements SchemaChangeVisitor { private Schema sourceSchema; + private SchemaResource schemaResource; private final SqlDialect sqlDialect; private final Table idTable; private final TableNameResolver tracker; @@ -30,13 +32,14 @@ class GraphBasedUpgradeSchemaChangeVisitor extends AbstractSchemaChangeVisitor i * Default constructor. * * @param sourceSchema schema prior to upgrade step. + * @param schemaResource schema resource * @param sqlDialect dialect to generate statements for the target database. * @param idTable table for id generation. * @param upgradeNodes all the {@link GraphBasedUpgradeNode} instances in the * upgrade for which the visitor will generate statements */ - GraphBasedUpgradeSchemaChangeVisitor(Schema sourceSchema, SqlDialect sqlDialect, Table idTable, Map upgradeNodes) { - super(sourceSchema, sqlDialect); + GraphBasedUpgradeSchemaChangeVisitor(Schema sourceSchema, SchemaResource schemaResource, SqlDialect sqlDialect, Table idTable, Map upgradeNodes) { + super(sourceSchema, schemaResource, sqlDialect); this.sourceSchema = sourceSchema; this.sqlDialect = sqlDialect; this.idTable = idTable; @@ -237,15 +240,16 @@ static class GraphBasedUpgradeSchemaChangeVisitorFactory { * Creates {@link GraphBasedUpgradeSchemaChangeVisitor} instance. * * @param sourceSchema schema prior to upgrade step + * @param schemaResource schema resource * @param sqlDialect dialect to generate statements for the target database * @param idTable table for id generation * @param upgradeNodes all the {@link GraphBasedUpgradeNode} instances in the upgrade for * which the visitor will generate statements * @return new {@link GraphBasedUpgradeSchemaChangeVisitor} instance */ - GraphBasedUpgradeSchemaChangeVisitor create(Schema sourceSchema, SqlDialect sqlDialect, Table idTable, + GraphBasedUpgradeSchemaChangeVisitor create(Schema sourceSchema, SchemaResource schemaResource, SqlDialect sqlDialect, Table idTable, Map upgradeNodes) { - return new GraphBasedUpgradeSchemaChangeVisitor(sourceSchema, sqlDialect, idTable, upgradeNodes); + return new GraphBasedUpgradeSchemaChangeVisitor(sourceSchema, schemaResource, sqlDialect, idTable, upgradeNodes); } } } diff --git a/morf-core/src/main/java/org/alfasoftware/morf/upgrade/InlineTableUpgrader.java b/morf-core/src/main/java/org/alfasoftware/morf/upgrade/InlineTableUpgrader.java index bb9257dff..3eec32f94 100755 --- a/morf-core/src/main/java/org/alfasoftware/morf/upgrade/InlineTableUpgrader.java +++ b/morf-core/src/main/java/org/alfasoftware/morf/upgrade/InlineTableUpgrader.java @@ -21,6 +21,7 @@ import org.alfasoftware.morf.jdbc.SqlDialect; import org.alfasoftware.morf.metadata.Schema; +import org.alfasoftware.morf.metadata.SchemaResource; import org.alfasoftware.morf.metadata.Table; import org.alfasoftware.morf.sql.Statement; @@ -42,12 +43,13 @@ public class InlineTableUpgrader extends AbstractSchemaChangeVisitor implements * Default constructor. * * @param startSchema schema prior to upgrade step. + * @param schemaResource schema resource * @param sqlDialect Dialect to generate statements for the target database. * @param sqlStatementWriter recipient for all upgrade SQL statements. * @param idTable table for id generation. */ - public InlineTableUpgrader(Schema startSchema, SqlDialect sqlDialect, SqlStatementWriter sqlStatementWriter, Table idTable) { - super(startSchema, sqlDialect); + public InlineTableUpgrader(Schema startSchema, SchemaResource schemaResource, SqlDialect sqlDialect, SqlStatementWriter sqlStatementWriter, Table idTable) { + super(startSchema, schemaResource, sqlDialect); this.currentSchema = startSchema; this.sqlDialect = sqlDialect; this.sqlStatementWriter = sqlStatementWriter; diff --git a/morf-core/src/main/java/org/alfasoftware/morf/upgrade/Upgrade.java b/morf-core/src/main/java/org/alfasoftware/morf/upgrade/Upgrade.java index 068b28805..d7dd6d286 100755 --- a/morf-core/src/main/java/org/alfasoftware/morf/upgrade/Upgrade.java +++ b/morf-core/src/main/java/org/alfasoftware/morf/upgrade/Upgrade.java @@ -249,7 +249,7 @@ else if (upgradeAuditCount != getUpgradeAuditRowCount(upgradeAuditRowProcessor)) // if (!schemaChangeSequence.getUpgradeSteps().isEmpty()) { // Run the upgrader over all the ElementarySchemaChanges in the upgrade steps - InlineTableUpgrader upgrader = new InlineTableUpgrader(sourceSchema, dialect, new SqlStatementWriter() { + InlineTableUpgrader upgrader = new InlineTableUpgrader(sourceSchema, connectionResources.openSchemaResource(), dialect, new SqlStatementWriter() { @Override public void writeSql(Collection sql) { upgradeStatements.addAll(sql); diff --git a/morf-core/src/test/java/org/alfasoftware/morf/upgrade/TestGraphBasedUpgradeSchemaChangeVisitor.java b/morf-core/src/test/java/org/alfasoftware/morf/upgrade/TestGraphBasedUpgradeSchemaChangeVisitor.java index 9bec99869..b926ae513 100644 --- a/morf-core/src/test/java/org/alfasoftware/morf/upgrade/TestGraphBasedUpgradeSchemaChangeVisitor.java +++ b/morf-core/src/test/java/org/alfasoftware/morf/upgrade/TestGraphBasedUpgradeSchemaChangeVisitor.java @@ -23,6 +23,7 @@ import org.alfasoftware.morf.metadata.Column; import org.alfasoftware.morf.metadata.Index; import org.alfasoftware.morf.metadata.Schema; +import org.alfasoftware.morf.metadata.SchemaResource; import org.alfasoftware.morf.metadata.Sequence; import org.alfasoftware.morf.metadata.Table; import org.alfasoftware.morf.sql.SelectStatement; @@ -57,6 +58,9 @@ public class TestGraphBasedUpgradeSchemaChangeVisitor { @Mock private GraphBasedUpgradeNode n1, n2; + @Mock + SchemaResource schemaResource; + private final static List STATEMENTS = Lists.newArrayList("a", "b"); private Map nodes; @@ -72,7 +76,7 @@ public void setup() { nodes.put(U1.class.getName(), n1); nodes.put(U2.class.getName(), n2); - visitor = new GraphBasedUpgradeSchemaChangeVisitor(sourceSchema, sqlDialect, idTable, nodes); + visitor = new GraphBasedUpgradeSchemaChangeVisitor(sourceSchema, schemaResource, sqlDialect, idTable, nodes); } @@ -121,7 +125,7 @@ public void testAddIndexVisit() { when(sqlDialect.addIndexStatements(nullable(Table.class), nullable(Index.class))).thenReturn(STATEMENTS); when(idTable.getName()).thenReturn(ID_TABLE_NAME); when(idTable.ignoredIndexes()).thenReturn(Collections.emptyList()); - when(sourceSchema.getTable(ID_TABLE_NAME)).thenReturn(idTable); + when(schemaResource.getTable(ID_TABLE_NAME)).thenReturn(idTable); // when visitor.visit(addIndex); @@ -161,7 +165,7 @@ public void testVisitAddIndexWithPRFIndex() { Table newTable = mock(Table.class); when(newTable.getName()).thenReturn(ID_TABLE_NAME); when(newTable.ignoredIndexes()).thenReturn(Lists.newArrayList(indexPrf, indexPrf1)); - when(sourceSchema.getTable(ID_TABLE_NAME)).thenReturn(newTable); + when(schemaResource.getTable(ID_TABLE_NAME)).thenReturn(newTable); when(sqlDialect.renameIndexStatements(nullable(Table.class), eq(ID_TABLE_NAME + "_PRF1"), eq(ID_TABLE_NAME + "_1"))).thenReturn(STATEMENTS); when(sqlDialect.renameIndexStatements(nullable(Table.class), eq(ID_TABLE_NAME + "_PRF2"), eq(ID_TABLE_NAME + "_2"))).thenReturn(STATEMENTS); @@ -487,7 +491,7 @@ public void testFactory() { GraphBasedUpgradeSchemaChangeVisitorFactory factory = new GraphBasedUpgradeSchemaChangeVisitorFactory(); // when - GraphBasedUpgradeSchemaChangeVisitor created = factory.create(sourceSchema, sqlDialect, idTable, nodes); + GraphBasedUpgradeSchemaChangeVisitor created = factory.create(sourceSchema, schemaResource, sqlDialect, idTable, nodes); // then assertNotNull(created); diff --git a/morf-core/src/test/java/org/alfasoftware/morf/upgrade/TestInlineTableUpgrader.java b/morf-core/src/test/java/org/alfasoftware/morf/upgrade/TestInlineTableUpgrader.java index 02bb5723d..29def1722 100755 --- a/morf-core/src/test/java/org/alfasoftware/morf/upgrade/TestInlineTableUpgrader.java +++ b/morf-core/src/test/java/org/alfasoftware/morf/upgrade/TestInlineTableUpgrader.java @@ -39,6 +39,7 @@ import org.alfasoftware.morf.metadata.Column; import org.alfasoftware.morf.metadata.Index; import org.alfasoftware.morf.metadata.Schema; +import org.alfasoftware.morf.metadata.SchemaResource; import org.alfasoftware.morf.metadata.Sequence; import org.alfasoftware.morf.metadata.Table; import org.alfasoftware.morf.sql.DeleteStatement; @@ -64,6 +65,7 @@ public class TestInlineTableUpgrader { private Schema schema; private SqlDialect sqlDialect; private SqlStatementWriter sqlStatementWriter; + private SchemaResource schemaResource; /** * Setup method run before each test. @@ -73,7 +75,8 @@ public void setUp() { schema = mock(Schema.class); sqlDialect = mock(SqlDialect.class); sqlStatementWriter = mock(SqlStatementWriter.class); - upgrader = new InlineTableUpgrader(schema, sqlDialect, sqlStatementWriter, SqlDialect.IdTable.withDeterministicName(ID_TABLE_NAME)); + schemaResource = mock(SchemaResource.class); + upgrader = new InlineTableUpgrader(schema, schemaResource, sqlDialect, sqlStatementWriter, SqlDialect.IdTable.withDeterministicName(ID_TABLE_NAME)); } @@ -157,7 +160,7 @@ public void testVisitAddIndex() { Table newTable = mock(Table.class); when(newTable.getName()).thenReturn(ID_TABLE_NAME); when(newTable.ignoredIndexes()).thenReturn(Lists.newArrayList()); - when(schema.getTable(ID_TABLE_NAME)).thenReturn(newTable); + when(schemaResource.getTable(ID_TABLE_NAME)).thenReturn(newTable); // when upgrader.visit(addIndex); @@ -194,7 +197,7 @@ public void testVisitAddIndexWithPRFIndex() { Table newTable = mock(Table.class); when(newTable.getName()).thenReturn(ID_TABLE_NAME); when(newTable.ignoredIndexes()).thenReturn(Lists.newArrayList(indexPrf, indexPrf1)); - when(schema.getTable(ID_TABLE_NAME)).thenReturn(newTable); + when(schemaResource.getTable(ID_TABLE_NAME)).thenReturn(newTable); Index newIndex1 = mock(Index.class); when(newIndex1.getName()).thenReturn(ID_TABLE_NAME + "_2"); diff --git a/morf-testsupport/src/main/java/org/alfasoftware/morf/testing/UpgradeTestHelper.java b/morf-testsupport/src/main/java/org/alfasoftware/morf/testing/UpgradeTestHelper.java index 91ef6cd83..3f08d5827 100755 --- a/morf-testsupport/src/main/java/org/alfasoftware/morf/testing/UpgradeTestHelper.java +++ b/morf-testsupport/src/main/java/org/alfasoftware/morf/testing/UpgradeTestHelper.java @@ -118,7 +118,7 @@ public void testUpgrades(Schema finalSchema, Iterable sql) { sqlScript.addAll(sql); From 0c4f2b0d71020467849c3475d6ade94239090bd6 Mon Sep 17 00:00:00 2001 From: Bruno Monteiro Date: Mon, 5 May 2025 14:52:26 +0100 Subject: [PATCH 08/11] Solve Sonar issues. --- .../morf/jdbc/DatabaseMetaDataProvider.java | 21 ++++++---- .../GraphBasedUpgradeSchemaChangeVisitor.java | 3 -- .../morf/upgrade/InlineTableUpgrader.java | 1 - ...tGraphBasedUpgradeSchemaChangeVisitor.java | 38 +++++++++---------- .../jdbc/TestDatabaseMetaDataProvider.java | 2 +- 5 files changed, 34 insertions(+), 31 deletions(-) diff --git a/morf-core/src/main/java/org/alfasoftware/morf/jdbc/DatabaseMetaDataProvider.java b/morf-core/src/main/java/org/alfasoftware/morf/jdbc/DatabaseMetaDataProvider.java index ebec5ba46..0daab2d64 100755 --- a/morf-core/src/main/java/org/alfasoftware/morf/jdbc/DatabaseMetaDataProvider.java +++ b/morf-core/src/main/java/org/alfasoftware/morf/jdbc/DatabaseMetaDataProvider.java @@ -830,13 +830,7 @@ protected List loadTableIndexes(RealName tableName, boolean returnIgnored indexUniqueness.put(indexName, unique); - if (DatabaseMetaDataProviderUtils.shouldIgnoreIndex(indexName.getDbName())) { - ignoredIndexColumns.computeIfAbsent(indexName, k -> ImmutableList.builder()) - .add(columnName); - } else { - indexColumns.computeIfAbsent(indexName, k -> ImmutableList.builder()) - .add(columnName); - } + appendIndexColumn(indexName, columnName, ignoredIndexColumns, indexColumns); } catch (SQLException e) { throw new RuntimeSqlException("Error reading metadata for index ["+indexName+"] on table ["+tableName+"]", e); @@ -863,6 +857,19 @@ protected List loadTableIndexes(RealName tableName, boolean returnIgnored } + private static void appendIndexColumn(RealName indexName, RealName columnName, Map> ignoredIndexColumns, Map> indexColumns) + { + if (DatabaseMetaDataProviderUtils.shouldIgnoreIndex(indexName.getDbName())) { + ignoredIndexColumns.computeIfAbsent(indexName, k -> ImmutableList.builder()) + .add(columnName); + } else { + indexColumns.computeIfAbsent(indexName, k -> ImmutableList.builder()) + .add(columnName); + } + } + + /** * Retrieves index name from a result set. * diff --git a/morf-core/src/main/java/org/alfasoftware/morf/upgrade/GraphBasedUpgradeSchemaChangeVisitor.java b/morf-core/src/main/java/org/alfasoftware/morf/upgrade/GraphBasedUpgradeSchemaChangeVisitor.java index 7c24c680c..2e4f1c1c9 100644 --- a/morf-core/src/main/java/org/alfasoftware/morf/upgrade/GraphBasedUpgradeSchemaChangeVisitor.java +++ b/morf-core/src/main/java/org/alfasoftware/morf/upgrade/GraphBasedUpgradeSchemaChangeVisitor.java @@ -19,9 +19,6 @@ */ class GraphBasedUpgradeSchemaChangeVisitor extends AbstractSchemaChangeVisitor implements SchemaChangeVisitor { - private Schema sourceSchema; - private SchemaResource schemaResource; - private final SqlDialect sqlDialect; private final Table idTable; private final TableNameResolver tracker; private final Map upgradeNodes; diff --git a/morf-core/src/main/java/org/alfasoftware/morf/upgrade/InlineTableUpgrader.java b/morf-core/src/main/java/org/alfasoftware/morf/upgrade/InlineTableUpgrader.java index 3eec32f94..754f20416 100755 --- a/morf-core/src/main/java/org/alfasoftware/morf/upgrade/InlineTableUpgrader.java +++ b/morf-core/src/main/java/org/alfasoftware/morf/upgrade/InlineTableUpgrader.java @@ -33,7 +33,6 @@ public class InlineTableUpgrader extends AbstractSchemaChangeVisitor implements SchemaChangeVisitor { private Schema currentSchema; - private final SqlDialect sqlDialect; private final SqlStatementWriter sqlStatementWriter; private final Table idTable; private final TableNameResolver tracker; diff --git a/morf-core/src/test/java/org/alfasoftware/morf/upgrade/TestGraphBasedUpgradeSchemaChangeVisitor.java b/morf-core/src/test/java/org/alfasoftware/morf/upgrade/TestGraphBasedUpgradeSchemaChangeVisitor.java index b926ae513..0772562d4 100644 --- a/morf-core/src/test/java/org/alfasoftware/morf/upgrade/TestGraphBasedUpgradeSchemaChangeVisitor.java +++ b/morf-core/src/test/java/org/alfasoftware/morf/upgrade/TestGraphBasedUpgradeSchemaChangeVisitor.java @@ -118,14 +118,14 @@ public void testRemoveTableVisit() { public void testAddIndexVisit() { // given visitor.startStep(U1.class); - String ID_TABLE_NAME = "IdTableName"; + String idTableName = "IdTableName"; AddIndex addIndex = mock(AddIndex.class); when(addIndex.apply(sourceSchema)).thenReturn(sourceSchema); - when(addIndex.getTableName()).thenReturn(ID_TABLE_NAME); + when(addIndex.getTableName()).thenReturn(idTableName); when(sqlDialect.addIndexStatements(nullable(Table.class), nullable(Index.class))).thenReturn(STATEMENTS); - when(idTable.getName()).thenReturn(ID_TABLE_NAME); + when(idTable.getName()).thenReturn(idTableName); when(idTable.ignoredIndexes()).thenReturn(Collections.emptyList()); - when(schemaResource.getTable(ID_TABLE_NAME)).thenReturn(idTable); + when(schemaResource.getTable(idTableName)).thenReturn(idTable); // when visitor.visit(addIndex); @@ -144,47 +144,47 @@ public void testVisitAddIndexWithPRFIndex() { // given visitor.startStep(U1.class); - String ID_TABLE_NAME = "IdTableName"; + String idTableName = "IdTableName"; Index newIndex = mock(Index.class); - when(newIndex.getName()).thenReturn(ID_TABLE_NAME + "_1"); + when(newIndex.getName()).thenReturn(idTableName + "_1"); when(newIndex.columnNames()).thenReturn(Collections.singletonList("column_1")); AddIndex addIndex = mock(AddIndex.class); given(addIndex.apply(sourceSchema)).willReturn(sourceSchema); - when(addIndex.getTableName()).thenReturn(ID_TABLE_NAME); + when(addIndex.getTableName()).thenReturn(idTableName); when(addIndex.getNewIndex()).thenReturn(newIndex); Index indexPrf = mock(Index.class); - when(indexPrf.getName()).thenReturn(ID_TABLE_NAME + "_PRF1"); + when(indexPrf.getName()).thenReturn(idTableName + "_PRF1"); when(indexPrf.columnNames()).thenReturn(List.of("column_1")); Index indexPrf1 = mock(Index.class); - when(indexPrf1.getName()).thenReturn(ID_TABLE_NAME + "_PRF2"); + when(indexPrf1.getName()).thenReturn(idTableName + "_PRF2"); when(indexPrf1.columnNames()).thenReturn(List.of("column_2")); Table newTable = mock(Table.class); - when(newTable.getName()).thenReturn(ID_TABLE_NAME); + when(newTable.getName()).thenReturn(idTableName); when(newTable.ignoredIndexes()).thenReturn(Lists.newArrayList(indexPrf, indexPrf1)); - when(schemaResource.getTable(ID_TABLE_NAME)).thenReturn(newTable); + when(schemaResource.getTable(idTableName)).thenReturn(newTable); - when(sqlDialect.renameIndexStatements(nullable(Table.class), eq(ID_TABLE_NAME + "_PRF1"), eq(ID_TABLE_NAME + "_1"))).thenReturn(STATEMENTS); - when(sqlDialect.renameIndexStatements(nullable(Table.class), eq(ID_TABLE_NAME + "_PRF2"), eq(ID_TABLE_NAME + "_2"))).thenReturn(STATEMENTS); + when(sqlDialect.renameIndexStatements(nullable(Table.class), eq(idTableName + "_PRF1"), eq(idTableName + "_1"))).thenReturn(STATEMENTS); + when(sqlDialect.renameIndexStatements(nullable(Table.class), eq(idTableName + "_PRF2"), eq(idTableName + "_2"))).thenReturn(STATEMENTS); when(sqlDialect.addIndexStatements(nullable(Table.class), nullable(Index.class))).thenReturn(STATEMENTS); Index newIndex1 = mock(Index.class); - when(newIndex1.getName()).thenReturn(ID_TABLE_NAME + "_2"); + when(newIndex1.getName()).thenReturn(idTableName + "_2"); when(newIndex1.columnNames()).thenReturn(Collections.singletonList("column_2")); AddIndex addIndex1 = mock(AddIndex.class); given(addIndex1.apply(sourceSchema)).willReturn(sourceSchema); - when(addIndex1.getTableName()).thenReturn(ID_TABLE_NAME); + when(addIndex1.getTableName()).thenReturn(idTableName); when(addIndex1.getNewIndex()).thenReturn(newIndex1); Index newIndex2 = mock(Index.class); - when(newIndex2.getName()).thenReturn(ID_TABLE_NAME + "_3"); + when(newIndex2.getName()).thenReturn(idTableName + "_3"); when(newIndex2.columnNames()).thenReturn(Collections.singletonList("column_3")); AddIndex addIndex2 = mock(AddIndex.class); given(addIndex2.apply(sourceSchema)).willReturn(sourceSchema); - when(addIndex2.getTableName()).thenReturn(ID_TABLE_NAME); + when(addIndex2.getTableName()).thenReturn(idTableName); when(addIndex2.getNewIndex()).thenReturn(newIndex2); // when @@ -194,8 +194,8 @@ public void testVisitAddIndexWithPRFIndex() { // then verify(addIndex).apply(sourceSchema); - verify(sqlDialect).renameIndexStatements(nullable(Table.class), eq(ID_TABLE_NAME + "_PRF1"), eq(ID_TABLE_NAME + "_1")); - verify(sqlDialect).renameIndexStatements(nullable(Table.class), eq(ID_TABLE_NAME + "_PRF2"), eq(ID_TABLE_NAME + "_2")); + verify(sqlDialect).renameIndexStatements(nullable(Table.class), eq(idTableName + "_PRF1"), eq(idTableName + "_1")); + verify(sqlDialect).renameIndexStatements(nullable(Table.class), eq(idTableName + "_PRF2"), eq(idTableName + "_2")); verify(sqlDialect).addIndexStatements(nullable(Table.class), nullable(Index.class)); verify(n1, times(3)).addAllUpgradeStatements(ArgumentMatchers.argThat(c-> c.containsAll(STATEMENTS))); } diff --git a/morf-integration-test/src/test/java/org/alfasoftware/morf/jdbc/TestDatabaseMetaDataProvider.java b/morf-integration-test/src/test/java/org/alfasoftware/morf/jdbc/TestDatabaseMetaDataProvider.java index 6b7a803f8..816c2ad8c 100755 --- a/morf-integration-test/src/test/java/org/alfasoftware/morf/jdbc/TestDatabaseMetaDataProvider.java +++ b/morf-integration-test/src/test/java/org/alfasoftware/morf/jdbc/TestDatabaseMetaDataProvider.java @@ -25,6 +25,7 @@ import static org.alfasoftware.morf.sql.SqlUtils.field; import static org.alfasoftware.morf.sql.SqlUtils.select; import static org.alfasoftware.morf.sql.SqlUtils.tableRef; +import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.contains; import static org.hamcrest.Matchers.containsInAnyOrder; import static org.hamcrest.Matchers.either; @@ -33,7 +34,6 @@ import static org.hamcrest.Matchers.equalToIgnoringCase; import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertThat; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; From 1b425cbd990c9fc3d5cdaf8e73bbda98f038b1a2 Mon Sep 17 00:00:00 2001 From: Bruno Monteiro Date: Fri, 9 May 2025 09:32:55 +0100 Subject: [PATCH 09/11] Add try with resources for SchemaResource to GraphBasedUpgradeBuilder and Upgrade. --- .../upgrade/GraphBasedUpgradeBuilder.java | 26 +++++++++++-------- .../alfasoftware/morf/upgrade/Upgrade.java | 20 +++++++------- 2 files changed, 26 insertions(+), 20 deletions(-) diff --git a/morf-core/src/main/java/org/alfasoftware/morf/upgrade/GraphBasedUpgradeBuilder.java b/morf-core/src/main/java/org/alfasoftware/morf/upgrade/GraphBasedUpgradeBuilder.java index d4bfe6b2d..d6905da54 100644 --- a/morf-core/src/main/java/org/alfasoftware/morf/upgrade/GraphBasedUpgradeBuilder.java +++ b/morf-core/src/main/java/org/alfasoftware/morf/upgrade/GraphBasedUpgradeBuilder.java @@ -12,6 +12,7 @@ import org.alfasoftware.morf.jdbc.ConnectionResources; import org.alfasoftware.morf.jdbc.SqlDialect; import org.alfasoftware.morf.metadata.Schema; +import org.alfasoftware.morf.metadata.SchemaResource; import org.alfasoftware.morf.metadata.Table; import org.alfasoftware.morf.upgrade.GraphBasedUpgradeSchemaChangeVisitor.GraphBasedUpgradeSchemaChangeVisitorFactory; import org.alfasoftware.morf.upgrade.GraphBasedUpgradeScriptGenerator.GraphBasedUpgradeScriptGeneratorFactory; @@ -97,21 +98,24 @@ public GraphBasedUpgrade prepareGraphBasedUpgrade(List initialisationSql GraphBasedUpgradeNode root = prepareGraph(nodes); + List preUpgStatements = new ArrayList<>(); + List postUpgStatements = new ArrayList<>(); Table idTable = SqlDialect.IdTable.withPrefix(connectionResources.sqlDialect(), "temp_id_", false); + try (SchemaResource schemaResource = connectionResources.openSchemaResource()) { + GraphBasedUpgradeSchemaChangeVisitor visitor = visitorFactory.create( + sourceSchema, + connectionResources.openSchemaResource(), + connectionResources.sqlDialect(), + idTable, + nodes.stream().collect(Collectors.toMap(GraphBasedUpgradeNode::getName, Function.identity()))); - GraphBasedUpgradeSchemaChangeVisitor visitor = visitorFactory.create( - sourceSchema, - connectionResources.openSchemaResource(), - connectionResources.sqlDialect(), - idTable, - nodes.stream().collect(Collectors.toMap(GraphBasedUpgradeNode::getName, Function.identity()))); - - GraphBasedUpgradeScriptGenerator scriptGenerator = scriptGeneratorFactory.create(sourceSchema, targetSchema, connectionResources, idTable, viewChanges, initialisationSql); + GraphBasedUpgradeScriptGenerator scriptGenerator = scriptGeneratorFactory.create(sourceSchema, targetSchema, connectionResources, idTable, viewChanges, initialisationSql); - List preUpgStatements = scriptGenerator.generatePreUpgradeStatements(); - schemaChangeSequence.applyTo(visitor); - List postUpgStatements = scriptGenerator.generatePostUpgradeStatements(); + preUpgStatements = scriptGenerator.generatePreUpgradeStatements(); + schemaChangeSequence.applyTo(visitor); + postUpgStatements = scriptGenerator.generatePostUpgradeStatements(); + } if (LOG.isDebugEnabled()) { logGraph(root); } diff --git a/morf-core/src/main/java/org/alfasoftware/morf/upgrade/Upgrade.java b/morf-core/src/main/java/org/alfasoftware/morf/upgrade/Upgrade.java index d7dd6d286..972ceefcc 100755 --- a/morf-core/src/main/java/org/alfasoftware/morf/upgrade/Upgrade.java +++ b/morf-core/src/main/java/org/alfasoftware/morf/upgrade/Upgrade.java @@ -249,15 +249,17 @@ else if (upgradeAuditCount != getUpgradeAuditRowCount(upgradeAuditRowProcessor)) // if (!schemaChangeSequence.getUpgradeSteps().isEmpty()) { // Run the upgrader over all the ElementarySchemaChanges in the upgrade steps - InlineTableUpgrader upgrader = new InlineTableUpgrader(sourceSchema, connectionResources.openSchemaResource(), dialect, new SqlStatementWriter() { - @Override - public void writeSql(Collection sql) { - upgradeStatements.addAll(sql); - } - }, SqlDialect.IdTable.withPrefix(dialect, "temp_id_")); - upgrader.preUpgrade(); - schemaChangeSequence.applyTo(upgrader); - upgrader.postUpgrade(); + try (SchemaResource schemaResource = connectionResources.openSchemaResource()) { + InlineTableUpgrader upgrader = new InlineTableUpgrader(sourceSchema, schemaResource, dialect, new SqlStatementWriter() { + @Override + public void writeSql(Collection sql) { + upgradeStatements.addAll(sql); + } + }, SqlDialect.IdTable.withPrefix(dialect, "temp_id_")); + upgrader.preUpgrade(); + schemaChangeSequence.applyTo(upgrader); + upgrader.postUpgrade(); + } } // -- Upgrade path... From fdfd5a45b9a8eb03fba71fd9faa8d5c6e8a0871e Mon Sep 17 00:00:00 2001 From: Bruno Monteiro Date: Fri, 9 May 2025 09:53:04 +0100 Subject: [PATCH 10/11] Fix Upgrade try with resources for SchemaResource. openSchemaResource must be called with dataSource argument. --- .../src/main/java/org/alfasoftware/morf/upgrade/Upgrade.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/morf-core/src/main/java/org/alfasoftware/morf/upgrade/Upgrade.java b/morf-core/src/main/java/org/alfasoftware/morf/upgrade/Upgrade.java index 972ceefcc..209f8d8cc 100755 --- a/morf-core/src/main/java/org/alfasoftware/morf/upgrade/Upgrade.java +++ b/morf-core/src/main/java/org/alfasoftware/morf/upgrade/Upgrade.java @@ -249,7 +249,7 @@ else if (upgradeAuditCount != getUpgradeAuditRowCount(upgradeAuditRowProcessor)) // if (!schemaChangeSequence.getUpgradeSteps().isEmpty()) { // Run the upgrader over all the ElementarySchemaChanges in the upgrade steps - try (SchemaResource schemaResource = connectionResources.openSchemaResource()) { + try (SchemaResource schemaResource = connectionResources.openSchemaResource(dataSource)) { InlineTableUpgrader upgrader = new InlineTableUpgrader(sourceSchema, schemaResource, dialect, new SqlStatementWriter() { @Override public void writeSql(Collection sql) { From d1f434c2b5c57c81e1e2be7f4312c32e7c3ad95e Mon Sep 17 00:00:00 2001 From: Bruno Monteiro Date: Fri, 9 May 2025 10:07:37 +0100 Subject: [PATCH 11/11] Fix dead store. --- .../alfasoftware/morf/upgrade/GraphBasedUpgradeBuilder.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/morf-core/src/main/java/org/alfasoftware/morf/upgrade/GraphBasedUpgradeBuilder.java b/morf-core/src/main/java/org/alfasoftware/morf/upgrade/GraphBasedUpgradeBuilder.java index d6905da54..af467750f 100644 --- a/morf-core/src/main/java/org/alfasoftware/morf/upgrade/GraphBasedUpgradeBuilder.java +++ b/morf-core/src/main/java/org/alfasoftware/morf/upgrade/GraphBasedUpgradeBuilder.java @@ -98,13 +98,13 @@ public GraphBasedUpgrade prepareGraphBasedUpgrade(List initialisationSql GraphBasedUpgradeNode root = prepareGraph(nodes); - List preUpgStatements = new ArrayList<>(); - List postUpgStatements = new ArrayList<>(); + List preUpgStatements; + List postUpgStatements; Table idTable = SqlDialect.IdTable.withPrefix(connectionResources.sqlDialect(), "temp_id_", false); try (SchemaResource schemaResource = connectionResources.openSchemaResource()) { GraphBasedUpgradeSchemaChangeVisitor visitor = visitorFactory.create( sourceSchema, - connectionResources.openSchemaResource(), + schemaResource, connectionResources.sqlDialect(), idTable, nodes.stream().collect(Collectors.toMap(GraphBasedUpgradeNode::getName, Function.identity())));