-
Notifications
You must be signed in to change notification settings - Fork 642
Closed
Labels
Description
Currently Gocql only splits version string with "." in host_source.unmarshal(). However there are cases you want to use "3.0.10-xxx" as version number. In this case, Gocql will just panic. We should match the behavior with Java driver, which uses the below code for parsing version (from VersionNumber.java):
private static final String VERSION_REGEXP = "(\d+)\.(\d+)(\.\d+)?(\.\d+)?([~\-]\w[.\w](?:\-\w[.\w])*)?(\+[.\w]+)?";
/**
* Parse a version from a string.
* <p/>
* The version string should have primarily the form X.Y.Z to which can be appended
* one or more pre-release label after dashes (2.0.1-beta1, 2.1.4-rc1-SNAPSHOT)
* and an optional build label (2.1.0-beta1+a20ba.sha). Out of convenience, the
* "patch" version number, Z, can be omitted, in which case it is assumed to be 0.
*
* @param version the string to parse
* @return the parsed version number.
* @throws IllegalArgumentException if the provided string does not
* represent a valid version.
*/
public static VersionNumber parse(String version) {
if (version == null)
return null;
Matcher matcher = pattern.matcher(version);
if (!matcher.matches())
throw new IllegalArgumentException("Invalid version number: " + version);
try {
int major = Integer.parseInt(matcher.group(1));
int minor = Integer.parseInt(matcher.group(2));
String pa = matcher.group(3);
int patch = pa == null || pa.isEmpty() ? 0 : Integer.parseInt(pa.substring(1)); // dropping the initial '.' since it's included this time
String dse = matcher.group(4);
int dsePatch = dse == null || dse.isEmpty() ? -1 : Integer.parseInt(dse.substring(1)); // dropping the initial '.' since it's included this time
String pr = matcher.group(5);
String[] preReleases = pr == null || pr.isEmpty() ? null : pr.substring(1).split("\\-"); // drop initial '-' or '~' then split on the remaining ones
String bl = matcher.group(6);
String build = bl == null || bl.isEmpty() ? null : bl.substring(1); // drop the initial '+'
return new VersionNumber(major, minor, patch, dsePatch, preReleases, build);
} catch (NumberFormatException e) {
throw new IllegalArgumentException("Invalid version number: " + version);
}
}