org.infinispan.client.hotrod.impl.query.RemoteQuery Maven / Gradle / Ivy
package org.infinispan.client.hotrod.impl.query;
import static org.infinispan.client.hotrod.impl.Util.await;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
import org.infinispan.client.hotrod.RemoteCache;
import org.infinispan.client.hotrod.exceptions.HotRodClientException;
import org.infinispan.client.hotrod.impl.InternalRemoteCache;
import org.infinispan.client.hotrod.logging.Log;
import org.infinispan.client.hotrod.logging.LogFactory;
import org.infinispan.commons.util.CloseableIterator;
import org.infinispan.commons.util.Closeables;
import org.infinispan.commons.util.concurrent.CompletableFutures;
import org.infinispan.protostream.SerializationContext;
import org.infinispan.query.dsl.QueryFactory;
import org.infinispan.query.dsl.QueryResult;
import org.infinispan.query.dsl.TotalHitCount;
import org.infinispan.query.dsl.impl.BaseQuery;
import org.infinispan.query.remote.client.impl.BaseQueryResponse;
/**
* @author [email protected]
* @since 6.0
*/
public final class RemoteQuery extends BaseQuery {
private static final Log log = LogFactory.getLog(RemoteQuery.class);
private final InternalRemoteCache, ?> cache;
private final SerializationContext serializationContext;
RemoteQuery(QueryFactory queryFactory, InternalRemoteCache, ?> cache, SerializationContext serializationContext,
String queryString) {
super(queryFactory, queryString);
this.cache = cache;
this.serializationContext = serializationContext;
}
RemoteQuery(QueryFactory queryFactory, InternalRemoteCache, ?> cache, SerializationContext serializationContext,
String queryString, Map namedParameters, String[] projection, long startOffset, int maxResults, boolean local) {
super(queryFactory, queryString, namedParameters, projection, startOffset, maxResults, local);
this.cache = cache;
this.serializationContext = serializationContext;
}
@Override
public void resetQuery() {
}
@Override
public List list() {
return awaitQueryResult(listAsync());
}
@Override
public QueryResult execute() {
return awaitQueryResult(executeAsync());
}
@Override
public int executeStatement() {
return awaitQueryResult(executeStatementAsync());
}
@Override
public CloseableIterator iterator() {
if (maxResults == -1 && startOffset == 0) {
log.warnPerfRemoteIterationWithoutPagination(queryString);
}
return Closeables.iterator(list().iterator());
}
@Override
public int getResultSize() {
return awaitQueryResult(executeRemotelyAsync(true)).hitCount();
}
public CompletionStage> executeAsync() {
return internalExecuteAsync().thenApply(CompletableFutures.identity());
}
public CompletionStage executeStatementAsync() {
return executeRemotelyAsync(false).thenApply(BaseQueryResponse::hitCount);
}
public CompletionStage> listAsync() {
return executeRemotelyAsync(false).thenApply(this::extractResults);
}
private CompletableFuture> executeRemotelyAsync(boolean withHitCount) {
validateNamedParameters();
return cache.getOperationsFactory()
.newQueryOperation(this, cache.getDataFormat(), withHitCount)
.execute();
}
/**
* Get the protobuf SerializationContext or {@code null} if we are not using protobuf.
*/
public SerializationContext getSerializationContext() {
return serializationContext;
}
public RemoteCache, ?> getCache() {
return cache;
}
private List extractResults(BaseQueryResponse response) {
try {
return response.extractResults(serializationContext);
} catch (IOException e) {
throw new HotRodClientException(e);
}
}
private R awaitQueryResult(CompletionStage rsp) {
return timeout == -1 ? await(rsp) : await(rsp.toCompletableFuture(), timeout);
}
private CompletionStage> internalExecuteAsync() {
return executeRemotelyAsync(true).thenApply(QueryResultAdapter::new);
}
@Override
public String toString() {
return "RemoteQuery{" +
"queryString=" + queryString +
", namedParameters=" + namedParameters +
", startOffset=" + startOffset +
", maxResults=" + maxResults +
", timeout=" + timeout +
'}';
}
private class QueryResultAdapter implements QueryResult {
private final BaseQueryResponse queryResponse;
QueryResultAdapter(BaseQueryResponse queryResponse) {
this.queryResponse = queryResponse;
}
@Override
public TotalHitCount count() {
return new TotalHitCount(queryResponse.hitCount(), queryResponse.hitCountExact());
}
@Override
public List list() {
return extractResults(queryResponse);
}
}
}