[NO ISSUE] Support driver/database version check Details: - Introduce 2 new driver properties: 'minDriverVersion' and 'minDatabaseVersion' that allow user to enforce minimal driver and database versions - Remove driver property handling from ADBDriverContext Change-Id: Icdca92fbc7a394aa91bfde14cae8f9e726cd51d5 Reviewed-on: https://asterix-gerrit.ics.uci.edu/c/asterixdb-clients/+/13863 Tested-by: Jenkins <jenkins@fulliautomatix.ics.uci.edu> Reviewed-by: Dmitry Lychagin <dmitry.lychagin@couchbase.com> Reviewed-by: Ian Maxon <imaxon@uci.edu>
diff --git a/asterixdb-jdbc/asterix-jdbc-core/src/main/java/org/apache/asterix/jdbc/core/ADBConnection.java b/asterixdb-jdbc/asterix-jdbc-core/src/main/java/org/apache/asterix/jdbc/core/ADBConnection.java index 23b98af..2a068f1 100644 --- a/asterixdb-jdbc/asterix-jdbc-core/src/main/java/org/apache/asterix/jdbc/core/ADBConnection.java +++ b/asterixdb-jdbc/asterix-jdbc-core/src/main/java/org/apache/asterix/jdbc/core/ADBConnection.java
@@ -50,7 +50,7 @@ protected final ADBProtocolBase protocol; protected final String url; - protected final String databaseVersion; + protected final ADBProductVersion databaseVersion; protected final ADBDriverProperty.CatalogDataverseMode catalogDataverseMode; protected final boolean catalogIncludesSchemaless; protected final boolean sqlCompatMode; @@ -63,8 +63,9 @@ // Lifecycle - public ADBConnection(ADBProtocolBase protocol, String url, String databaseVersion, String dataverseCanonicalName, - Map<ADBDriverProperty, Object> properties, SQLWarning connectWarning) throws SQLException { + public ADBConnection(ADBProtocolBase protocol, String url, ADBProductVersion databaseVersion, + String dataverseCanonicalName, Map<ADBDriverProperty, Object> properties, SQLWarning connectWarning) + throws SQLException { this.url = Objects.requireNonNull(url); this.protocol = Objects.requireNonNull(protocol); this.databaseVersion = databaseVersion;
diff --git a/asterixdb-jdbc/asterix-jdbc-core/src/main/java/org/apache/asterix/jdbc/core/ADBDatabaseMetaData.java b/asterixdb-jdbc/asterix-jdbc-core/src/main/java/org/apache/asterix/jdbc/core/ADBDatabaseMetaData.java index 81e42eb..7068182 100644 --- a/asterixdb-jdbc/asterix-jdbc-core/src/main/java/org/apache/asterix/jdbc/core/ADBDatabaseMetaData.java +++ b/asterixdb-jdbc/asterix-jdbc-core/src/main/java/org/apache/asterix/jdbc/core/ADBDatabaseMetaData.java
@@ -35,35 +35,36 @@ protected final ADBMetaStatement metaStatement; - protected final String databaseVersionText; + protected final ADBProductVersion driverVersion; - private volatile ADBProductVersion databaseVersion; + protected final ADBProductVersion databaseVersion; - public ADBDatabaseMetaData(ADBMetaStatement metaStatement, String databaseVersionText) { + public ADBDatabaseMetaData(ADBMetaStatement metaStatement, ADBProductVersion databaseVersion) { this.metaStatement = Objects.requireNonNull(metaStatement); - this.databaseVersionText = databaseVersionText; + this.driverVersion = metaStatement.connection.protocol.getDriverContext().getDriverVersion(); + this.databaseVersion = databaseVersion; } // Driver name and version @Override public String getDriverName() { - return metaStatement.connection.protocol.getDriverContext().getDriverVersion().getProductName(); + return driverVersion.getProductName(); } @Override public String getDriverVersion() { - return metaStatement.connection.protocol.getDriverContext().getDriverVersion().getProductVersion(); + return driverVersion.getProductVersion(); } @Override public int getDriverMajorVersion() { - return metaStatement.connection.protocol.getDriverContext().getDriverVersion().getMajorVersion(); + return driverVersion.getMajorVersion(); } @Override public int getDriverMinorVersion() { - return metaStatement.connection.protocol.getDriverContext().getDriverVersion().getMinorVersion(); + return driverVersion.getMinorVersion(); } @Override @@ -80,30 +81,22 @@ @Override public String getDatabaseProductName() { - return getDatabaseVersion().getProductName(); + return databaseVersion.getProductName(); } @Override public String getDatabaseProductVersion() { - return getDatabaseVersion().getProductVersion(); + return databaseVersion.getProductVersion(); } @Override public int getDatabaseMajorVersion() { - return getDatabaseVersion().getMajorVersion(); + return databaseVersion.getMajorVersion(); } @Override public int getDatabaseMinorVersion() { - return getDatabaseVersion().getMinorVersion(); - } - - protected ADBProductVersion getDatabaseVersion() { - ADBProductVersion result = databaseVersion; - if (result == null) { - databaseVersion = result = ADBProductVersion.parseDatabaseVersion(databaseVersionText); - } - return result; + return databaseVersion.getMinorVersion(); } // Database objects
diff --git a/asterixdb-jdbc/asterix-jdbc-core/src/main/java/org/apache/asterix/jdbc/core/ADBDriverBase.java b/asterixdb-jdbc/asterix-jdbc-core/src/main/java/org/apache/asterix/jdbc/core/ADBDriverBase.java index 613c3a9..63dc5a8 100644 --- a/asterixdb-jdbc/asterix-jdbc-core/src/main/java/org/apache/asterix/jdbc/core/ADBDriverBase.java +++ b/asterixdb-jdbc/asterix-jdbc-core/src/main/java/org/apache/asterix/jdbc/core/ADBDriverBase.java
@@ -29,8 +29,10 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; +import java.util.Collections; import java.util.Enumeration; import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Objects; @@ -53,11 +55,18 @@ protected final int defaultApiPort; + protected final ADBErrorReporter errorReporter; + + private volatile ADBProductVersion driverVersion; + + private volatile Map<String, ADBDriverProperty> supportedPropertiesIndex; + private volatile ADBDriverContext context; public ADBDriverBase(String driverScheme, int defaultApiPort) { this.urlScheme = JDBC_SCHEME + Objects.requireNonNull(driverScheme); this.defaultApiPort = defaultApiPort; + this.errorReporter = createErrorReporter(); } protected static void registerDriver(java.sql.Driver driver) { @@ -68,23 +77,23 @@ } } - protected static void parseConnectionProperties(Properties inProps, ADBDriverContext driverContext, - Map<ADBDriverProperty, Object> outProperties, SQLWarning outWarning) throws SQLException { + protected void parseConnectionProperties(Properties inProps, Map<ADBDriverProperty, Object> outProperties, + Map<String, ADBDriverProperty> supportedProperties, SQLWarning outWarning) throws SQLException { if (inProps != null) { for (Enumeration<?> en = inProps.propertyNames(); en.hasMoreElements();) { String name = en.nextElement().toString(); String value = inProps.getProperty(name); - parseConnectionProperty(name, value, driverContext, outProperties, outWarning); + parseConnectionProperty(name, value, supportedProperties, outProperties, outWarning); } } } - protected static void parseConnectionProperty(String name, String textValue, ADBDriverContext driverContext, - Map<ADBDriverProperty, Object> outProperties, SQLWarning outWarning) throws SQLException { - ADBDriverProperty property = driverContext.getSupportedProperties().get(name); + protected void parseConnectionProperty(String name, String textValue, + Map<String, ADBDriverProperty> supportedProperties, Map<ADBDriverProperty, Object> outProperties, + SQLWarning outWarning) throws SQLException { + ADBDriverProperty property = supportedProperties.get(name); if (property == null) { - outWarning.setNextWarning( - new SQLWarning(driverContext.getErrorReporter().warningParameterNotSupported(name))); + outWarning.setNextWarning(new SQLWarning(errorReporter.warningParameterNotSupported(name))); return; } if (textValue == null || textValue.isEmpty()) { @@ -94,7 +103,7 @@ try { value = Objects.requireNonNull(property.getValueParser().apply(textValue)); } catch (RuntimeException e) { - throw driverContext.getErrorReporter().errorParameterValueNotSupported(name); + throw errorReporter.errorParameterValueNotSupported(name); } outProperties.put(property, value); } @@ -135,34 +144,34 @@ try { subUri = new URI(url.substring(JDBC_SCHEME.length())); } catch (URISyntaxException e) { - throw createErrorReporter().errorParameterValueNotSupported("URL"); + throw errorReporter.errorParameterValueNotSupported("URL"); } String host = subUri.getHost(); if (host == null) { - throw createErrorReporter().errorParameterValueNotSupported("URL"); + throw errorReporter.errorParameterValueNotSupported("URL"); } int port = subUri.getPort(); if (port <= 0) { port = defaultApiPort; } - Properties uriParams = getURIParameters(subUri); - - ADBDriverContext driverContext = getOrCreateDriverContext(); - SQLWarning warning = new SQLWarning(); Map<ADBDriverProperty, Object> properties = new HashMap<>(); - parseConnectionProperties(uriParams, driverContext, properties, warning); - parseConnectionProperties(info, driverContext, properties, warning); - + Map<String, ADBDriverProperty> supportedProperties = getOrCreateSupportedPropertiesIndex(); + SQLWarning warning = new SQLWarning(); + parseConnectionProperties(getURIParameters(subUri), properties, supportedProperties, warning); + parseConnectionProperties(info, properties, supportedProperties, warning); warning = warning.getNextWarning() != null ? warning.getNextWarning() : null; - String path = subUri.getPath(); - String dataverseCanonicalName = - path != null && path.length() > 1 && path.startsWith("/") ? path.substring(1) : null; + checkDriverVersion(properties); + String dataverseCanonicalName = getDataverseCanonicalNameFromURI(subUri); + + ADBDriverContext driverContext = getOrCreateDriverContext(); ADBProtocolBase protocol = createProtocol(host, port, properties, driverContext); try { - String databaseVersion = protocol.connect(); + String serverVersion = protocol.connect(); + ADBProductVersion databaseVersion = protocol.parseDatabaseVersion(serverVersion); + checkDatabaseVersion(properties, databaseVersion); return createConnection(protocol, url, databaseVersion, dataverseCanonicalName, properties, warning); } catch (SQLException e) { try { @@ -174,9 +183,13 @@ } } + protected String getDataverseCanonicalNameFromURI(URI subUri) { + String path = subUri.getPath(); + return path != null && path.length() > 1 && path.startsWith("/") ? path.substring(1) : null; + } + public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) { - Collection<ADBDriverProperty> supportedProperties = - getOrCreateDriverContext().getSupportedProperties().values(); + Collection<ADBDriverProperty> supportedProperties = getOrCreateSupportedPropertiesIndex().values(); List<DriverPropertyInfo> result = new ArrayList<>(supportedProperties.size()); for (ADBDriverProperty property : supportedProperties) { if (property.isHidden()) { @@ -191,11 +204,11 @@ } public int getMajorVersion() { - return getOrCreateDriverContext().getDriverVersion().getMajorVersion(); + return getOrCreateDriverVersion().getMajorVersion(); } public int getMinorVersion() { - return getOrCreateDriverContext().getDriverVersion().getMinorVersion(); + return getOrCreateDriverVersion().getMinorVersion(); } public boolean jdbcCompliant() { @@ -211,31 +224,84 @@ } protected ADBDriverContext getOrCreateDriverContext() { - ADBDriverContext ctx = context; - if (ctx == null) { + ADBDriverContext result = context; + if (result == null) { synchronized (this) { - ctx = context; - if (ctx == null) { - context = ctx = createDriverContext(); + result = context; + if (result == null) { + context = result = createDriverContext(); } } } - return ctx; + return result; } protected ADBDriverContext createDriverContext() { - return new ADBDriverContext(getDriverVersion(), getDriverSupportedProperties(), createErrorReporter(), - getLogger()); + return new ADBDriverContext(getOrCreateDriverVersion(), errorReporter, getLogger()); } - protected ADBProductVersion getDriverVersion() { - return ADBProductVersion.parseDriverVersion(getClass().getPackage()); + protected ADBProductVersion getOrCreateDriverVersion() { + ADBProductVersion result = driverVersion; + if (result == null) { + synchronized (this) { + result = driverVersion; + if (result == null) { + driverVersion = result = getDriverVersion(); + } + } + } + return result; } - protected Collection<ADBDriverProperty> getDriverSupportedProperties() { + protected abstract ADBProductVersion getDriverVersion(); + + protected Collection<ADBDriverProperty> getSupportedProperties() { return Arrays.asList(ADBDriverProperty.Common.values()); } + private Map<String, ADBDriverProperty> getOrCreateSupportedPropertiesIndex() { + Map<String, ADBDriverProperty> result = supportedPropertiesIndex; + if (result == null) { + synchronized (this) { + result = supportedPropertiesIndex; + if (result == null) { + supportedPropertiesIndex = result = createPropertyIndexByName(getSupportedProperties()); + } + } + } + return result; + } + + private static Map<String, ADBDriverProperty> createPropertyIndexByName(Collection<ADBDriverProperty> properties) { + Map<String, ADBDriverProperty> m = new LinkedHashMap<>(); + for (ADBDriverProperty p : properties) { + m.put(p.getPropertyName(), p); + } + return Collections.unmodifiableMap(m); + } + + public void checkDriverVersion(Map<ADBDriverProperty, Object> properties) throws SQLException { + ADBProductVersion minExpectedVersion = + (ADBProductVersion) ADBDriverProperty.Common.MIN_DRIVER_VERSION.fetchPropertyValue(properties); + if (minExpectedVersion != null) { + ADBProductVersion driverVersion = getOrCreateDriverVersion(); + if (!driverVersion.isAtLeast(minExpectedVersion)) { + throw errorReporter.errorUnexpectedDriverVersion(driverVersion, minExpectedVersion); + } + } + } + + public void checkDatabaseVersion(Map<ADBDriverProperty, Object> properties, ADBProductVersion databaseVersion) + throws SQLException { + ADBProductVersion minExpectedVersion = + (ADBProductVersion) ADBDriverProperty.Common.MIN_DATABASE_VERSION.fetchPropertyValue(properties); + if (minExpectedVersion != null) { + if (!databaseVersion.isAtLeast(minExpectedVersion)) { + throw errorReporter.errorUnexpectedDatabaseVersion(databaseVersion, minExpectedVersion); + } + } + } + protected ADBErrorReporter createErrorReporter() { return new ADBErrorReporter(); } @@ -243,7 +309,7 @@ protected abstract ADBProtocolBase createProtocol(String host, int port, Map<ADBDriverProperty, Object> properties, ADBDriverContext driverContext) throws SQLException; - protected ADBConnection createConnection(ADBProtocolBase protocol, String url, String databaseVersion, + protected ADBConnection createConnection(ADBProtocolBase protocol, String url, ADBProductVersion databaseVersion, String dataverseCanonicalName, Map<ADBDriverProperty, Object> properties, SQLWarning connectWarning) throws SQLException { return new ADBConnection(protocol, url, databaseVersion, dataverseCanonicalName, properties, connectWarning);
diff --git a/asterixdb-jdbc/asterix-jdbc-core/src/main/java/org/apache/asterix/jdbc/core/ADBDriverContext.java b/asterixdb-jdbc/asterix-jdbc-core/src/main/java/org/apache/asterix/jdbc/core/ADBDriverContext.java index f81bb9f..45f64b2 100644 --- a/asterixdb-jdbc/asterix-jdbc-core/src/main/java/org/apache/asterix/jdbc/core/ADBDriverContext.java +++ b/asterixdb-jdbc/asterix-jdbc-core/src/main/java/org/apache/asterix/jdbc/core/ADBDriverContext.java
@@ -19,10 +19,6 @@ package org.apache.asterix.jdbc.core; -import java.util.Collection; -import java.util.Collections; -import java.util.LinkedHashMap; -import java.util.Map; import java.util.Objects; import java.util.logging.Logger; @@ -40,8 +36,6 @@ private final ADBProductVersion driverVersion; - private final Map<String, ADBDriverProperty> supportedProperties; - private final ADBErrorReporter errorReporter; private final Logger logger; @@ -54,12 +48,10 @@ private final ObjectWriter admFormatObjectWriter; - public ADBDriverContext(ADBProductVersion driverVersion, Collection<ADBDriverProperty> driverSupportedProperties, - ADBErrorReporter errorReporter, Logger logger) { + public ADBDriverContext(ADBProductVersion driverVersion, ADBErrorReporter errorReporter, Logger logger) { this.driverVersion = Objects.requireNonNull(driverVersion); this.errorReporter = Objects.requireNonNull(errorReporter); this.logger = Objects.requireNonNull(logger); - this.supportedProperties = createPropertyIndexByName(driverSupportedProperties); ObjectMapper genericObjectMapper = createGenericObjectMapper(); this.genericObjectReader = genericObjectMapper.reader(); @@ -90,14 +82,6 @@ return mapper; } - private Map<String, ADBDriverProperty> createPropertyIndexByName(Collection<ADBDriverProperty> properties) { - Map<String, ADBDriverProperty> m = new LinkedHashMap<>(); - for (ADBDriverProperty p : properties) { - m.put(p.getPropertyName(), p); - } - return Collections.unmodifiableMap(m); - } - public ADBErrorReporter getErrorReporter() { return errorReporter; } @@ -125,8 +109,4 @@ public ADBProductVersion getDriverVersion() { return driverVersion; } - - public Map<String, ADBDriverProperty> getSupportedProperties() { - return supportedProperties; - } }
diff --git a/asterixdb-jdbc/asterix-jdbc-core/src/main/java/org/apache/asterix/jdbc/core/ADBDriverProperty.java b/asterixdb-jdbc/asterix-jdbc-core/src/main/java/org/apache/asterix/jdbc/core/ADBDriverProperty.java index 4d454e6..11c762d 100644 --- a/asterixdb-jdbc/asterix-jdbc-core/src/main/java/org/apache/asterix/jdbc/core/ADBDriverProperty.java +++ b/asterixdb-jdbc/asterix-jdbc-core/src/main/java/org/apache/asterix/jdbc/core/ADBDriverProperty.java
@@ -43,8 +43,11 @@ CATALOG_DATAVERSE_MODE("catalogDataverseMode", Integer::parseInt, 1, false), // 1 -> CATALOG, 2 -> CATALOG_SCHEMA CATALOG_INCLUDES_SCHEMALESS("catalogIncludesSchemaless", Boolean::parseBoolean, false, false), SQL_COMPAT_MODE("sqlCompatMode", Boolean::parseBoolean, true, false), // Whether user statements are executed in 'SQL-compat' mode - ACTIVE_REQUESTS_PATH("activeRequestsPath", Function.identity(), null, true), - SSL("ssl", Boolean::parseBoolean, false, false); + SSL("ssl", Boolean::parseBoolean, false, false), + // Hidden properties + MIN_DRIVER_VERSION("minDriverVersion", Common::parseMinVersion, null, true), + MIN_DATABASE_VERSION("minDatabaseVersion", Common::parseMinVersion, null, true), + ACTIVE_REQUESTS_PATH("activeRequestsPath", Function.identity(), null, true); private final String propertyName; @@ -89,6 +92,22 @@ public Object fetchPropertyValue(Map<ADBDriverProperty, Object> properties) { return properties.getOrDefault(this, defaultValue); } + + public static ADBProductVersion parseMinVersion(String text) { + String[] parts = text.split("\\."); + int major, minor = 0; + switch (parts.length) { + case 2: + minor = Integer.parseInt(parts[1]); + // fall thru to 1 + case 1: + major = Integer.parseInt(parts[0]); + break; + default: + throw new IllegalArgumentException(text); + } + return new ADBProductVersion(null, text, major, minor); + } } enum CatalogDataverseMode {
diff --git a/asterixdb-jdbc/asterix-jdbc-core/src/main/java/org/apache/asterix/jdbc/core/ADBErrorReporter.java b/asterixdb-jdbc/asterix-jdbc-core/src/main/java/org/apache/asterix/jdbc/core/ADBErrorReporter.java index 8ae76f3..07abd87 100644 --- a/asterixdb-jdbc/asterix-jdbc-core/src/main/java/org/apache/asterix/jdbc/core/ADBErrorReporter.java +++ b/asterixdb-jdbc/asterix-jdbc-core/src/main/java/org/apache/asterix/jdbc/core/ADBErrorReporter.java
@@ -67,6 +67,19 @@ return String.format("Ignored unsupported or invalid value of %s parameter", parameterName); } + public SQLException errorUnexpectedDriverVersion(ADBProductVersion version, ADBProductVersion minExpectedVersion) { + return new SQLException( + String.format("Unexpected driver version %s. Expected at least %s.%s", version.getProductVersion(), + minExpectedVersion.getMajorVersion(), minExpectedVersion.getMinorVersion())); + } + + public SQLException errorUnexpectedDatabaseVersion(ADBProductVersion version, + ADBProductVersion minExpectedVersion) { + return new SQLException( + String.format("Unexpected database version %s. Expected at least %s.%s", version.getProductVersion(), + minExpectedVersion.getMajorVersion(), minExpectedVersion.getMinorVersion())); + } + public SQLException errorIncompatibleMode(String mode) { return new SQLException(String.format("Operation cannot be performed in %s mode", mode)); }
diff --git a/asterixdb-jdbc/asterix-jdbc-core/src/main/java/org/apache/asterix/jdbc/core/ADBProductVersion.java b/asterixdb-jdbc/asterix-jdbc-core/src/main/java/org/apache/asterix/jdbc/core/ADBProductVersion.java index a49a209..dd16812 100644 --- a/asterixdb-jdbc/asterix-jdbc-core/src/main/java/org/apache/asterix/jdbc/core/ADBProductVersion.java +++ b/asterixdb-jdbc/asterix-jdbc-core/src/main/java/org/apache/asterix/jdbc/core/ADBProductVersion.java
@@ -19,16 +19,10 @@ package org.apache.asterix.jdbc.core; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - public class ADBProductVersion { public static final String ASTERIXDB = "Apache AsterixDB"; - private static final Pattern DATABASE_VERSION_PATTERN = - Pattern.compile("(?<name>[^/]+)(?:/(?<ver>(?:(?<vermj>\\d+)(?:\\.(?<vermn>\\d+))?)?.*))?"); - private final String productName; private final String productVersion; @@ -60,55 +54,13 @@ return minorVersion; } - public static ADBProductVersion parseDriverVersion(Package driverPackage) { - int majorVersion = 0, minorVersion = 0; - String productName = driverPackage.getImplementationTitle(); - if (productName == null) { - productName = ASTERIXDB; - } - String productVersion = driverPackage.getImplementationVersion(); - if (productVersion != null) { - String[] v = productVersion.split("\\."); - try { - majorVersion = Integer.parseInt(v[0]); - if (v.length > 1) { - minorVersion = Integer.parseInt(v[1]); - } - } catch (NumberFormatException e) { - // ignore - } - } - return new ADBProductVersion(productName, productVersion, majorVersion, minorVersion); + public boolean isAtLeast(ADBProductVersion otherVersion) { + return majorVersion == otherVersion.majorVersion ? minorVersion >= otherVersion.minorVersion + : majorVersion > otherVersion.majorVersion; } - public static ADBProductVersion parseDatabaseVersion(String serverVersion) { - String dbProductName = null; - String dbProductVersion = null; - int dbMajorVersion = 0; - int dbMinorVersion = 0; - if (serverVersion != null) { - Matcher m = DATABASE_VERSION_PATTERN.matcher(serverVersion); - if (m.matches()) { - dbProductName = m.group("name"); - dbProductVersion = m.group("ver"); - String vermj = m.group("vermj"); - String vermn = m.group("vermn"); - if (vermj != null) { - try { - dbMajorVersion = Integer.parseInt(vermj); - } catch (NumberFormatException e) { - // ignore (overflow) - } - } - if (vermn != null) { - try { - dbMinorVersion = Integer.parseInt(vermn); - } catch (NumberFormatException e) { - // ignore (overflow) - } - } - } - } - return new ADBProductVersion(dbProductName, dbProductVersion, dbMajorVersion, dbMinorVersion); + @Override + public String toString() { + return productName + '/' + productVersion; } }
diff --git a/asterixdb-jdbc/asterix-jdbc-core/src/main/java/org/apache/asterix/jdbc/core/ADBProtocolBase.java b/asterixdb-jdbc/asterix-jdbc-core/src/main/java/org/apache/asterix/jdbc/core/ADBProtocolBase.java index 39db835..6bf6c1f 100644 --- a/asterixdb-jdbc/asterix-jdbc-core/src/main/java/org/apache/asterix/jdbc/core/ADBProtocolBase.java +++ b/asterixdb-jdbc/asterix-jdbc-core/src/main/java/org/apache/asterix/jdbc/core/ADBProtocolBase.java
@@ -33,6 +33,8 @@ import java.util.UUID; import java.util.function.Function; import java.util.logging.Logger; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.node.ArrayNode; @@ -63,6 +65,9 @@ private static final String OPTIONAL_TYPE_SUFFIX = "?"; private static final String EXPLAIN_ONLY_RESULT_COLUMN_NAME = "$1"; + private static final Pattern DATABASE_VERSION_PATTERN = + Pattern.compile("(?<name>[^/]+)(?:/(?<ver>(?:(?<vermj>\\d+)(?:\\.(?<vermn>\\d+))?)?.*))?"); + protected final ADBDriverContext driverContext; protected final String user; protected final int maxWarnings; @@ -218,6 +223,37 @@ return paramPos; } + public ADBProductVersion parseDatabaseVersion(String serverVersion) { + String dbProductName = null; + String dbProductVersion = null; + int dbMajorVersion = 0; + int dbMinorVersion = 0; + if (serverVersion != null) { + Matcher m = DATABASE_VERSION_PATTERN.matcher(serverVersion); + if (m.matches()) { + dbProductName = m.group("name"); + dbProductVersion = m.group("ver"); + String vermj = m.group("vermj"); + String vermn = m.group("vermn"); + if (vermj != null) { + try { + dbMajorVersion = Integer.parseInt(vermj); + } catch (NumberFormatException e) { + // ignore (overflow) + } + } + if (vermn != null) { + try { + dbMinorVersion = Integer.parseInt(vermn); + } catch (NumberFormatException e) { + // ignore (overflow) + } + } + } + } + return new ADBProductVersion(dbProductName, dbProductVersion, dbMajorVersion, dbMinorVersion); + } + public String getDefaultDataverse() { return DEFAULT_DATAVERSE; }
diff --git a/asterixdb-jdbc/asterix-jdbc-driver/src/main/java/org/apache/asterix/jdbc/Driver.java b/asterixdb-jdbc/asterix-jdbc-driver/src/main/java/org/apache/asterix/jdbc/Driver.java index 97fb256..ac1701f 100644 --- a/asterixdb-jdbc/asterix-jdbc-driver/src/main/java/org/apache/asterix/jdbc/Driver.java +++ b/asterixdb-jdbc/asterix-jdbc-driver/src/main/java/org/apache/asterix/jdbc/Driver.java
@@ -31,6 +31,7 @@ import org.apache.asterix.jdbc.core.ADBDriverContext; import org.apache.asterix.jdbc.core.ADBDriverProperty; import org.apache.asterix.jdbc.core.ADBErrorReporter; +import org.apache.asterix.jdbc.core.ADBProductVersion; import org.apache.http.NameValuePair; import org.apache.http.client.utils.URLEncodedUtils; @@ -82,4 +83,26 @@ } }; } + + @Override + protected ADBProductVersion getDriverVersion() { + Package driverPackage = getClass().getPackage(); + return parseDriverVersion(driverPackage.getImplementationTitle(), driverPackage.getImplementationVersion()); + } + + private static ADBProductVersion parseDriverVersion(String productName, String productVersion) { + int majorVersion = 0, minorVersion = 0; + if (productVersion != null) { + String[] v = productVersion.split("\\."); + try { + majorVersion = Integer.parseInt(v[0]); + if (v.length > 1) { + minorVersion = Integer.parseInt(v[1]); + } + } catch (NumberFormatException e) { + // ignore + } + } + return new ADBProductVersion(productName, productVersion, majorVersion, minorVersion); + } }