package com.netflix.astyanax.cql.reads;
import java.util.HashMap;
import java.util.Map;
import com.datastax.driver.core.ResultSet;
import com.datastax.driver.core.Row;
import com.datastax.driver.core.Statement;
import com.google.common.util.concurrent.ListenableFuture;
import com.netflix.astyanax.CassandraOperationType;
import com.netflix.astyanax.connectionpool.OperationResult;
import com.netflix.astyanax.connectionpool.exceptions.ConnectionException;
import com.netflix.astyanax.cql.CqlAbstractExecutionImpl;
import com.netflix.astyanax.cql.CqlKeyspaceImpl.KeyspaceContext;
import com.netflix.astyanax.cql.util.CFQueryContext;
import com.netflix.astyanax.cql.util.CqlTypeMapping;
import com.netflix.astyanax.query.ColumnCountQuery;
import com.netflix.astyanax.query.RowSliceColumnCountQuery;
/**
* Impl for {@link RowSliceColumnCountQuery} interface.
* Just like {@link ColumnCountQuery}, this class only manages the context for the query.
* The actual query statement is supplied from the {@link CqlRowSliceQueryImpl} class.
*
* Note that CQL3 treats columns as rows for certain schemas that contain clustering keys.
* Hence this class collapses all {@link ResultSet} rows with the same partition key into a single row
* when counting all unique rows.
*
* @author poberai
*
* @param <K>
*/
public class CqlRowSliceColumnCountQueryImpl<K> implements RowSliceColumnCountQuery<K> {
private final KeyspaceContext ksContext;
private final CFQueryContext<?,?> cfContext;
private final Statement query;
public CqlRowSliceColumnCountQueryImpl(KeyspaceContext ksCtx, CFQueryContext<?,?> cfCtx, Statement query) {
this.ksContext = ksCtx;
this.cfContext = cfCtx;
this.query = query;
}
@Override
public OperationResult<Map<K, Integer>> execute() throws ConnectionException {
return new InternalQueryExecutionImpl().execute();
}
@Override
public ListenableFuture<OperationResult<Map<K, Integer>>> executeAsync() throws ConnectionException {
return new InternalQueryExecutionImpl().executeAsync();
}
private class InternalQueryExecutionImpl extends CqlAbstractExecutionImpl<Map<K, Integer>> {
public InternalQueryExecutionImpl() {
super(ksContext, cfContext);
}
@Override
public CassandraOperationType getOperationType() {
return CassandraOperationType.GET_ROWS_SLICE;
}
@Override
public Statement getQuery() {
return query;
}
@SuppressWarnings("unchecked")
@Override
public Map<K, Integer> parseResultSet(ResultSet resultSet) {
Map<K, Integer> columnCountPerRow = new HashMap<K, Integer>();
for (Row row : resultSet.all()) {
K key = (K) CqlTypeMapping.getDynamicColumn(row, cf.getKeySerializer(), 0, cf);
Integer colCount = columnCountPerRow.get(key);
if (colCount == null) {
colCount = new Integer(0);
}
colCount = colCount.intValue() + 1;
columnCountPerRow.put(key, colCount);
}
return columnCountPerRow;
}
}
}