First post on these forums. I’m trying to understand the checksum calculated by Liquibase. The MD5SUM value in the DATABASECHANGELOG table clearly seems to consist of two parts:
n:hash
Where the prefix n is a number or possible a hex nibble, : must be a separator and then the actual checksum hash.
I have studied the source for Liquibase and I’ve hit a force field with CommandBuilder which I haven’t been able to break down and fully grock it’s inner mechanics. I might add that I’m not a Java developer which make things a bit challening to say the least.
When I calculate a MD5 checksum based on input in the format below as a single string it computes to something else so apparently it is not the whole truth:
filepath::id::author
Does anyone have knowledge about how this actually works and can give me any pointers in the right direction? Any idea what that prefix is?
I can’t really tell you how the md5sum is calculated, but the initial digit appears to the “checksum algorithm version” number. See here for more details:
The combination of filepath:id:author is what is required to make a unique changset in the databasechangelog table. The md5sum represents the “checksum” for the actual code in the changeset.
I’m probably not explaining this exactly correct, but maybe some of what I provided will help you.
I believe I might be on a slightly older version of liquibase so that makes sense. Mine says 8.
I’d be surprised if there is an excessive amount of voodoo going on in the actual md5 calculation. I tried a few simple variants of input but nothing turned out right. So, instead of finding out by doing crazy amounts of trial and error tests I started looking at the code.
Further investigation led me to
StandardChangeLogHistoryService.java:
if (!md5sumRS.isEmpty()) {
String md5sum = md5sumRS.get(0).get("MD5SUM").toString();
if (!md5sum.startsWith(CheckSum.getCurrentVersion() + ":")) {
executor.comment("DatabaseChangeLog checksums are an incompatible version. Setting them to null " +
"so they will be updated on next database update");
databaseChecksumsCompatible = false;
UpdateStatement updateStatement = new UpdateStatement(database.getLiquibaseCatalogName(),
database.getLiquibaseSchemaName(), database.getDatabaseChangeLogTableName())
.addNewColumnValue("MD5SUM", null);
statementsToExecute.add(updateStatement);
}
}
I’d say that confirms your find Daryl.
Is there a way to find all the methods for the CheckSum object? I figure there could be a method for generating the CurrentVersion as well and that might provide some more insights if I can find where it is being called.