add a little sugar in code

This commit is contained in:
Albert Shift 2015-03-30 17:18:33 -07:00
parent 427cf4ab7a
commit af811228d9
13 changed files with 277 additions and 172 deletions

View file

@ -70,8 +70,8 @@ CasserSession session = Casser.init(getSession()).showCql().add(Timeline.class).
Select information: Select information:
``` ```
session.select(timeline::userId, timeline::timestamp, timeline::text) session.select(timeline::userId, timeline::timestamp, timeline::text)
.where(timeline::userId, Operator.EQ, userId) .where(timeline::userId, eq(userId))
.orderBy(timeline::timestamp, "desc").limit(5).sync() .orderBy(desc(timeline::timestamp)).limit(5).sync()
.forEach(System.out::println); .forEach(System.out::println);
``` ```

View file

@ -15,10 +15,11 @@
*/ */
package com.noorq.casser; package com.noorq.casser;
import static com.noorq.casser.core.Query.*;
import com.datastax.driver.core.Cluster; import com.datastax.driver.core.Cluster;
import com.noorq.casser.core.Casser; import com.noorq.casser.core.Casser;
import com.noorq.casser.core.CasserSession; import com.noorq.casser.core.CasserSession;
import com.noorq.casser.core.Filter;
import com.noorq.casser.core.Prepared; import com.noorq.casser.core.Prepared;
import com.noorq.casser.core.operation.SelectOperation; import com.noorq.casser.core.operation.SelectOperation;
import com.noorq.casser.core.tuple.Tuple1; import com.noorq.casser.core.tuple.Tuple1;
@ -86,23 +87,23 @@ public class Example {
newUser.age = 34; newUser.age = 34;
session.upsert(newUser); session.upsert(newUser);
String nameAndAge = session.select(user::name, user::age).where(user::id, "==", 100L).sync().findFirst().map(t -> { String nameAndAge = session.select(user::name, user::age).where(user::id, eq(100L)).sync().findFirst().map(t -> {
return t._1 + ":" + t._2; return t._1 + ":" + t._2;
}).get(); }).get();
User userTmp = session.select(user::name, user::age).where(user::id, "==", 100L).map(Example::mapUser).sync().findFirst().get(); User userTmp = session.select(user::name, user::age).where(user::id, eq(100L)).map(Example::mapUser).sync().findFirst().get();
session.update(user::age, 10).where(user::id, "==", 100L).async(); session.update(user::age, 10).where(user::id, eq(100L)).async();
session.delete(User.class).where(user::id, "==", 100L).async(); session.delete(User.class).where(user::id, eq(100L)).async();
Prepared<SelectOperation<Tuple1<String>>> ps = session.select(user::name).where(user::id, "==", null).prepare(); Prepared<SelectOperation<Tuple1<String>>> ps = session.select(user::name).where(user::id, "==", null).prepare();
long cnt = ps.bind(100L).sync().count(); long cnt = ps.bind(100L).sync().count();
cnt = session.select(user::name).where(user::id, "==", 100L).count().sync(); cnt = session.select(user::name).where(user::id, eq(100L)).count().sync();
cnt = session.select(user::name).where(Filter.equal(user::id, 100L)).count().sync(); cnt = session.select(user::name).where(user::id, eq(100L)).count().sync();
} }

View file

@ -18,7 +18,6 @@ package com.noorq.casser.core;
import java.util.Objects; import java.util.Objects;
import com.datastax.driver.core.querybuilder.Clause; import com.datastax.driver.core.querybuilder.Clause;
import com.datastax.driver.core.querybuilder.QueryBuilder;
import com.noorq.casser.core.reflect.CasserPropertyNode; import com.noorq.casser.core.reflect.CasserPropertyNode;
import com.noorq.casser.mapping.CasserMappingProperty; import com.noorq.casser.mapping.CasserMappingProperty;
import com.noorq.casser.mapping.MappingUtil; import com.noorq.casser.mapping.MappingUtil;
@ -28,67 +27,29 @@ import com.noorq.casser.support.CasserMappingException;
public final class Filter<V> { public final class Filter<V> {
private final CasserMappingProperty property; private final CasserMappingProperty property;
private final Operator operation; private final Postulate<V> postulate;
private final V value;
private final V[] values;
private Filter(CasserMappingProperty prop, Operator op, V value) { private Filter(CasserMappingProperty prop, Operator op, V value) {
this.property = prop; this.property = prop;
this.operation = op; this.postulate = new Postulate<V>(op, value);
this.value = value;
this.values = null;
} }
private Filter(CasserMappingProperty prop, Operator op, V[] values) { private Filter(CasserMappingProperty prop, Operator op, V[] values) {
this.property = prop; this.property = prop;
this.operation = op; this.postulate = new Postulate<V>(op, values);
this.value = null; }
this.values = values;
private Filter(CasserMappingProperty prop, Postulate<V> postulate) {
this.property = prop;
this.postulate = postulate;
} }
public CasserMappingProperty getProperty() { public CasserMappingProperty getProperty() {
return property; return property;
} }
public Operator getOperation() {
return operation;
}
public V getValue() {
return value;
}
public Clause getClause(ColumnValuePreparer valuePreparer) { public Clause getClause(ColumnValuePreparer valuePreparer) {
return postulate.getClause(property, valuePreparer);
switch(operation) {
case EQ:
return QueryBuilder.eq(property.getColumnName(),
valuePreparer.prepareColumnValue(value, property));
case IN:
Object[] preparedValues = new Object[values.length];
for (int i = 0; i != values.length; ++i) {
preparedValues[i] = valuePreparer.prepareColumnValue(values[i], property);
}
return QueryBuilder.in(property.getColumnName(), preparedValues);
case LT:
return QueryBuilder.lt(property.getColumnName(), valuePreparer.prepareColumnValue(value, property));
case LTE:
return QueryBuilder.lte(property.getColumnName(), valuePreparer.prepareColumnValue(value, property));
case GT:
return QueryBuilder.gt(property.getColumnName(), valuePreparer.prepareColumnValue(value, property));
case GTE:
return QueryBuilder.gte(property.getColumnName(), valuePreparer.prepareColumnValue(value, property));
default:
throw new CasserMappingException("unknown filter operation " + operation);
}
} }
public static <V> Filter<V> equal(Getter<V> getter, V val) { public static <V> Filter<V> equal(Getter<V> getter, V val) {
@ -112,22 +73,31 @@ public final class Filter<V> {
return new Filter<V>(prop.getProperty(), Operator.IN, vals); return new Filter<V>(prop.getProperty(), Operator.IN, vals);
} }
public static <V> Filter<V> greater(Getter<V> getter, V val) { public static <V> Filter<V> greaterThan(Getter<V> getter, V val) {
return create(getter, Operator.GT, val); return create(getter, Operator.GT, val);
} }
public static <V> Filter<V> less(Getter<V> getter, V val) { public static <V> Filter<V> lessThan(Getter<V> getter, V val) {
return create(getter, Operator.LT, val); return create(getter, Operator.LT, val);
} }
public static <V> Filter<V> greaterOrEqual(Getter<V> getter, V val) { public static <V> Filter<V> greaterThanOrEqual(Getter<V> getter, V val) {
return create(getter, Operator.GTE, val); return create(getter, Operator.GTE, val);
} }
public static <V> Filter<V> lessOrEqual(Getter<V> getter, V val) { public static <V> Filter<V> lessThanOrEqual(Getter<V> getter, V val) {
return create(getter, Operator.LTE, val); return create(getter, Operator.LTE, val);
} }
public static <V> Filter<V> create(Getter<V> getter, Postulate<V> postulate) {
Objects.requireNonNull(getter, "empty getter");
Objects.requireNonNull(postulate, "empty operator");
CasserPropertyNode prop = MappingUtil.resolveMappingProperty(getter);
return new Filter<V>(prop.getProperty(), postulate);
}
public static <V> Filter<V> create(Getter<V> getter, String operator, V val) { public static <V> Filter<V> create(Getter<V> getter, String operator, V val) {
Objects.requireNonNull(operator, "empty operator"); Objects.requireNonNull(operator, "empty operator");

View file

@ -0,0 +1,46 @@
package com.noorq.casser.core;
import java.util.Objects;
import com.datastax.driver.core.querybuilder.Ordering;
import com.datastax.driver.core.querybuilder.QueryBuilder;
import com.noorq.casser.core.reflect.CasserPropertyNode;
import com.noorq.casser.mapping.MappingUtil;
import com.noorq.casser.mapping.OrderingDirection;
import com.noorq.casser.support.CasserMappingException;
public final class Ordered {
private final Getter<?> getter;
private final OrderingDirection direction;
public Ordered(Getter<?> getter, OrderingDirection direction) {
this.getter = getter;
this.direction = direction;
}
public Ordering getOrdering() {
Objects.requireNonNull(getter, "property is null");
Objects.requireNonNull(direction, "direction is null");
CasserPropertyNode propNode = MappingUtil.resolveMappingProperty(getter);
if (!propNode.getProperty().isClusteringColumn()) {
throw new CasserMappingException("property must be a clustering column " + propNode.getProperty().getPropertyName());
}
switch(direction) {
case ASC:
return QueryBuilder.asc(propNode.getColumnName());
case DESC:
return QueryBuilder.desc(propNode.getColumnName());
}
throw new CasserMappingException("invalid direction " + direction);
}
}

View file

@ -0,0 +1,83 @@
/*
* Copyright (C) 2015 Noorq, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.noorq.casser.core;
import com.datastax.driver.core.querybuilder.Clause;
import com.datastax.driver.core.querybuilder.QueryBuilder;
import com.noorq.casser.mapping.CasserMappingProperty;
import com.noorq.casser.mapping.value.ColumnValuePreparer;
import com.noorq.casser.support.CasserMappingException;
public final class Postulate<V> {
private final Operator operator;
private final V value;
private final V[] values;
protected Postulate(Operator op, V value) {
this.operator = op;
this.value = value;
this.values = null;
if (op == Operator.IN) {
throw new IllegalArgumentException("invalid usage of the 'in' operator");
}
}
protected Postulate(Operator op, V[] values) {
this.operator = op;
this.value = null;
this.values = values;
if (op != Operator.IN) {
throw new IllegalArgumentException("invalid usage of the non 'in' operator");
}
}
public Clause getClause(CasserMappingProperty property, ColumnValuePreparer valuePreparer) {
switch(operator) {
case EQ:
return QueryBuilder.eq(property.getColumnName(),
valuePreparer.prepareColumnValue(value, property));
case IN:
Object[] preparedValues = new Object[values.length];
for (int i = 0; i != values.length; ++i) {
preparedValues[i] = valuePreparer.prepareColumnValue(values[i], property);
}
return QueryBuilder.in(property.getColumnName(), preparedValues);
case LT:
return QueryBuilder.lt(property.getColumnName(), valuePreparer.prepareColumnValue(value, property));
case LTE:
return QueryBuilder.lte(property.getColumnName(), valuePreparer.prepareColumnValue(value, property));
case GT:
return QueryBuilder.gt(property.getColumnName(), valuePreparer.prepareColumnValue(value, property));
case GTE:
return QueryBuilder.gte(property.getColumnName(), valuePreparer.prepareColumnValue(value, property));
default:
throw new CasserMappingException("unknown filter operation " + operator);
}
}
}

View file

@ -0,0 +1,75 @@
/*
* Copyright (C) 2015 Noorq, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.noorq.casser.core;
import java.util.List;
import java.util.Map;
import com.noorq.casser.mapping.OrderingDirection;
/**
* Sugar methods for the queries
*
*/
public final class Query {
private Query() {
}
public static Ordered asc(Getter<?> getter) {
return new Ordered(getter, OrderingDirection.ASC);
}
public static Ordered desc(Getter<?> getter) {
return new Ordered(getter, OrderingDirection.DESC);
}
public static <V> Postulate<V> eq(V val) {
return new Postulate<V>(Operator.EQ, val);
}
public static <V> Postulate<V> lt(V val) {
return new Postulate<V>(Operator.LT, val);
}
public static <V> Postulate<V> lte(V val) {
return new Postulate<V>(Operator.LTE, val);
}
public static <V> Postulate<V> gt(V val) {
return new Postulate<V>(Operator.GT, val);
}
public static <V> Postulate<V> gte(V val) {
return new Postulate<V>(Operator.GTE, val);
}
public static <V> Postulate<V> in(Getter<V> getter, V[] vals) {
return new Postulate<V>(Operator.IN, vals);
}
public static <K,V> Getter<V> get(Getter<List<V>> listGetter, int index) {
return null;
}
public static <K,V> Getter<V> get(Getter<Map<K, V>> mapGetter, K k) {
return null;
}
}

View file

@ -1,31 +0,0 @@
/*
* Copyright (C) 2015 Noorq, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.noorq.casser.core.collection;
import java.util.List;
import com.noorq.casser.core.Getter;
public final class CList {
private CList() {
}
public static <K,V> Getter<V> get(Getter<List<V>> listGetter, int index) {
return null;
}
}

View file

@ -1,31 +0,0 @@
/*
* Copyright (C) 2015 Noorq, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.noorq.casser.core.collection;
import java.util.Map;
import com.noorq.casser.core.Getter;
public final class CMap {
private CMap() {
}
public static <K,V> Getter<V> get(Getter<Map<K, V>> mapGetter, K k) {
return null;
}
}

View file

@ -1,27 +0,0 @@
/*
* Copyright (C) 2015 Noorq, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.noorq.casser.core.collection;
import java.util.List;
import com.noorq.casser.core.Getter;
public final class CSet {
private CSet() {
}
}

View file

@ -22,6 +22,7 @@ import com.noorq.casser.core.AbstractSessionOperations;
import com.noorq.casser.core.Filter; import com.noorq.casser.core.Filter;
import com.noorq.casser.core.Getter; import com.noorq.casser.core.Getter;
import com.noorq.casser.core.Operator; import com.noorq.casser.core.Operator;
import com.noorq.casser.core.Postulate;
public abstract class AbstractFilterOperation<E, O extends AbstractFilterOperation<E, O>> extends AbstractEntityOperation<E, O> { public abstract class AbstractFilterOperation<E, O extends AbstractFilterOperation<E, O>> extends AbstractEntityOperation<E, O> {
@ -31,6 +32,14 @@ public abstract class AbstractFilterOperation<E, O extends AbstractFilterOperati
super(sessionOperations); super(sessionOperations);
} }
public <V> O where(Getter<V> getter, Postulate<V> postulate) {
addFilter(Filter.create(getter, postulate));
return (O) this;
}
public <V> O where(Getter<V> getter, String operator, V val) { public <V> O where(Getter<V> getter, String operator, V val) {
addFilter(Filter.create(getter, operator, val)); addFilter(Filter.create(getter, operator, val));
@ -52,6 +61,13 @@ public abstract class AbstractFilterOperation<E, O extends AbstractFilterOperati
return (O) this; return (O) this;
} }
public <V> O add(Getter<V> getter, Postulate<V> postulate) {
addFilter(Filter.create(getter, postulate));
return (O) this;
}
public <V> O and(Getter<V> getter, String operator, V val) { public <V> O and(Getter<V> getter, String operator, V val) {
addFilter(Filter.create(getter, operator, val)); addFilter(Filter.create(getter, operator, val));

View file

@ -22,6 +22,7 @@ import com.noorq.casser.core.AbstractSessionOperations;
import com.noorq.casser.core.Filter; import com.noorq.casser.core.Filter;
import com.noorq.casser.core.Getter; import com.noorq.casser.core.Getter;
import com.noorq.casser.core.Operator; import com.noorq.casser.core.Operator;
import com.noorq.casser.core.Postulate;
public abstract class AbstractFilterStreamOperation<E, O extends AbstractFilterStreamOperation<E, O>> extends AbstractStreamOperation<E, O> { public abstract class AbstractFilterStreamOperation<E, O extends AbstractFilterStreamOperation<E, O>> extends AbstractStreamOperation<E, O> {
@ -31,6 +32,13 @@ public abstract class AbstractFilterStreamOperation<E, O extends AbstractFilterS
super(sessionOperations); super(sessionOperations);
} }
public <V> O where(Getter<V> getter, Postulate<V> postulate) {
addFilter(Filter.create(getter, postulate));
return (O) this;
}
public <V> O where(Getter<V> getter, String operator, V val) { public <V> O where(Getter<V> getter, String operator, V val) {
addFilter(Filter.create(getter, operator, val)); addFilter(Filter.create(getter, operator, val));
@ -52,6 +60,13 @@ public abstract class AbstractFilterStreamOperation<E, O extends AbstractFilterS
return (O) this; return (O) this;
} }
public <V> O add(Getter<V> getter, Postulate<V> postulate) {
addFilter(Filter.create(getter, postulate));
return (O) this;
}
public <V> O and(Getter<V> getter, String operator, V val) { public <V> O and(Getter<V> getter, String operator, V val) {
addFilter(Filter.create(getter, operator, val)); addFilter(Filter.create(getter, operator, val));

View file

@ -35,10 +35,9 @@ import com.datastax.driver.core.querybuilder.Select.Where;
import com.noorq.casser.core.AbstractSessionOperations; import com.noorq.casser.core.AbstractSessionOperations;
import com.noorq.casser.core.Filter; import com.noorq.casser.core.Filter;
import com.noorq.casser.core.Getter; import com.noorq.casser.core.Getter;
import com.noorq.casser.core.Ordered;
import com.noorq.casser.core.reflect.CasserPropertyNode; import com.noorq.casser.core.reflect.CasserPropertyNode;
import com.noorq.casser.mapping.CasserMappingEntity; import com.noorq.casser.mapping.CasserMappingEntity;
import com.noorq.casser.mapping.CasserMappingProperty;
import com.noorq.casser.mapping.MappingUtil;
import com.noorq.casser.mapping.OrderingDirection; import com.noorq.casser.mapping.OrderingDirection;
import com.noorq.casser.support.CasserMappingException; import com.noorq.casser.support.CasserMappingException;
@ -87,25 +86,13 @@ public final class SelectOperation<E> extends AbstractFilterStreamOperation<E, S
} }
public SelectOperation<E> orderBy(Getter<?> getter, OrderingDirection direction) { public SelectOperation<E> orderBy(Getter<?> getter, OrderingDirection direction) {
Objects.requireNonNull(getter, "property is null"); getOrCreateOrdering().add(new Ordered(getter, direction).getOrdering());
Objects.requireNonNull(direction, "direction is null"); return this;
}
CasserPropertyNode propNode = MappingUtil.resolveMappingProperty(getter);
public SelectOperation<E> orderBy(Ordered ordered) {
if (!propNode.getProperty().isClusteringColumn()) { getOrCreateOrdering().add(ordered.getOrdering());
throw new CasserMappingException("property must be a clustering column " + propNode.getProperty().getPropertyName()); return this;
}
switch(direction) {
case ASC:
getOrCreateOrdering().add(QueryBuilder.asc(propNode.getColumnName()));
return this;
case DESC:
getOrCreateOrdering().add(QueryBuilder.desc(propNode.getColumnName()));
return this;
}
throw new CasserMappingException("unknown ordering direction " + direction);
} }
public SelectOperation<E> limit(Integer limit) { public SelectOperation<E> limit(Integer limit) {

View file

@ -24,6 +24,7 @@ import org.junit.Test;
import com.noorq.casser.core.Casser; import com.noorq.casser.core.Casser;
import com.noorq.casser.core.CasserSession; import com.noorq.casser.core.CasserSession;
import static com.noorq.casser.core.Query.*;
import com.noorq.casser.support.Mutable; import com.noorq.casser.support.Mutable;
import com.noorq.casser.test.integration.build.AbstractEmbeddedCassandraTest; import com.noorq.casser.test.integration.build.AbstractEmbeddedCassandraTest;
@ -89,7 +90,7 @@ public class CompondKeyTest extends AbstractEmbeddedCassandraTest {
session.select(timeline::userId, timeline::timestamp, timeline::text) session.select(timeline::userId, timeline::timestamp, timeline::text)
.where(timeline::userId, "==", userId) .where(timeline::userId, "==", userId)
.orderBy(timeline::timestamp, "desc").limit(5).sync() .orderBy(desc(timeline::timestamp)).limit(5).sync()
.forEach(t -> { .forEach(t -> {
//System.out.println(t); //System.out.println(t);