diff --git a/src/main/java/com/aerospike/jdbc/AerospikeConnection.java b/src/main/java/com/aerospike/jdbc/AerospikeConnection.java index 1f9bf02..1aeeea8 100644 --- a/src/main/java/com/aerospike/jdbc/AerospikeConnection.java +++ b/src/main/java/com/aerospike/jdbc/AerospikeConnection.java @@ -6,6 +6,7 @@ import com.aerospike.jdbc.sql.SimpleWrapper; import com.aerospike.jdbc.sql.type.ByteArrayBlob; import com.aerospike.jdbc.sql.type.StringClob; +import com.aerospike.jdbc.util.AerospikeVersion; import com.aerospike.jdbc.util.DatabaseMetadataBuilder; import java.sql.*; @@ -33,7 +34,9 @@ public class AerospikeConnection implements Connection, SimpleWrapper { private final DriverConfiguration config; private final IAerospikeClient client; private final DatabaseMetadataBuilder metadataBuilder; + private final AerospikeVersion aerospikeVersion; private final AtomicReference schema = new AtomicReference<>(null); // namespace + private volatile boolean readOnly = false; private volatile Map> typeMap = emptyMap(); private volatile int holdability = HOLD_CURSORS_OVER_COMMIT; @@ -45,6 +48,7 @@ public AerospikeConnection(String url, Properties props) { config = new DriverConfiguration(props); client = config.parse(url); metadataBuilder = new DatabaseMetadataBuilder(config.getDriverPolicy()); + aerospikeVersion = new AerospikeVersion(client); schema.set(config.getSchema()); // namespace } @@ -361,6 +365,10 @@ public DriverConfiguration getConfiguration() { return config; } + public AerospikeVersion getAerospikeVersion() { + return aerospikeVersion; + } + public IAerospikeClient getClient() { return client; } diff --git a/src/main/java/com/aerospike/jdbc/AerospikeDatabaseMetadata.java b/src/main/java/com/aerospike/jdbc/AerospikeDatabaseMetadata.java index 2cd5ae9..e8b562e 100644 --- a/src/main/java/com/aerospike/jdbc/AerospikeDatabaseMetadata.java +++ b/src/main/java/com/aerospike/jdbc/AerospikeDatabaseMetadata.java @@ -58,7 +58,7 @@ public class AerospikeDatabaseMetadata implements DatabaseMetaData, SimpleWrappe private final Map> catalogIndexes; private final Map secondaryIndexes; - public AerospikeDatabaseMetadata(String url, IAerospikeClient client, Connection connection) { + public AerospikeDatabaseMetadata(String url, IAerospikeClient client, AerospikeConnection connection) { logger.info("Init AerospikeDatabaseMetadata"); AerospikeSchemaBuilder.cleanSchemaCache(); this.url = url; @@ -82,17 +82,22 @@ public AerospikeDatabaseMetadata(String url, IAerospikeClient client, Connection ); streamOfSubProperties(r, "sindex") .filter(AerospikeUtils::isSupportedIndexType) - .forEach(p -> - catalogIndexes.computeIfAbsent(p.getProperty("ns"), s -> new HashSet<>()) - .add(new AerospikeSecondaryIndex( - p.getProperty("ns"), - p.getProperty("set"), - p.getProperty("bin"), - p.getProperty("indexname"), - IndexType.valueOf(p.getProperty("type").toUpperCase(Locale.ENGLISH)), - getIndexBinValuesRatio(client, p.getProperty("ns"), p.getProperty("indexname"))) - ) - ); + .forEach(p -> { + String namespace = p.getProperty("ns"); + String indexName = p.getProperty("indexname"); + Integer binRatio = connection.getAerospikeVersion().isSIndexCardinalitySupported() + ? getIndexBinValuesRatio(client, namespace, indexName) + : null; + catalogIndexes.computeIfAbsent(namespace, s -> new HashSet<>()) + .add(new AerospikeSecondaryIndex( + namespace, + p.getProperty("set"), + p.getProperty("bin"), + indexName, + IndexType.valueOf(p.getProperty("type").toUpperCase(Locale.ENGLISH)), + binRatio) + ); + }); }); secondaryIndexes = catalogIndexes.values().stream() .flatMap(Collection::stream) @@ -853,7 +858,8 @@ public ResultSet getPrimaryKeys(String catalog, String schema, String table) { final Iterable> tablesData; if (catalog == null) { tablesData = tables.entrySet().stream() - .flatMap(p -> p.getValue().stream().map(t -> asList(p.getKey(), null, t, defaultKeyName, 1, defaultKeyName))) + .flatMap(p -> p.getValue().stream().map(t -> + asList(p.getKey(), null, t, defaultKeyName, 1, defaultKeyName))) .collect(toList()); } else { tablesData = tables.getOrDefault(catalog, Collections.emptyList()).stream() @@ -906,8 +912,9 @@ public ResultSet getCrossReference(String parentCatalog, String parentSchema, St public ResultSet getTypeInfo() { String[] columns = new String[]{ "TYPE_NAME", "DATA_TYPE", "PRECISION", "LITERAL_PREFIX", "LITERAL_SUFFIX", "CREATE_PARAMS", "NULLABLE", - "CASE_SENSITIVE", "SEARCHABLE", "UNSIGNED_ATTRIBUTE", "FIXED_PREC_SCALE", "AUTO_INCREMENT", "LOCAL_TYPE_NAME", - "MINIMUM_SCALE", "MAXIMUM_SCALE", "SQL_DATA_TYPE", "SQL_DATETIME_SUB", "NUM_PREC_RADIX", + "CASE_SENSITIVE", "SEARCHABLE", "UNSIGNED_ATTRIBUTE", "FIXED_PREC_SCALE", "AUTO_INCREMENT", + "LOCAL_TYPE_NAME", "MINIMUM_SCALE", "MAXIMUM_SCALE", "SQL_DATA_TYPE", "SQL_DATETIME_SUB", + "NUM_PREC_RADIX", }; Iterable> data = asList( @@ -1100,7 +1107,8 @@ public ResultSet getAttributes(String catalog, String schemaPattern, String type "IS_NULLABLE", "SCOPE_CATALOG", "SCOPE_SCHEMA", "SCOPE_TABLE", "SOURCE_DATA_TYPE"}; int[] sqlTypes = new int[]{VARCHAR, VARCHAR, VARCHAR, VARCHAR, INTEGER, VARCHAR, INTEGER, INTEGER, INTEGER, - INTEGER, VARCHAR, VARCHAR, INTEGER, INTEGER, INTEGER, INTEGER, VARCHAR, VARCHAR, VARCHAR, VARCHAR, SMALLINT}; + INTEGER, VARCHAR, VARCHAR, INTEGER, INTEGER, INTEGER, INTEGER, VARCHAR, VARCHAR, VARCHAR, VARCHAR, + SMALLINT}; return new ListRecordSet(null, "system", "attributes", systemColumns(columns, sqlTypes), emptyList()); @@ -1206,7 +1214,8 @@ public ResultSet getFunctions(String catalog, String schemaPattern, String funct } @Override - public ResultSet getFunctionColumns(String catalog, String schemaPattern, String functionNamePattern, String columnNamePattern) { + public ResultSet getFunctionColumns(String catalog, String schemaPattern, String functionNamePattern, + String columnNamePattern) { String[] columns = new String[]{"FUNCTION_CAT", "FUNCTION_SCHEM", "FUNCTION_NAME", "COLUMN_NAME", "COLUMN_TYPE", "DATA_TYPE", "TYPE_NAME", "PRECISION", "LENGTH", "SCALE", "RADIX", "NULLABLE", "REMARKS", "CHAR_OCTET_LENGTH", "ORDINAL_POSITION", "IS_NULLABLE", "SPECIFIC_NAME"}; @@ -1219,9 +1228,11 @@ public ResultSet getFunctionColumns(String catalog, String schemaPattern, String } @Override - public ResultSet getPseudoColumns(String catalog, String schemaPattern, String tableNamePattern, String columnNamePattern) { + public ResultSet getPseudoColumns(String catalog, String schemaPattern, String tableNamePattern, + String columnNamePattern) { String[] columns = new String[]{"TABLE_CAT", "TABLE_SCHEM", "TABLE_NAME", "COLUMN_NAME", "DATA_TYPE", - "COLUMN_SIZE", "DECIMAL_DIGITS", "NUM_PREC_RADIX", "COLUMN_USAGE", "REMARKS", "CHAR_OCTET_LENGTH", "IS_NULLABLE"}; + "COLUMN_SIZE", "DECIMAL_DIGITS", "NUM_PREC_RADIX", "COLUMN_USAGE", "REMARKS", "CHAR_OCTET_LENGTH", + "IS_NULLABLE"}; int[] sqlTypes = new int[]{VARCHAR, VARCHAR, VARCHAR, VARCHAR, INTEGER, INTEGER, INTEGER, INTEGER, VARCHAR, VARCHAR, INTEGER, VARCHAR}; diff --git a/src/main/java/com/aerospike/jdbc/model/AerospikeQuery.java b/src/main/java/com/aerospike/jdbc/model/AerospikeQuery.java index 4e7d11e..a0de1f6 100644 --- a/src/main/java/com/aerospike/jdbc/model/AerospikeQuery.java +++ b/src/main/java/com/aerospike/jdbc/model/AerospikeQuery.java @@ -13,6 +13,7 @@ import java.util.Collection; import java.util.Collections; import java.util.List; +import java.util.Objects; import static com.aerospike.jdbc.util.Constants.defaultSchemaName; @@ -160,6 +161,10 @@ public Collection getPrimaryKeys() { return Collections.emptyList(); } + public boolean isIndexable() { + return Objects.nonNull(predicate) && predicate.isIndexable() && Objects.isNull(offset); + } + @Override public String toString() { try { diff --git a/src/main/java/com/aerospike/jdbc/query/BaseQueryHandler.java b/src/main/java/com/aerospike/jdbc/query/BaseQueryHandler.java index 6edd395..7d9eafd 100644 --- a/src/main/java/com/aerospike/jdbc/query/BaseQueryHandler.java +++ b/src/main/java/com/aerospike/jdbc/query/BaseQueryHandler.java @@ -7,6 +7,7 @@ import com.aerospike.jdbc.model.AerospikeQuery; import com.aerospike.jdbc.model.DriverConfiguration; import com.aerospike.jdbc.sql.ListRecordSet; +import com.aerospike.jdbc.util.AerospikeVersion; import java.sql.SQLException; import java.sql.Statement; @@ -18,18 +19,16 @@ public abstract class BaseQueryHandler implements QueryHandler { protected final IAerospikeClient client; protected final Statement statement; - protected final DriverConfiguration config; protected final PolicyBuilder policyBuilder; + protected final DriverConfiguration config; + protected final AerospikeVersion aerospikeVersion; protected BaseQueryHandler(IAerospikeClient client, Statement statement) { this.client = client; this.statement = statement; - try { - config = ((AerospikeConnection) statement.getConnection()).getConfiguration(); - } catch (SQLException e) { - throw new IllegalStateException("Failed to get configuration", e); - } policyBuilder = new PolicyBuilder(client); + config = getConfiguration(); + aerospikeVersion = getAerospikeVersion(); } protected Bin[] getBins(AerospikeQuery query) { @@ -45,4 +44,20 @@ protected ListRecordSet emptyRecordSet(AerospikeQuery query) { return new ListRecordSet(statement, query.getSchema(), query.getTable(), emptyList(), emptyList()); } + + private DriverConfiguration getConfiguration() { + try { + return ((AerospikeConnection) statement.getConnection()).getConfiguration(); + } catch (SQLException e) { + throw new IllegalStateException("Failed to get DriverConfiguration", e); + } + } + + private AerospikeVersion getAerospikeVersion() { + try { + return ((AerospikeConnection) statement.getConnection()).getAerospikeVersion(); + } catch (SQLException e) { + throw new IllegalStateException("Failed to get AerospikeVersion", e); + } + } } diff --git a/src/main/java/com/aerospike/jdbc/query/InsertQueryHandler.java b/src/main/java/com/aerospike/jdbc/query/InsertQueryHandler.java index 8d00da9..caf2d7d 100644 --- a/src/main/java/com/aerospike/jdbc/query/InsertQueryHandler.java +++ b/src/main/java/com/aerospike/jdbc/query/InsertQueryHandler.java @@ -9,7 +9,6 @@ import com.aerospike.jdbc.async.FutureWriteListener; import com.aerospike.jdbc.model.AerospikeQuery; import com.aerospike.jdbc.model.Pair; -import com.aerospike.jdbc.util.VersionUtils; import java.sql.ResultSet; import java.sql.Statement; @@ -33,7 +32,7 @@ public InsertQueryHandler(IAerospikeClient client, Statement statement) { @Override public Pair execute(AerospikeQuery query) { - if (VersionUtils.isBatchOpsSupported(client)) { + if (aerospikeVersion.isBatchOpsSupported()) { logger.info("INSERT batch"); return putBatch(query); } diff --git a/src/main/java/com/aerospike/jdbc/query/SelectQueryHandler.java b/src/main/java/com/aerospike/jdbc/query/SelectQueryHandler.java index 9e67b08..123f337 100644 --- a/src/main/java/com/aerospike/jdbc/query/SelectQueryHandler.java +++ b/src/main/java/com/aerospike/jdbc/query/SelectQueryHandler.java @@ -20,7 +20,6 @@ import com.aerospike.jdbc.model.Pair; import com.aerospike.jdbc.schema.AerospikeSchemaBuilder; import com.aerospike.jdbc.sql.AerospikeRecordResultSet; -import com.aerospike.jdbc.util.VersionUtils; import java.sql.ResultSet; import java.sql.SQLException; @@ -75,7 +74,8 @@ private Pair executeCountQuery(AerospikeQuery query) { recordNumber = getTableRecordsNumber(client, query.getSchema(), query.getTable()); } else { ScanPolicy policy = policyBuilder.buildScanNoBinDataPolicy(query); - RecordSet recordSet = ScanQueryHandler.create(client, config.getDriverPolicy()).execute(policy, query); + RecordSet recordSet = ScanQueryHandler.create(client, config.getDriverPolicy()) + .execute(policy, query); final AtomicInteger count = new AtomicInteger(); recordSet.forEach(r -> count.incrementAndGet()); @@ -88,25 +88,26 @@ private Pair executeCountQuery(AerospikeQuery query) { recordSet.put(new KeyRecord(null, aeroRecord)); recordSet.close(); - List columnList = Collections.singletonList(new DataColumn(query.getSchema(), - query.getTable(), Types.INTEGER, countLabel, countLabel)); + columns = Collections.singletonList(new DataColumn(query.getSchema(), query.getTable(), + Types.INTEGER, countLabel, countLabel)); - return new Pair<>(new AerospikeRecordResultSet(recordSet, statement, query.getSchema(), - query.getTable(), columnList), -1); + return queryResult(recordSet, query); } private Pair executeSelectByPrimaryKey(AerospikeQuery query, Collection keyObjects) { logger.info(() -> "SELECT primary key"); final BatchReadPolicy policy = policyBuilder.buildBatchReadPolicy(query); List batchReadList = keyObjects.stream() - .map(k -> new BatchRead(policy, new Key(query.getSchema(), query.getSetName(), Value.get(k)), true)) + .map(k -> { + Key key = new Key(query.getSchema(), query.getSetName(), Value.get(k)); + return new BatchRead(policy, key, true); + }) .collect(Collectors.toList()); RecordSetBatchSequenceListener listener = new RecordSetBatchSequenceListener(config.getDriverPolicy()); client.get(EventLoopProvider.getEventLoop(), listener, null, batchReadList); - return new Pair<>(new AerospikeRecordResultSet(listener.getRecordSet(), statement, query.getSchema(), - query.getTable(), filterColumns(columns, query.getBinNames())), -1); + return queryResult(listener.getRecordSet(), query); } private Pair executeScan(AerospikeQuery query) { @@ -115,8 +116,7 @@ private Pair executeScan(AerospikeQuery query) { ScanPolicy policy = policyBuilder.buildScanPolicy(query); RecordSet recordSet = ScanQueryHandler.create(client, config.getDriverPolicy()).execute(policy, query); - return new Pair<>(new AerospikeRecordResultSet(recordSet, statement, query.getSchema(), - query.getTable(), filterColumns(columns, query.getBinNames())), -1); + return queryResult(recordSet, query); } private Pair executeQuery(AerospikeQuery query, @@ -127,13 +127,11 @@ private Pair executeQuery(AerospikeQuery query, RecordSet recordSet = SecondaryIndexQueryHandler.create(client, config.getDriverPolicy()) .execute(policy, query, secondaryIndex); - return new Pair<>(new AerospikeRecordResultSet(recordSet, statement, query.getSchema(), - query.getTable(), filterColumns(columns, query.getBinNames())), -1); + return queryResult(recordSet, query); } private Optional secondaryIndex(AerospikeQuery query) { - if (VersionUtils.isSIndexSupported(client) && Objects.nonNull(query.getPredicate()) - && query.getPredicate().isIndexable() && Objects.isNull(query.getOffset())) { + if (aerospikeVersion.isSIndexSupported() && query.isIndexable()) { Map indexMap = secondaryIndexes; List binNames = query.getPredicate().getBinNames(); if (!binNames.isEmpty() && indexMap != null && !indexMap.isEmpty()) { @@ -146,11 +144,7 @@ private Optional secondaryIndex(AerospikeQuery query) { } } else { List indexList = new ArrayList<>(indexMap.values()); - if (VersionUtils.isSIndexCardinalitySupported(client)) { - indexList.sort(Comparator.comparingInt(AerospikeSecondaryIndex::getBinValuesRatio)); - } else { - indexList.sort(Comparator.comparing(AerospikeSecondaryIndex::getBinName)); - } + sortIndexList(indexList); for (AerospikeSecondaryIndex index : indexList) { if (binNames.contains(index.getBinName())) { return Optional.of(index); @@ -162,6 +156,19 @@ private Optional secondaryIndex(AerospikeQuery query) { return Optional.empty(); } + private Pair queryResult(RecordSet recordSet, AerospikeQuery query) { + return new Pair<>(new AerospikeRecordResultSet(recordSet, statement, query.getSchema(), + query.getTable(), filterColumns(columns, query.getBinNames())), -1); + } + + private void sortIndexList(List indexList) { + if (aerospikeVersion.isSIndexCardinalitySupported()) { + indexList.sort(Comparator.comparingInt(AerospikeSecondaryIndex::getBinValuesRatio)); + } else { + indexList.sort(Comparator.comparing(AerospikeSecondaryIndex::getBinName)); + } + } + private boolean isCount(AerospikeQuery query) { return query.getColumns().size() == 1 && query.getColumns().get(0).toLowerCase(Locale.ENGLISH).startsWith("count("); diff --git a/src/main/java/com/aerospike/jdbc/util/AerospikeUtils.java b/src/main/java/com/aerospike/jdbc/util/AerospikeUtils.java index 3cd6a48..bb0737c 100644 --- a/src/main/java/com/aerospike/jdbc/util/AerospikeUtils.java +++ b/src/main/java/com/aerospike/jdbc/util/AerospikeUtils.java @@ -3,6 +3,7 @@ import com.aerospike.client.IAerospikeClient; import com.aerospike.client.Info; import com.aerospike.client.cluster.Node; +import com.aerospike.client.policy.InfoPolicy; import com.aerospike.client.query.IndexType; import com.google.common.base.Splitter; @@ -21,11 +22,12 @@ public final class AerospikeUtils { private AerospikeUtils() { } - public static Map getTableInfo(String ns, String set, Node node) { - String sets = Info.request(null, node, "sets"); + public static Map getTableInfo(InfoPolicy infoPolicy, String ns, String set, Node node) { + String sets = Info.request(infoPolicy, node, "sets"); Optional tableInfo = Splitter.on(";").trimResults().splitToList(sets).stream() .filter(s -> s.startsWith("ns=" + ns + ":set=" + set)) .findFirst(); + return tableInfo.map(value -> Pattern.compile("\\s*:\\s*") .splitAsStream(value) .map(s -> s.split("=", 2)) @@ -33,14 +35,17 @@ public static Map getTableInfo(String ns, String set, Node node) } public static Map getSchemaInfo(IAerospikeClient client, String ns) { - String schemaInfo = Info.request(null, client.getCluster().getRandomNode(), "namespace/" + ns); + String schemaInfo = Info.request(client.getInfoPolicyDefault(), + client.getCluster().getRandomNode(), "namespace/" + ns); + return Splitter.on(";").trimResults().splitToList(schemaInfo).stream() .map(s -> s.split("=", 2)) .collect(Collectors.toMap(e -> e[0], e -> e[1])); } public static int getTableRecordsNumber(IAerospikeClient client, String ns, String set) { - int allRecords = Arrays.stream(client.getNodes()).map(n -> getTableInfo(ns, set, n)) + int allRecords = Arrays.stream(client.getNodes()) + .map(n -> getTableInfo(client.getInfoPolicyDefault(), ns, set, n)) .map(m -> Integer.parseInt(m.get("objects"))) .reduce(0, Integer::sum); @@ -56,19 +61,17 @@ public static boolean isSupportedIndexType(Properties properties) { } public static Integer getIndexBinValuesRatio(IAerospikeClient client, String namespace, String indexName) { - if (VersionUtils.isSIndexCardinalitySupported(client)) { - try { - String indexStatData = Info.request(null, client.getCluster().getRandomNode(), - String.format("sindex-stat:ns=%s;indexname=%s", namespace, indexName)); + try { + String indexStatData = Info.request(client.getInfoPolicyDefault(), client.getCluster().getRandomNode(), + String.format("sindex-stat:ns=%s;indexname=%s", namespace, indexName)); - return Integer.valueOf(Splitter.on(";").trimResults().splitToList(indexStatData).stream() - .map(stat -> Splitter.on("=").trimResults().splitToList(stat)) - .collect(Collectors.toMap(t -> t.get(0), t -> t.get(1))) - .get("entries_per_bval")); - } catch (Exception e) { - logger.warning(() -> String.format("Failed to fetch secondary index %s cardinality", indexName)); - } + return Integer.valueOf(Splitter.on(";").trimResults().splitToList(indexStatData).stream() + .map(stat -> Splitter.on("=").trimResults().splitToList(stat)) + .collect(Collectors.toMap(t -> t.get(0), t -> t.get(1))) + .get("entries_per_bval")); + } catch (Exception e) { + logger.warning(() -> String.format("Failed to fetch secondary index %s cardinality", indexName)); + return null; } - return null; } } diff --git a/src/main/java/com/aerospike/jdbc/util/VersionUtils.java b/src/main/java/com/aerospike/jdbc/util/AerospikeVersion.java similarity index 76% rename from src/main/java/com/aerospike/jdbc/util/VersionUtils.java rename to src/main/java/com/aerospike/jdbc/util/AerospikeVersion.java index d6b2662..ccd3a62 100644 --- a/src/main/java/com/aerospike/jdbc/util/VersionUtils.java +++ b/src/main/java/com/aerospike/jdbc/util/AerospikeVersion.java @@ -9,27 +9,29 @@ import static java.lang.String.format; -public final class VersionUtils { +public class AerospikeVersion { - private static final Logger logger = Logger.getLogger(VersionUtils.class.getName()); + private static final Logger logger = Logger.getLogger(AerospikeVersion.class.getName()); private static final String S_INDEX_SUPPORT_VERSION = "6.0.0.0"; private static final String BATCH_OPS_SUPPORT_VERSION = "6.0.0.0"; private static final String S_INDEX_CARDINALITY_SUPPORT_VERSION = "6.1.0.0"; private static final Pattern versionPattern = Pattern.compile("^(\\d.){1,3}\\d(?=.*|$)"); - private static volatile Boolean sIndexSupported; - private static volatile Boolean batchOpsSupported; - private static volatile Boolean sIndexCardinalitySupported; + private final IAerospikeClient client; + private volatile Boolean sIndexSupported; + private volatile Boolean batchOpsSupported; + private volatile Boolean sIndexCardinalitySupported; - private VersionUtils() { + public AerospikeVersion(IAerospikeClient client) { + this.client = client; } - public static boolean isSIndexSupported(IAerospikeClient client) { + public boolean isSIndexSupported() { if (sIndexSupported == null) { - synchronized (VersionUtils.class) { + synchronized (this) { if (sIndexSupported == null) { - String serverVersion = clearQualifier(getAerospikeServerVersion(client)); + String serverVersion = clearQualifier(getAerospikeServerVersion()); sIndexSupported = compareVersions(serverVersion, S_INDEX_SUPPORT_VERSION) >= 0; logger.info(() -> format("Secondary index supported: %b, for version: %s", sIndexSupported, serverVersion)); @@ -39,11 +41,11 @@ public static boolean isSIndexSupported(IAerospikeClient client) { return sIndexSupported; } - public static boolean isBatchOpsSupported(IAerospikeClient client) { + public boolean isBatchOpsSupported() { if (batchOpsSupported == null) { - synchronized (VersionUtils.class) { + synchronized (this) { if (batchOpsSupported == null) { - String serverVersion = clearQualifier(getAerospikeServerVersion(client)); + String serverVersion = clearQualifier(getAerospikeServerVersion()); batchOpsSupported = compareVersions(serverVersion, BATCH_OPS_SUPPORT_VERSION) >= 0; logger.info(() -> format("Batch operations supported: %b, for version: %s", batchOpsSupported, serverVersion)); @@ -53,11 +55,11 @@ public static boolean isBatchOpsSupported(IAerospikeClient client) { return batchOpsSupported; } - public static boolean isSIndexCardinalitySupported(IAerospikeClient client) { + public boolean isSIndexCardinalitySupported() { if (sIndexCardinalitySupported == null) { - synchronized (VersionUtils.class) { + synchronized (this) { if (sIndexCardinalitySupported == null) { - String serverVersion = clearQualifier(getAerospikeServerVersion(client)); + String serverVersion = clearQualifier(getAerospikeServerVersion()); sIndexCardinalitySupported = compareVersions(serverVersion, S_INDEX_CARDINALITY_SUPPORT_VERSION) >= 0; logger.info(() -> format("Secondary index cardinality supported: %b, for version: %s", sIndexCardinalitySupported, serverVersion)); @@ -67,13 +69,13 @@ public static boolean isSIndexCardinalitySupported(IAerospikeClient client) { return sIndexCardinalitySupported; } - public static String getAerospikeServerVersion(IAerospikeClient client) { + public String getAerospikeServerVersion() { String versionString = Info.request(client.getInfoPolicyDefault(), client.getCluster().getRandomNode(), "version"); return versionString.substring(versionString.lastIndexOf(' ') + 1); } - private static String clearQualifier(String version) { + private String clearQualifier(String version) { Matcher m = versionPattern.matcher(version); if (m.find()) { return m.group(0); @@ -81,7 +83,7 @@ private static String clearQualifier(String version) { return version; } - private static int compareVersions(String version1, String version2) { + private int compareVersions(String version1, String version2) { int comparisonResult = 0; String[] version1Splits = version1.split("\\."); diff --git a/src/main/java/com/aerospike/jdbc/util/DatabaseMetadataBuilder.java b/src/main/java/com/aerospike/jdbc/util/DatabaseMetadataBuilder.java index 8ef70e0..7744cf1 100644 --- a/src/main/java/com/aerospike/jdbc/util/DatabaseMetadataBuilder.java +++ b/src/main/java/com/aerospike/jdbc/util/DatabaseMetadataBuilder.java @@ -1,12 +1,12 @@ package com.aerospike.jdbc.util; import com.aerospike.client.IAerospikeClient; +import com.aerospike.jdbc.AerospikeConnection; import com.aerospike.jdbc.AerospikeDatabaseMetadata; import com.aerospike.jdbc.model.DriverPolicy; import com.google.common.cache.Cache; import com.google.common.cache.CacheBuilder; -import java.sql.Connection; import java.sql.SQLException; import java.time.Duration; import java.util.concurrent.ExecutionException; @@ -21,7 +21,7 @@ public DatabaseMetadataBuilder(DriverPolicy driverPolicy) { .build(); } - public AerospikeDatabaseMetadata build(String url, IAerospikeClient client, Connection connection) + public AerospikeDatabaseMetadata build(String url, IAerospikeClient client, AerospikeConnection connection) throws SQLException { try { return metadataCache.get(url, () -> new AerospikeDatabaseMetadata(url, client, connection));