package com.netflix.astyanax.cql.reads.model; import java.util.Collection; import com.netflix.astyanax.model.ColumnSlice; import com.netflix.astyanax.query.RowQuery; /** * Impl for {@link ColumnSlice}. * * See {@link RowQuery} for where ColumnSlice can be used. There are essentially 2 components to a ColumnSLice * 1. Collection of Columns. * 2. Column range specification * * This class encapsulates data structures for both types of ColumnSlice(s). It also maintains state that helps identify * the type of query being performed. * * @author poberai * * @param <C> */ public class CqlColumnSlice<C> extends ColumnSlice<C> { private CqlRangeImpl<C> cqlRange; private Collection<C> cqlColumns; public CqlColumnSlice() { super(null, null); } public CqlColumnSlice(C startColumn, C endColumn) { super(null, null); } public CqlColumnSlice(CqlRangeImpl<C> cqlRange) { super(null, null); this.cqlRange = cqlRange; } public CqlColumnSlice(Collection<C> columns) { super(null, null); this.cqlColumns = columns; } public void setColumns(Collection<C> columns) { this.cqlColumns = columns; } public void setCqlRange(CqlRangeImpl<C> cqlRange) { this.cqlRange = cqlRange; } public CqlColumnSlice(ColumnSlice<C> columnSlice) { super(null, null); if (columnSlice instanceof CqlColumnSlice<?>) { initFrom(((CqlColumnSlice<C>)columnSlice)); } else { if (columnSlice.getColumns() != null) { this.cqlColumns = columnSlice.getColumns(); this.cqlRange = null; } else { // this is where the consumer is using the old style range query using the same code i.e no column name specified. // in this case we must assume the columnName = 'column1' which is the default chosen by CQL3 this.cqlColumns = null; this.cqlRange = new CqlRangeBuilder<C>() .setColumn("column1") .setStart(columnSlice.getStartColumn()) .setEnd(columnSlice.getEndColumn()) .setReversed(columnSlice.getReversed()) .setLimit(columnSlice.getLimit()) .build(); } } } public CqlColumnSlice(CqlColumnSlice<C> cqlColumnSlice) { super(null, null); initFrom(cqlColumnSlice); } private void initFrom(CqlColumnSlice<C> cqlColumnSlice) { this.cqlColumns = (Collection<C>) cqlColumnSlice.cqlColumns; this.cqlRange = cqlColumnSlice.cqlRange; } @Override public ColumnSlice<C> setLimit(int limit) { this.cqlRange = new CqlRangeBuilder<C>().withRange(cqlRange).setLimit(limit).build(); return this; } @Override public ColumnSlice<C> setReversed(boolean value) { this.cqlRange = new CqlRangeBuilder<C>().withRange(cqlRange).setReversed(value).build(); return this; } public String getColumnName() { return cqlRange.getColumnName(); } @Override public Collection<C> getColumns() { return cqlColumns; } @Override public C getStartColumn() { return (cqlRange != null) ? (C) cqlRange.getCqlStart() : null; } @Override public C getEndColumn() { return (cqlRange != null) ? (C) cqlRange.getCqlEnd() : null; } @Override public boolean getReversed() { return (cqlRange != null ) ? cqlRange.isReversed() : false; } @Override public int getLimit() { return (cqlRange != null ) ? cqlRange.getLimit() : -1; } public int getFetchSize() { return (cqlRange != null ) ? cqlRange.getFetchSize() : -1; } public boolean isColumnSelectQuery() { return (this.cqlColumns != null); } public boolean isRangeQuery() { if (isColumnSelectQuery()) { return false; } if (cqlRange != null) { return true; } return false; } public boolean isSelectAllQuery() { return (!isColumnSelectQuery() && !isRangeQuery()); } public static enum QueryType { SELECT_ALL, COLUMN_COLLECTION, COLUMN_RANGE; } public QueryType getQueryType() { if (isSelectAllQuery()) { return QueryType.SELECT_ALL; } else if (isRangeQuery()) { return QueryType.COLUMN_RANGE; } else { return QueryType.COLUMN_COLLECTION; } } }