com.netflix.astyanax.cql.reads.CFRowSliceQueryGen Maven / Gradle / Ivy
package com.netflix.astyanax.cql.reads;
import static com.datastax.driver.core.querybuilder.QueryBuilder.desc;
import static com.datastax.driver.core.querybuilder.QueryBuilder.eq;
import static com.datastax.driver.core.querybuilder.QueryBuilder.gt;
import static com.datastax.driver.core.querybuilder.QueryBuilder.gte;
import static com.datastax.driver.core.querybuilder.QueryBuilder.lt;
import static com.datastax.driver.core.querybuilder.QueryBuilder.lte;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
import com.datastax.driver.core.Session;
import com.datastax.driver.core.querybuilder.QueryBuilder;
import com.datastax.driver.core.querybuilder.Select;
import com.datastax.driver.core.querybuilder.Select.Where;
import com.netflix.astyanax.cql.reads.model.CqlColumnSlice;
import com.netflix.astyanax.cql.schema.CqlColumnFamilyDefinitionImpl;
import com.netflix.astyanax.ddl.ColumnDefinition;
import com.netflix.astyanax.query.RowSliceQuery;
import com.netflix.astyanax.serializers.CompositeRangeBuilder.CompositeByteBufferRange;
import com.netflix.astyanax.serializers.CompositeRangeBuilder.RangeQueryOp;
import com.netflix.astyanax.serializers.CompositeRangeBuilder.RangeQueryRecord;
/**
* Base class that contains the utilities for generating queries for read operations via the
* {@link RowSliceQuery} class.
*
* Note that this class is just a place holder for some useful generic utilities.
* See {@link CFRowKeysQueryGen} and {@link CFRowRangeQueryGen} which are the 2 extending classes
* for functionality that actually supports the queries.
*
* @author poberai
*/
public class CFRowSliceQueryGen {
// Thread safe reference to the underlying session object. We need the session object to be able to "prepare" query statements
protected final AtomicReference sessionRef = new AtomicReference(null);
// the keyspace being queried. Used for all the underlying queries being generated
protected final String keyspace;
// the cf definition which helps extending classes construct the right query as per the schema
protected final CqlColumnFamilyDefinitionImpl cfDef;
// Other useful derivatives of the cf definition that are frequently used by query generators
protected final String partitionKeyCol;
protected final String[] allPrimayKeyCols;
protected final List clusteringKeyCols;
protected final List regularCols;
// Condition tracking whether the underlying schema uses composite columns. This is imp since it influences how
// a single Column (composite column) can be decomposed into it's individual components that form different parts of the query.
protected boolean isCompositeColumn;
// bind marker for generating the prepared statements
protected static final String BIND_MARKER = "?";
public CFRowSliceQueryGen(Session session, String keyspaceName, CqlColumnFamilyDefinitionImpl cfDefinition) {
this.keyspace = keyspaceName;
this.cfDef = cfDefinition;
this.sessionRef.set(session);
partitionKeyCol = cfDef.getPartitionKeyColumnDefinition().getName();
allPrimayKeyCols = cfDef.getAllPkColNames();
clusteringKeyCols = cfDef.getClusteringKeyColumnDefinitionList();
regularCols = cfDef.getRegularColumnDefinitionList();
isCompositeColumn = (clusteringKeyCols.size() > 1);
}
/**
*
* SOME BASIC UTILITY METHODS USED BY ALL THE ROW SLICE QUERY GENERATORS
*/
protected Select selectAllColumnsFromKeyspaceAndCF() {
Select.Selection select = QueryBuilder.select();
for (int i=0; i columnSlice) {
String clusteringKeyCol = clusteringKeyCols.get(0).getName();
if (!columnSlice.isRangeQuery()) {
return where;
}
if (columnSlice.getStartColumn() != null) {
where.and(gte(clusteringKeyCol, columnSlice.getStartColumn()));
}
if (columnSlice.getEndColumn() != null) {
where.and(lte(clusteringKeyCol, columnSlice.getEndColumn()));
}
if (columnSlice.getReversed()) {
where.orderBy(desc(clusteringKeyCol));
}
if (columnSlice.getLimit() != -1) {
where.limit(columnSlice.getLimit());
}
return where;
}
protected void bindWhereClauseForColumnRange(List