com.avaje.ebean.dbmigration.model.MigrationVersion Maven / Gradle / Ivy
package com.avaje.ebean.dbmigration.model;
import java.util.Arrays;
/**
* The version of a migration used so that migrations are processed in order.
*/
public class MigrationVersion implements Comparable {
private static final int[] REPEAT_ORDERING = {Integer.MAX_VALUE};
private static final boolean[] REPEAT_UNDERSCORES = {false};
/**
* The raw version text.
*/
private final String raw;
/**
* The ordering parts.
*/
private final int[] ordering;
private final boolean[] underscores;
private final String comment;
/**
* Construct for "repeatable" version.
*/
private MigrationVersion(String raw, String comment) {
this.raw = raw;
this.comment = comment;
this.ordering = REPEAT_ORDERING;
this.underscores = REPEAT_UNDERSCORES;
}
/**
* Construct for "normal" version.
*/
private MigrationVersion(String raw, int[] ordering, boolean[] underscores, String comment) {
this.raw = raw;
this.ordering = ordering;
this.underscores = underscores;
this.comment = comment;
}
/**
* Return true if this is a "repeatable" version.
*/
public boolean isRepeatable() {
return ordering == REPEAT_ORDERING;
}
/**
* Return the full version.
*/
public String getFull() {
return raw;
}
public String toString() {
return raw;
}
/**
* Return the version comment.
*/
public String getComment() {
return comment;
}
/**
* Return the version in raw form.
*/
public String getRaw() {
return raw;
}
/**
* Return the trimmed version excluding version comment and un-parsable string.
*/
public String asString() {
return formattedVersion(false, false);
}
/**
* Return the trimmed version with any underscores replaced with '.'
*/
public String normalised() {
return formattedVersion(true, false);
}
/**
* Return the next version based on this version.
*/
public String nextVersion() {
return formattedVersion(false, true);
}
/**
* Returns the version part of the string.
*
* Normalised means always use '.' delimiters (no underscores).
* NextVersion means bump/increase the last version number by 1.
*/
private String formattedVersion(boolean normalised, boolean nextVersion) {
if (ordering == REPEAT_ORDERING) {
return "R";
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < ordering.length; i++) {
if (i < ordering.length - 1) {
sb.append(ordering[i]);
if (normalised) {
sb.append('.');
} else {
sb.append(underscores[i] ? '_' : '.');
}
} else {
sb.append((nextVersion) ? ordering[i] + 1 : ordering[i]);
}
}
return sb.toString();
}
@Override
public int compareTo(MigrationVersion other) {
int otherLength = other.ordering.length;
for (int i = 0; i < ordering.length; i++) {
if (i >= otherLength) {
// considered greater
return 1;
}
if (ordering[i] != other.ordering[i]) {
return (ordering[i] > other.ordering[i]) ? 1 : -1;
}
}
return comment.compareTo(other.comment);
}
/**
* Parse the raw version string and just return the leading version number;
*/
public static String trim(String raw) {
return parse(raw).asString();
}
/**
* Parse the raw version string into a MigrationVersion.
*/
public static MigrationVersion parse(String raw) {
if (raw.startsWith("V") || raw.startsWith("v")) {
raw = raw.substring(1);
}
String comment = "";
String value = raw;
int commentStart = raw.indexOf("__");
if (commentStart > -1) {
// trim off the trailing comment
comment = raw.substring(commentStart + 2);
value = value.substring(0, commentStart);
}
value = value.replace('_', '.');
String[] sections = value.split("[\\.-]");
if ("r".equalsIgnoreCase(sections[0])) {
// a "repeatable" version (does not have a version number)
return new MigrationVersion(raw, comment);
}
boolean[] underscores = new boolean[sections.length];
int[] ordering = new int[sections.length];
int delimiterPos = 0;
int stopIndex = 0;
for (int i = 0; i < sections.length; i++) {
try {
ordering[i] = Integer.parseInt(sections[i]);
stopIndex++;
delimiterPos += sections[i].length();
underscores[i] = (delimiterPos < raw.length() - 1 && raw.charAt(delimiterPos) == '_');
delimiterPos++;
} catch (NumberFormatException e) {
// stop parsing
break;
}
}
int[] actualOrder = Arrays.copyOf(ordering, stopIndex);
boolean[] actualUnderscores = Arrays.copyOf(underscores, stopIndex);
return new MigrationVersion(raw, actualOrder, actualUnderscores, comment);
}
}