Skip to content

Commit

Permalink
Support early checksum calculation with auto patching old checksums
Browse files Browse the repository at this point in the history
  • Loading branch information
rbygrave committed Oct 31, 2023
1 parent 73a1c08 commit 95e24bc
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,8 @@ public class MigrationConfig {
private String basePlatform;
private String platform;
private Properties properties;

private boolean earlyChecksumMode;
private boolean autoPatchChecksum = true;
/**
* Return the name of the migration table.
*/
Expand Down Expand Up @@ -469,6 +470,8 @@ public void load(Properties props) {
dbSchema = getProperty("schema", dbSchema);
skipMigrationRun = getBool("skipMigrationRun", skipMigrationRun);
skipChecksum = getBool("skipChecksum", skipChecksum);
earlyChecksumMode = getBool("earlyChecksum", earlyChecksumMode);
autoPatchChecksum = getBool("autoPatchChecksum", autoPatchChecksum);
createSchemaIfNotExists = getBool("createSchemaIfNotExists", createSchemaIfNotExists);
setCurrentSchema = getBool("setCurrentSchema", setCurrentSchema);
basePlatform = getProperty("basePlatform", basePlatform);
Expand Down Expand Up @@ -575,6 +578,36 @@ public void setPlatform(String platform) {
this.platform = platform;
}

/**
* Return true if changing to use earlyChecksumMode, and we want to automatically
* patch checksums that were computed on the original mode.
*/
public boolean isAutoPatchChecksum() {
return autoPatchChecksum;
}

/**
* Set this to false in order to turn off auto patching for earlyChecksumMode.
*/
public void setAutoPatchChecksum(boolean autoPatchChecksum) {
this.autoPatchChecksum = autoPatchChecksum;
}

/**
* Return true if using the earlyChecksumMode which means checksums are computed
* before any expressions in the scripts are translated.
*/
public boolean isEarlyChecksumMode() {
return earlyChecksumMode;
}

/**
* Set to true to turn on earlyChecksumMode.
*/
public void setEarlyChecksumMode(boolean earlyChecksumMode) {
this.earlyChecksumMode = earlyChecksumMode;
}

/**
* Default factory. Uses the migration's class loader and injects the config if necessary.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ final class MigrationTable {

private final Connection connection;
private final boolean checkStateOnly;
private final boolean autoPatchChecksum;
private final boolean useEarlyChecksum;
private final MigrationPlatform platform;
private final MigrationScriptRunner scriptRunner;
private final String catalog;
Expand Down Expand Up @@ -74,6 +76,8 @@ final class MigrationTable {
this.connection = connection;
this.scriptRunner = new MigrationScriptRunner(connection, platform);
this.checkStateOnly = checkStateOnly;
this.useEarlyChecksum = config.isEarlyChecksumMode();
this.autoPatchChecksum = !checkStateOnly && config.isAutoPatchChecksum();
this.migrations = new LinkedHashMap<>();
this.catalog = null;
this.allowErrorInRepeatable = config.isAllowErrorInRepeatable();
Expand Down Expand Up @@ -296,20 +300,24 @@ private boolean shouldRun(LocalMigrationResource localVersion, LocalMigrationRes
private boolean runMigration(LocalMigrationResource local, MigrationMetaRow existing) throws SQLException {
String script = null;
int checksum;
int checksum2 = 0;
if (local instanceof LocalUriMigrationResource) {
script = convertScript(local.content());
checksum = ((LocalUriMigrationResource)local).checksum();
} else if (local instanceof LocalDdlMigrationResource) {
script = convertScript(local.content());
checksum = Checksum.calculate(script);
} else if (local instanceof LocalDdlMigrationResource) {
final String content = local.content();
script = convertScript(content);
// checksum on original content (NEW) or converted script content (LEGACY)
checksum = Checksum.calculate(useEarlyChecksum ? content : script);
checksum2 = autoPatchChecksum ? Checksum.calculate(script) : 0;
} else {
checksum = ((LocalJdbcMigrationResource) local).checksum();
}

if (existing == null && patchInsertMigration(local, checksum)) {
return true;
}
if (existing != null && skipMigration(checksum, local, existing)) {
if (existing != null && skipMigration(checksum, checksum2, local, existing)) {
return true;
}
executeMigration(local, script, checksum, existing);
Expand All @@ -333,12 +341,17 @@ private boolean patchInsertMigration(LocalMigrationResource local, int checksum)
/**
* Return true if the migration should be skipped.
*/
boolean skipMigration(int checksum, LocalMigrationResource local, MigrationMetaRow existing) throws SQLException {
boolean skipMigration(int checksum, int checksum2, LocalMigrationResource local, MigrationMetaRow existing) throws SQLException {
boolean matchChecksum = (existing.checksum() == checksum);
if (matchChecksum) {
log.log(TRACE, "skip unchanged migration {0}", local.location());
return true;

} else if (autoPatchChecksum && existing.checksum() == checksum2) {
log.log(INFO, "Patch migration, reset checksum on {0}", local.location());
existing.resetChecksum(checksum, connection, updateChecksumSql);
return true;

} else if (patchResetChecksum(existing, checksum)) {
log.log(INFO, "Patch migration, reset checksum on {0}", local.location());
return true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,16 +48,17 @@ void test_skipMigration_Repeatable() throws Exception {

MigrationTable mt = new MigrationTable(config, null, false, new MigrationPlatform());
// checksum different - no skip
assertFalse(mt.skipMigration(100, local, existing));
assertFalse(mt.skipMigration(100, 100, local, existing));
// checksum same - skip
assertTrue(mt.skipMigration(42, local, existing));
assertTrue(mt.skipMigration(42, 42, local, existing));
}

@Test
void test_skipMigration_skipChecksum() throws Exception {

MigrationConfig config = new MigrationConfig();
config.setSkipChecksum(true);
config.setAutoPatchChecksum(true);

MigrationTable mt = new MigrationTable(config, null, false, new MigrationPlatform());

Expand All @@ -66,19 +67,20 @@ void test_skipMigration_skipChecksum() throws Exception {
MigrationMetaRow existing = new MigrationMetaRow(12, "R", "", "comment", 42, null, null, 0);

// repeatable checksum mismatch
assertFalse(mt.skipMigration(44, local, existing));
assertFalse(mt.skipMigration(44, 44, local, existing));

// repeatable match checksum
assertTrue(mt.skipMigration(42, local, existing));
assertTrue(mt.skipMigration(42, 42, local, existing));
// assertTrue(mt.skipMigration(99, 42, local, existing));

LocalMigrationResource localVer = local("V1__hello");
MigrationMetaRow localExisting = new MigrationMetaRow(12, "V", "1", "comment", 42, null, null, 0);

// re-run on checksum mismatch and skipChecksum
assertFalse(mt.skipMigration(44, localVer, localExisting));
assertFalse(mt.skipMigration(44, 44, localVer, localExisting));

// match checksum so skip
assertTrue(mt.skipMigration(42, localVer, localExisting));
assertTrue(mt.skipMigration(42, 42, localVer, localExisting));
}

private LocalMigrationResource local(String raw) {
Expand Down

0 comments on commit 95e24bc

Please sign in to comment.