package cassandra.cql;
import cassandra.CassandraSession;
import cassandra.protocol.CassandraMessage;
import java.nio.ByteBuffer;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
public class ResultSet implements Iterator<Row>, Iterable<Row> {
public static final ResultSet EMPTY_RESULT_SET = new ResultSet(null, null, new ArrayDeque<List<ByteBuffer>>(0), null, null);
private final AtomicReference<ByteBuffer> pagingState;
private final AbstractStatement<?> statement;
private final Queue<List<ByteBuffer>> rows;
private final List<Trace> traces;
private Trace lastTrace;
private RowMetadata metadata;
private boolean autoPaging;
ResultSet(AbstractStatement<?> statement, RowMetadata metadata, Queue<List<ByteBuffer>> rows, ByteBuffer pagingState, UUID tracingId) {
this.pagingState = new AtomicReference<ByteBuffer>(pagingState);
this.statement = statement;
this.rows = rows;
this.metadata = metadata;
autoPaging = true;
if (tracingId != null) {
Trace trace = new Trace(statement.getSession(), tracingId);
traces = new ArrayList<Trace>();
traces.add(trace);
lastTrace = trace;
} else {
traces = Collections.emptyList();
}
}
public RowMetadata getMetadata() {
return metadata;
}
public boolean isAutoPaging() {
return autoPaging;
}
public ResultSet setAutoPaging(boolean autoPaging) {
this.autoPaging = autoPaging;
return this;
}
public boolean hasMorePages() {
return pagingState.get() != null;
}
public boolean hasRoutingKey() {
return statement.hasRoutingKey();
}
public PagingState getPagingState() {
ByteBuffer pagingState = this.pagingState.get();
if (pagingState == null) {
return null;
}
return PagingState.copyFrom(pagingState);
}
public boolean hasTraces() {
return !traces.isEmpty();
}
public List<Trace> getTraces() {
return traces;
}
public Trace getLastTrace() {
return lastTrace;
}
public List<Row> asList() {
List<Row> list = new ArrayList<Row>(rows.size());
for (Row row : this) {
list.add(row);
}
return list;
}
public void queryNext() {
if (!hasMorePages()) {
return;
}
CassandraMessage.QueryParameters queryParameters = new CassandraMessage.QueryParameters(statement.getConsistency(),
statement.getParameters(),
metadata != null,
statement.getPageSizeLimit(),
pagingState.getAndSet(null),
statement.getSerialConsistency());
CassandraSession.ResultFuture future = statement.getSession().executeAsync(statement, queryParameters);
CassandraMessage.Result result = future.get();
if (result.hasTracingId()) {
Trace trace = new Trace(statement.getSession(), result.getTracingId());
traces.add(trace);
lastTrace = trace;
}
switch (result.kind) {
case ROWS:
CassandraMessage.Result.Rows resultRows = (CassandraMessage.Result.Rows)result;
rows.addAll(resultRows.rows);
if (metadata == null && resultRows.metadata.columns != null) {
metadata = new RowMetadata(resultRows.metadata.columns);
}
pagingState.set(resultRows.metadata.pagingState);
break;
default:
break;
}
}
@Override
public Iterator<Row> iterator() {
return this;
}
@Override
public boolean hasNext() {
if (!rows.isEmpty()) {
return true;
}
if (!autoPaging) {
return false;
}
queryNext();
return !rows.isEmpty();
}
@Override
public Row next() {
if (!hasNext()) {
return null;
}
return new Row(getMetadata(), rows.poll());
}
@Override
public void remove() {
throw new UnsupportedOperationException();
}
}