package cassandra.cql.query;
import cassandra.cql.PagingState;
import java.util.LinkedList;
public class Select extends Query<Select> {
private Clause.Selection selection;
private Clause where;
private Sort sort;
private Limit limit;
private boolean allowFiltering;
Select(String keyspace, String table, Clause.Selection selection) {
this.keyspace = keyspace;
this.table = table;
this.selection = selection;
}
public boolean hasSelectionClause() {
return selection != null;
}
public Clause selectionClause() {
return selection;
}
public boolean hasWhereClause() {
return where != null;
}
public Clause whereClause() {
return where;
}
public Select where(Clause.Operator clause) {
if (clause == null) {
throw new NullPointerException("clause");
}
if (where == null) {
where = clause;
} else if (where instanceof Clause.And) {
((Clause.And)where).clauses().add(clause);
} else {
Clause.And and = new Clause.And();
and.clauses().add(where);
and.clauses().add(clause);
where = and;
}
return this;
}
public Select where(Clause.Operator... clauses) {
if (clauses == null) {
throw new NullPointerException("clauses");
}
for (Clause.Operator clause : clauses) {
where(clause);
}
return this;
}
public boolean hasSort() {
return sort != null && !sort.orders().isEmpty();
}
public Sort sort() {
return sort;
}
public Select orderBy(Order order) {
if (order == null) {
throw new NullPointerException("order");
}
if (sort == null) {
sort = new Sort();
}
sort.orders().add(order);
return this;
}
public Select orderBy(Order... orders) {
if (orders == null) {
throw new NullPointerException("orders");
}
for (Order order : orders) {
orderBy(order);
}
return this;
}
public boolean hasLimit() {
return limit != null && limit.count() >= 0;
}
public Limit limit() {
return limit;
}
public Select limit(int limit) {
if (limit < 0) {
throw new IllegalArgumentException(String.format("LIMIT: %d (expected: >= 0)", limit));
}
this.limit = new Limit(limit);
return this;
}
public Select pagingState(PagingState pagingState) {
this.pagingState = pagingState;
return this;
}
public boolean isAllowFiltering() {
return allowFiltering;
}
public Select allowFiltering() {
allowFiltering = true;
return this;
}
@Override
public void accept(QueryVisitor visitor) {
visitor.visit(this);
}
public static class Builder {
protected LinkedList<Clause.Selection.Selector> selectors;
protected boolean distinct;
public Select from(String table) {
return from(null, table);
}
public Select from(String keyspace, String table) {
if (table == null) {
throw new NullPointerException("table");
}
if (table.isEmpty()) {
throw new IllegalArgumentException("empty table");
}
Clause.Selection selection = null;
if (selectors != null && !selectors.isEmpty()) {
selection = new Clause.Selection(distinct, selectors.toArray(new Clause.Selection.Selector[selectors.size()]));
}
return new Select(keyspace, table, selection);
}
}
public static abstract class Selection extends Builder {
public Selection distinct() {
this.distinct = true;
return this;
}
public Select.Builder all() {
if (selectors != null && !selectors.isEmpty()) {
throw new IllegalStateException("column not empty");
}
return this;
}
public Select.Builder count() {
return count(null);
}
public Select.Builder count(String alias) {
if (selectors != null && !selectors.isEmpty()) {
throw new IllegalStateException("column not empty");
}
if (alias != null && !alias.isEmpty()) {
column("COUNT(*)").as(alias);
} else {
column("COUNT(*)");
}
distinct = false;
return this;
}
public abstract Selection.Builder column(String name);
public Selection.Builder ttl(String name) {
return column(functionAlias("TTL", name));
}
public Selection.Builder writeTime(String name) {
return column(functionAlias("WRITETIME", name));
}
public Selection.Builder dateOf(String name) {
return column(functionAlias("dateOf", name));
}
public Selection.Builder unixTimestampOf(String name) {
return column(functionAlias("unixTimestampOf", name));
}
public Selection.Builder token(String name) {
return column(functionAlias("token", name));
}
public Selection.Builder blobAsDecimal(String name) {
return column(functionAlias("blobAsDecimal", name));
}
public Selection.Builder minTimeuuid(String name) {
return column(functionAlias("minTimeuuid", name));
}
public Selection.Builder maxTimeuuid(String name) {
return column(functionAlias("maxTimeuuid", name));
}
public Selection.Builder blobAsAscii(String name) {
return column(functionAlias("blobAsAscii", name));
}
public Selection.Builder blobAsBigint(String name) {
return column(functionAlias("blobAsBigint", name));
}
public Selection.Builder blobAsBoolean(String name) {
return column(functionAlias("blobAsBoolean", name));
}
public Selection.Builder blobAsCounter(String name) {
return column(functionAlias("blobAsCounter", name));
}
public Selection.Builder blobAsDouble(String name) {
return column(functionAlias("blobAsDouble", name));
}
public Selection.Builder blobAsFloat(String name) {
return column(functionAlias("blobAsFloat", name));
}
public Selection.Builder blobAsInet(String name) {
return column(functionAlias("blobAsInet", name));
}
public Selection.Builder blobAsInt(String name) {
return column(functionAlias("blobAsInt", name));
}
public Selection.Builder blobAsText(String name) {
return column(functionAlias("blobAsText", name));
}
public Selection.Builder blobAsTimestamp(String name) {
return column(functionAlias("blobAsTimestamp", name));
}
public Selection.Builder blobAsUuid(String name) {
return column(functionAlias("blobAsUuid", name));
}
public Selection.Builder blobAsVarchar(String name) {
return column(functionAlias("blobAsVarchar", name));
}
public Selection.Builder blobAsVarint(String name) {
return column(functionAlias("blobAsVarint", name));
}
public Selection.Builder blobAsTimeUuid(String name) {
return column(functionAlias("blobAsTimeUuid", name));
}
public Selection.Builder asciiAsBlob(String name) {
return column(functionAlias("asciiAsBlob", name));
}
public Selection.Builder bigintAsBlob(String name) {
return column(functionAlias("bigintAsBlob", name));
}
public Selection.Builder booleanAsBlob(String name) {
return column(functionAlias("booleanAsBlob", name));
}
public Selection.Builder counterAsBlob(String name) {
return column(functionAlias("counterAsBlob", name));
}
public Selection.Builder decimalAsBlob(String name) {
return column(functionAlias("decimalAsBlob", name));
}
public Selection.Builder doubleAsBlob(String name) {
return column(functionAlias("doubleAsBlob", name));
}
public Selection.Builder floatAsBlob(String name) {
return column(functionAlias("floatAsBlob", name));
}
public Selection.Builder inetAsBlob(String name) {
return column(functionAlias("inetAsBlob", name));
}
public Selection.Builder intAsBlob(String name) {
return column(functionAlias("intAsBlob", name));
}
public Selection.Builder textAsBlob(String name) {
return column(functionAlias("textAsBlob", name));
}
public Selection.Builder timestampAsBlob(String name) {
return column(functionAlias("timestampAsBlob", name));
}
public Selection.Builder uuidAsBlob(String name) {
return column(functionAlias("uuidAsBlob", name));
}
public Selection.Builder varcharAsBlob(String name) {
return column(functionAlias("varcharAsBlob", name));
}
public Selection.Builder varintAsBlob(String name) {
return column(functionAlias("varintAsBlob", name));
}
public Selection.Builder timeUuidAsBlob(String name) {
return column(functionAlias("timeUuidAsBlob", name));
}
protected String functionAlias(String function, String name) {
return String.format("%s(%s)", function, name);
}
public static class Builder extends Selection {
public Selection.Builder column(String name) {
if (name == null) {
throw new NullPointerException("name");
}
if (name.isEmpty()) {
throw new IllegalArgumentException("empty name");
}
Clause.Selection.Selector selector = new Clause.Selection.Selector();
selector.name = name;
if (selectors == null) {
selectors = new LinkedList<Clause.Selection.Selector>();
}
selectors.addLast(selector);
return this;
}
public Selection as(String alias) {
if (alias == null) {
throw new NullPointerException("alias");
}
if (alias.isEmpty()) {
throw new IllegalArgumentException("empty alias");
}
Clause.Selection.Selector selector = selectors.getLast();
if (selector == null) {
throw new IllegalStateException("column is empty");
}
selector.alias = alias;
return this;
}
}
}
}