added optimization for like usage

This commit is contained in:
Timo Westkämper 2009-03-12 11:53:45 +00:00
parent bc9e254cdd
commit 91e910efa5
7 changed files with 46 additions and 17 deletions

View File

@ -1,6 +1,10 @@
/*
* Copyright (c) 2009 Mysema Ltd.
* All rights reserved.
*
*/
package com.mysema.query.collections.utils;
import java.lang.reflect.InvocationTargetException;
import java.util.List;
import org.codehaus.janino.ExpressionEvaluator;
@ -17,14 +21,6 @@ import com.mysema.query.grammar.types.Expr;
*/
public class EvaluatorUtils {
public static <T> T evaluate(ExpressionEvaluator ev, Object... args){
try {
return (T) ev.evaluate(args);
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
}
}
public static ExpressionEvaluator create(JavaOps ops, List<Expr<?>> sources, Expr<?> expr){
try {
return new JavaSerializer(ops).handle(expr).createExpressionEvaluator(sources, expr);

View File

@ -1,5 +1,11 @@
/*
* Copyright (c) 2009 Mysema Ltd.
* All rights reserved.
*
*/
package com.mysema.query.collections.utils;
import java.lang.reflect.InvocationTargetException;
import java.util.Iterator;
import java.util.List;
@ -13,12 +19,20 @@ import com.mysema.query.grammar.types.Expr;
import com.mysema.query.grammar.types.Expr.EBoolean;
/**
* Util provides
* QueryIteratorUtils provides
*
* @author tiwe
* @version $Id$
*/
public class QueryIteratorUtils {
public static <T> T evaluate(ExpressionEvaluator ev, Object... args){
try {
return (T) ev.evaluate(args);
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
}
}
public static <S> Iterator<S> multiArgFilter(JavaOps ops, Iterator<S> source, List<Expr<?>> sources, EBoolean condition){
ExpressionEvaluator ev = EvaluatorUtils.create(ops, sources, condition);
@ -28,7 +42,7 @@ public class QueryIteratorUtils {
private static <S> Iterator<S> multiArgFilter(Iterator<S> source, final ExpressionEvaluator ev){
return IteratorUtils.filteredIterator(source, new Predicate<S>(){
public boolean evaluate(S object) {
return EvaluatorUtils.<Boolean>evaluate(ev, (Object[])object);
return QueryIteratorUtils.<Boolean>evaluate(ev, (Object[])object);
}
});
}
@ -41,7 +55,7 @@ public class QueryIteratorUtils {
private static <S,T> Iterator<T> project(Iterator<S> source, final ExpressionEvaluator ev){
return IteratorUtils.transformedIterator(source, new Transformer<S,T>(){
public T transform(S input) {
return EvaluatorUtils.<T>evaluate(ev, (Object[])input);
return QueryIteratorUtils.<T>evaluate(ev, (Object[])input);
}
});
}
@ -49,7 +63,7 @@ public class QueryIteratorUtils {
public static <S> Iterator<S> singleArgFilter(Iterator<S> source, final ExpressionEvaluator ev){
return IteratorUtils.filteredIterator(source, new Predicate<S>(){
public boolean evaluate(S object) {
return EvaluatorUtils.<Boolean>evaluate(ev, object);
return QueryIteratorUtils.<Boolean>evaluate(ev, object);
}
});
}

View File

@ -7,6 +7,7 @@ package com.mysema.query.grammar;
import java.util.List;
import com.mysema.query.grammar.Ops;
import com.mysema.query.grammar.Ops.Op;
import com.mysema.query.grammar.types.Expr;
import com.mysema.query.grammar.types.Path;

View File

@ -59,7 +59,7 @@ public class JavaOps extends OperationPatterns {
add(Ops.LAST_INDEX_2ARGS, "%s.lastIndex(%s)");
add(Ops.LAST_INDEX, "%s.lastIndex(%s,%s)");
add(Ops.ISEMPTY, "%s.isEmpty()");
add(Ops.STARTSWITH, "%s.startsWith(%s)");
add(Ops.STARTSWITH, "%s.startsWith(%s, 0)");
add(Ops.INDEXOF_2ARGS, "%s.indexOf(%s,%s)");
add(Ops.INDEXOF, "%s.indexOf(%s)");
add(Ops.EQ_IGNORECASE, "%s.equalsIgnoreCase(%s)");
@ -95,7 +95,7 @@ public class JavaOps extends OperationPatterns {
}
public static boolean like(String source, String pattern){
return Pattern.compile(pattern.replace("%", ".*")).matcher(source).matches();
return Pattern.compile(pattern.replace("%", ".*").replace("_",".")).matcher(source).matches();
}
}

View File

@ -207,7 +207,20 @@ public class JavaSerializer extends BaseSerializer<JavaSerializer>{
@Override
protected void visitOperation(Class<?> type, Op<?> operator, Expr<?>... args) {
if (operator.equals(Ops.STRING_CAST)){
if (operator.equals(Ops.LIKE)){
String right = args[1].toString();
if (!right.contains("_")){
int lastIndex = right.lastIndexOf('%');
if (lastIndex == right.length() -1){
operator = Ops.STARTSWITH;
args[1] = new Expr.EConstant<String>(right.substring(0, lastIndex));
}else if (lastIndex == 0){
operator = Ops.ENDSWITH;
args[1] = new Expr.EConstant<String>(right.substring(1));
}
}
super.visitOperation(type, operator, args);
}else if (operator.equals(Ops.STRING_CAST)){
visitCast(operator, args[0], String.class);
}else if (operator.equals(Ops.NUMCAST)){
visitCast(operator, args[0], (Class<?>) ((EConstant<?>)args[1]).getConstant());

View File

@ -1,3 +1,8 @@
/*
* Copyright (c) 2009 Mysema Ltd.
* All rights reserved.
*
*/
package com.mysema.query;
import java.math.BigDecimal;

View File

@ -85,7 +85,7 @@ public class FilteredJavaSerializerTest {
@Test
public void test14(){
assertMatches1Expr("true && true", cat.name.ne(otherCat.name).and(otherCat.name.like("Kate5%")));
assertMatches1Expr("true && com.mysema.query.grammar.JavaOps.like(cat.getName(),a1)", otherCat.name.ne(cat.name).and(cat.name.like("Kate5%")));
assertMatches1Expr("true && cat.getName().startsWith(a1, 0)", otherCat.name.ne(cat.name).and(cat.name.like("Kate5%")));
}
private void assertMatches1Expr(String expected, EBoolean where) {