Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.aerospike.jdbc.query.SelectQueryHandler Maven / Gradle / Ivy
package com.aerospike.jdbc.query;
import com.aerospike.client.BatchRead;
import com.aerospike.client.IAerospikeClient;
import com.aerospike.client.Key;
import com.aerospike.client.Value;
import com.aerospike.client.policy.BatchReadPolicy;
import com.aerospike.client.policy.QueryPolicy;
import com.aerospike.client.policy.ScanPolicy;
import com.aerospike.client.query.KeyRecord;
import com.aerospike.jdbc.async.EventLoopProvider;
import com.aerospike.jdbc.async.RecordSet;
import com.aerospike.jdbc.async.RecordSetBatchSequenceListener;
import com.aerospike.jdbc.async.ScanQueryHandler;
import com.aerospike.jdbc.async.SecondaryIndexQueryHandler;
import com.aerospike.jdbc.model.AerospikeQuery;
import com.aerospike.jdbc.model.AerospikeSecondaryIndex;
import com.aerospike.jdbc.model.DataColumn;
import com.aerospike.jdbc.model.Pair;
import com.aerospike.jdbc.sql.AerospikeRecordResultSet;
import java.sql.ResultSet;
import java.sql.Statement;
import java.sql.Types;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Logger;
import java.util.stream.Collectors;
import static com.aerospike.jdbc.util.AerospikeUtils.getTableRecordsNumber;
public class SelectQueryHandler extends BaseQueryHandler {
private static final Logger logger = Logger.getLogger(SelectQueryHandler.class.getName());
protected List columns;
public SelectQueryHandler(IAerospikeClient client, Statement statement) {
super(client, statement);
}
@Override
public Pair execute(AerospikeQuery query) {
columns = databaseMetadata.getSchemaBuilder().getSchema(query.getCatalogTable());
Collection keyObjects = query.getPrimaryKeys();
Optional sIndex = secondaryIndex(query);
Pair result;
if (query.isCount()) {
result = executeCountQuery(query);
} else if (!keyObjects.isEmpty()) {
result = executeSelectByPrimaryKey(query, keyObjects);
} else {
result = sIndex.map(secondaryIndex -> executeQuery(query, secondaryIndex))
.orElseGet(() -> executeScan(query));
}
return result;
}
private Pair executeCountQuery(AerospikeQuery query) {
logger.info(() -> "SELECT count");
String countLabel = query.getColumns().get(0);
int recordNumber;
if (Objects.isNull(query.getPredicate())) {
recordNumber = getTableRecordsNumber(client, query.getCatalog(), query.getTable());
} else {
ScanPolicy policy = policyBuilder.buildScanNoBinDataPolicy(query);
RecordSet recordSet = ScanQueryHandler.create(client, config.getDriverPolicy())
.execute(policy, query);
final AtomicInteger count = new AtomicInteger();
recordSet.forEach(r -> count.incrementAndGet());
recordNumber = count.get();
}
com.aerospike.client.Record aeroRecord = new com.aerospike.client.Record(Collections.singletonMap(
countLabel, recordNumber), 1, 0);
RecordSet recordSet = new RecordSet(2, config.getDriverPolicy().getRecordSetTimeoutMs());
recordSet.put(new KeyRecord(null, aeroRecord));
recordSet.close();
columns = Collections.singletonList(new DataColumn(query.getCatalog(), query.getTable(),
Types.INTEGER, countLabel, countLabel));
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 -> {
Key key = new Key(query.getCatalog(), 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 queryResult(listener.getRecordSet(), query);
}
private Pair executeScan(AerospikeQuery query) {
logger.info(() -> "SELECT scan " + (Objects.nonNull(query.getOffset()) ? "partition" : "all"));
ScanPolicy policy = policyBuilder.buildScanPolicy(query);
RecordSet recordSet = ScanQueryHandler.create(client, config.getDriverPolicy()).execute(policy, query);
return queryResult(recordSet, query);
}
private Pair executeQuery(AerospikeQuery query,
AerospikeSecondaryIndex secondaryIndex) {
logger.info(() -> "SELECT secondary index query for column: " + secondaryIndex.getBinName());
QueryPolicy policy = policyBuilder.buildQueryPolicy(query);
RecordSet recordSet = SecondaryIndexQueryHandler.create(client, config.getDriverPolicy())
.execute(policy, query, secondaryIndex);
return queryResult(recordSet, query);
}
private Optional secondaryIndex(AerospikeQuery query) {
if (aerospikeVersion.isSIndexSupported() && query.isIndexable()) {
Collection indexes = databaseMetadata.getSecondaryIndexes(query.getCatalog());
List binNames = query.getPredicate().getBinNames();
if (!binNames.isEmpty() && indexes != null && !indexes.isEmpty()) {
List indexList = indexes.stream()
.filter(i -> i.getSet().equals(query.getTable()))
.sorted(secondaryIndexComparator())
.collect(Collectors.toList());
for (AerospikeSecondaryIndex index : indexList) {
if (binNames.contains(index.getBinName())) {
return Optional.of(index);
}
}
}
}
return Optional.empty();
}
private Pair queryResult(RecordSet recordSet, AerospikeQuery query) {
return new Pair<>(new AerospikeRecordResultSet(recordSet, statement, query.getCatalog(),
query.getTable(), filterColumns(query)), -1);
}
private Comparator secondaryIndexComparator() {
if (aerospikeVersion.isSIndexCardinalitySupported()) {
return Comparator.comparingInt(AerospikeSecondaryIndex::getBinValuesRatio);
}
return Comparator.comparing(AerospikeSecondaryIndex::getBinName);
}
private List filterColumns(AerospikeQuery query) {
if (query.isStar()) {
return columns;
}
return columns.stream()
.filter(c -> query.getColumns().contains(c.getName()))
.sorted(Comparator.comparing(c -> query.getColumns().indexOf(c.getName())))
.collect(Collectors.toList());
}
}