mirror of
https://github.com/querydsl/querydsl.git
synced 2026-06-13 21:01:01 +08:00
#94 fixed JPA substring handling
This commit is contained in:
parent
433fa77327
commit
3ca2dbcc2c
@ -18,6 +18,8 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
@ -46,7 +48,9 @@ import com.mysema.query.types.Visitor;
|
||||
public abstract class SerializerBase<S extends SerializerBase<S>> implements Visitor<Void,Void> {
|
||||
|
||||
private final StringBuilder builder = new StringBuilder();
|
||||
|
||||
|
||||
private static final Pattern OPERATION = Pattern.compile("\\d+[\\+\\-]\\d+");
|
||||
|
||||
private String constantPrefix = "a";
|
||||
|
||||
private String paramPrefix = "p";
|
||||
@ -61,6 +65,32 @@ public abstract class SerializerBase<S extends SerializerBase<S>> implements Vis
|
||||
private final Templates templates;
|
||||
|
||||
private final boolean dry;
|
||||
|
||||
private boolean normalize = true;
|
||||
|
||||
public static final String normalize(String queryString) {
|
||||
StringBuilder rv = new StringBuilder();
|
||||
Matcher m = OPERATION.matcher(queryString);
|
||||
int end = 0;
|
||||
while (m.find()) {
|
||||
if (m.start() > end) {
|
||||
rv.append(queryString.subSequence(end, m.start()));
|
||||
}
|
||||
String str = queryString.substring(m.start(), m.end());
|
||||
String[] operands = str.split("[\\+\\-]");
|
||||
char operator = str.charAt(operands[0].length());
|
||||
if (operator == '+') {
|
||||
rv.append(Integer.valueOf(operands[0]) + Integer.valueOf(operands[1]));
|
||||
} else {
|
||||
rv.append(Integer.valueOf(operands[0]) - Integer.valueOf(operands[1]));
|
||||
}
|
||||
end = m.end();
|
||||
}
|
||||
if (end < queryString.length()) {
|
||||
rv.append(queryString.substring(end));
|
||||
}
|
||||
return rv.toString();
|
||||
}
|
||||
|
||||
public SerializerBase(Templates templates) {
|
||||
this(templates, false);
|
||||
@ -171,10 +201,18 @@ public abstract class SerializerBase<S extends SerializerBase<S>> implements Vis
|
||||
public void setAnonParamPrefix(String prefix){
|
||||
this.anonParamPrefix = prefix;
|
||||
}
|
||||
|
||||
public void setNormalize(boolean normalize) {
|
||||
this.normalize = normalize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return builder.toString();
|
||||
if (normalize) {
|
||||
return normalize(builder.toString());
|
||||
} else {
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -256,6 +256,7 @@ public class MatchingFiltersFactory {
|
||||
|
||||
if (module != Module.LUCENE){
|
||||
rv.add(expr.substring(0,1).eq(other.substring(0,1)));
|
||||
rv.add(expr.substring(1,2).eq(other.substring(1,2)));
|
||||
rv.add(expr.substring(1).eq(other.substring(1)));
|
||||
|
||||
rv.add(expr.trim().eq(other.trim()));
|
||||
|
||||
@ -0,0 +1,15 @@
|
||||
package com.mysema.query.support;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
public class SerializerBaseTest {
|
||||
|
||||
@Test
|
||||
public void Normalize() {
|
||||
assertEquals("3", SerializerBase.normalize("1+2"));
|
||||
assertEquals("where 3 = 3", SerializerBase.normalize("where 1+2 = 3"));
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,6 +1,6 @@
|
||||
----------------------------------------------------------------
|
||||
Sat Jan 14 19:25:17 EET 2012:
|
||||
Booting Derby version The Apache Software Foundation - Apache Derby - 10.8.2.2 - (1181258): instance a816c00e-0134-dd40-7974-000002cca5a0
|
||||
Sat Feb 04 17:45:33 EET 2012:
|
||||
Booting Derby version The Apache Software Foundation - Apache Derby - 10.8.2.2 - (1181258): instance a816c00e-0135-490a-b7a3-000002be71c0
|
||||
on database directory /home/tiwe/work/querydsl/querydsl-jpa/target/derbydb with class loader sun.misc.Launcher$AppClassLoader@1a16869
|
||||
Loaded from file:/home/tiwe/.m2/repository/org/apache/derby/derby/10.8.2.2/derby-10.8.2.2.jar
|
||||
java.vendor=Sun Microsystems Inc.
|
||||
|
||||
@ -15,7 +15,6 @@ package com.mysema.query.jpa;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import com.mysema.query.types.Constant;
|
||||
import com.mysema.query.types.Operator;
|
||||
import com.mysema.query.types.OperatorImpl;
|
||||
import com.mysema.query.types.Ops;
|
||||
@ -74,12 +73,12 @@ public class JPQLTemplates extends Templates {
|
||||
add(Ops.MATCHES, "{0} like {1} escape '\\'", 27); // TODO : support real regexes
|
||||
add(Ops.MATCHES_IC, "{0} like {1} escape '\\'", 27); // TODO : support real regexes
|
||||
add(Ops.LOWER, "lower({0})");
|
||||
add(Ops.SUBSTR_1ARG, "substring({0},{1}+1)");
|
||||
add(Ops.SUBSTR_2ARGS, "substring({0},{1}+1,{2})");
|
||||
add(Ops.SUBSTR_1ARG, "substring({0},{1s}+1)");
|
||||
add(Ops.SUBSTR_2ARGS, "substring({0},{1s}+1,{2s}-{1s})");
|
||||
add(Ops.TRIM, "trim({0})");
|
||||
add(Ops.UPPER, "upper({0})");
|
||||
add(Ops.EQ_IGNORE_CASE, "{0l} = {1l}");
|
||||
add(Ops.CHAR_AT, "cast(substring({0},{1}+1,1) as char)");
|
||||
add(Ops.CHAR_AT, "cast(substring({0},{1s}+1,1) as char)");
|
||||
add(Ops.STRING_IS_EMPTY, "length({0}) = 0");
|
||||
|
||||
add(Ops.STRING_CONTAINS, "{0} like {%1%} escape '\\'");
|
||||
@ -89,7 +88,7 @@ public class JPQLTemplates extends Templates {
|
||||
add(Ops.STARTS_WITH, "{0} like {1%} escape '\\'");
|
||||
add(Ops.STARTS_WITH_IC, "{0l} like {1%%} escape '\\'");
|
||||
add(Ops.INDEX_OF, "locate({1},{0}) - 1");
|
||||
add(Ops.INDEX_OF_2ARGS, "locate({1},{0},{2}+1) - 1");
|
||||
add(Ops.INDEX_OF_2ARGS, "locate({1},{0},{2s}+1) - 1");
|
||||
|
||||
// date time
|
||||
add(Ops.DateTimeOps.SYSDATE, "sysdate");
|
||||
|
||||
@ -52,7 +52,7 @@ public class JPQLCollectionAnyVisitorTest {
|
||||
Predicate predicate = cat.kittens.any().name.substring(1).eq("uth123");
|
||||
assertEquals("exists (select 1\n" +
|
||||
"from Cat cat_kittens\n" +
|
||||
"where cat_kittens in elements(cat.kittens) and substring(cat_kittens.name,:a1+1) = :a2)", serialize(predicate));
|
||||
"where cat_kittens in elements(cat.kittens) and substring(cat_kittens.name,2) = :a1)", serialize(predicate));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@ -562,9 +562,12 @@ public class SQLSerializer extends SerializerBase<SQLSerializer> {
|
||||
&& args.get(1) instanceof Constant<?>
|
||||
&& operator != Ops.STRING_CAST
|
||||
&& operator != Ops.NUMCAST
|
||||
&& operator != Ops.SUBSTR_1ARG
|
||||
&& operator != Ops.CHAR_AT
|
||||
&& operator != SQLTemplates.CAST) {
|
||||
constantPaths.add((Path<?>)args.get(0));
|
||||
}
|
||||
}
|
||||
|
||||
if (operator.equals(Ops.STRING_CAST)) {
|
||||
String typeName = templates.getTypeForCast(String.class);
|
||||
visitOperation(String.class, SQLTemplates.CAST, Arrays.<Expression<?>>asList(args.get(0), ConstantImpl.create(typeName)));
|
||||
|
||||
@ -164,13 +164,13 @@ public class SQLTemplates extends Templates {
|
||||
add(Ops.DateTimeOps.YEAR_MONTH, "year({0}) * 100 + month({0})");
|
||||
|
||||
// string
|
||||
add(Ops.CHAR_AT, "cast(substr({0},{1}+1,1) as char)");
|
||||
add(Ops.CHAR_AT, "cast(substr({0},{1s}+1,1) as char)");
|
||||
add(Ops.EQ_IGNORE_CASE, "{0l} = {1l}");
|
||||
add(Ops.INDEX_OF, "locate({1},{0})-1");
|
||||
add(Ops.INDEX_OF_2ARGS, "locate({1},{0},{2}+1)-1");
|
||||
add(Ops.INDEX_OF_2ARGS, "locate({1},{0},{2s}+1)-1");
|
||||
add(Ops.STRING_IS_EMPTY, "length({0}) = 0");
|
||||
add(Ops.SUBSTR_1ARG, "substr({0},{1}+1)");
|
||||
add(Ops.SUBSTR_2ARGS, "substr({0},{1}+1,{2})");
|
||||
add(Ops.SUBSTR_1ARG, "substr({0},{1s}+1)");
|
||||
add(Ops.SUBSTR_2ARGS, "substr({0},{1s}+1,{2s}-{1s})");
|
||||
|
||||
// like with escape
|
||||
add(Ops.LIKE, "{0} like {1} escape '"+escape+"'");
|
||||
|
||||
Loading…
Reference in New Issue
Block a user