Skip to content

Gocql doesn't parse Cassandra version correctly #910

@szhou1234

Description

@szhou1234

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);
    }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions