You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by th...@apache.org on 2012/02/29 15:41:57 UTC
svn commit: r1295136 - in /jackrabbit/sandbox/jackrabbit-microkernel/src:
main/java/org/apache/jackrabbit/query/qom/
main/java/org/apache/jackrabbit/query/qom/tree/ test/resources/
Author: thomasm
Date: Wed Feb 29 14:41:56 2012
New Revision: 1295136
URL: http://svn.apache.org/viewvc?rev=1295136&view=rev
Log:
Query implementation (WIP)
Modified:
jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/QueryObjectModelImpl.java
jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/ComparisonImpl.java
jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/LengthImpl.java
jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/LowerCaseImpl.java
jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/UpperCaseImpl.java
jackrabbit/sandbox/jackrabbit-microkernel/src/test/resources/queryTest.txt
Modified: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/QueryObjectModelImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/QueryObjectModelImpl.java?rev=1295136&r1=1295135&r2=1295136&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/QueryObjectModelImpl.java (original)
+++ jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/QueryObjectModelImpl.java Wed Feb 29 14:41:56 2012
@@ -32,7 +32,9 @@ import org.apache.jackrabbit.query.qom.t
import org.apache.jackrabbit.query.qom.tree.DescendantNodeJoinConditionImpl;
import org.apache.jackrabbit.query.qom.tree.EquiJoinConditionImpl;
import org.apache.jackrabbit.query.qom.tree.FullTextSearchScoreImpl;
+import org.apache.jackrabbit.query.qom.tree.LengthImpl;
import org.apache.jackrabbit.query.qom.tree.LiteralImpl;
+import org.apache.jackrabbit.query.qom.tree.LowerCaseImpl;
import org.apache.jackrabbit.query.qom.tree.NodeLocalNameImpl;
import org.apache.jackrabbit.query.qom.tree.NodeNameImpl;
import org.apache.jackrabbit.query.qom.tree.OrderingImpl;
@@ -43,6 +45,7 @@ import org.apache.jackrabbit.query.qom.t
import org.apache.jackrabbit.query.qom.tree.SameNodeJoinConditionImpl;
import org.apache.jackrabbit.query.qom.tree.SelectorImpl;
import org.apache.jackrabbit.query.qom.tree.SourceImpl;
+import org.apache.jackrabbit.query.qom.tree.UpperCaseImpl;
/**
* The implementation of the corresponding JCR interface. Lifecycle: use the
@@ -178,6 +181,24 @@ public class QueryObjectModelImpl implem
return true;
}
+ @Override
+ public boolean visit(LengthImpl node) {
+ node.setQuery(query);
+ return super.visit(node);
+ }
+
+ @Override
+ public boolean visit(UpperCaseImpl node) {
+ node.setQuery(query);
+ return super.visit(node);
+ }
+
+ @Override
+ public boolean visit(LowerCaseImpl node) {
+ node.setQuery(query);
+ return super.visit(node);
+ }
+
}.visit(this);
source.init(this);
}
Modified: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/ComparisonImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/ComparisonImpl.java?rev=1295136&r1=1295135&r2=1295136&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/ComparisonImpl.java (original)
+++ jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/ComparisonImpl.java Wed Feb 29 14:41:56 2012
@@ -21,6 +21,7 @@ package org.apache.jackrabbit.query.qom.
import javax.jcr.RepositoryException;
import javax.jcr.Value;
import javax.jcr.query.qom.Comparison;
+import org.h2.message.DbException;
/**
* The implementation of the corresponding JCR interface.
@@ -64,11 +65,12 @@ public class ComparisonImpl extends Cons
case GE:
case GT:
case LE:
- case LIKE:
case LT:
return operand1.currentValue() .equals(operand2.currentValue());
case NE:
return !operand1.currentValue().equals(operand2.currentValue());
+ case LIKE:
+ return evaluateLike(v1, v2);
}
// TODO Auto-generated method stub
return false;
@@ -78,6 +80,11 @@ public class ComparisonImpl extends Cons
}
}
+ private boolean evaluateLike(Value v1, Value v2) throws RepositoryException {
+ LikePattern like = new LikePattern(v2.getString());
+ return like.matches(v1.getString());
+ }
+
@Override
boolean accept(QOMVisitor v) {
return v.visit(this);
@@ -87,4 +94,118 @@ public class ComparisonImpl extends Cons
return operator.formatSql(operand1.toString(), operand2.toString());
}
+ /**
+ * A pattern matcher.
+ */
+ public static class LikePattern {
+
+ // TODO LIKE: optimize condition to '=' when no patterns are used, or 'between x and x+1'
+ // TODO LIKE: what to do for invalid patterns (patterns ending with a backslash)
+
+ private static final int MATCH = 0, ONE = 1, ANY = 2;
+
+ private String patternString;
+ private boolean invalidPattern;
+ private char[] patternChars;
+ private int[] patternTypes;
+ private int patternLength;
+
+ LikePattern(String pattern) {
+ initPattern(pattern);
+ }
+
+ boolean matches(String value) {
+ if (invalidPattern) {
+ return false;
+ }
+ return compareAt(value, 0, 0, value.length(), patternChars, patternTypes);
+ }
+
+ private boolean compare(char[] pattern, String s, int pi, int si) {
+ return pattern[pi] == s.charAt(si);
+ }
+
+ private boolean compareAt(String s, int pi, int si, int sLen, char[] pattern, int[] types) {
+ for (; pi < patternLength; pi++) {
+ switch (types[pi]) {
+ case MATCH:
+ if ((si >= sLen) || !compare(pattern, s, pi, si++)) {
+ return false;
+ }
+ break;
+ case ONE:
+ if (si++ >= sLen) {
+ return false;
+ }
+ break;
+ case ANY:
+ if (++pi >= patternLength) {
+ return true;
+ }
+ while (si < sLen) {
+ if (compare(pattern, s, pi, si) && compareAt(s, pi, si, sLen, pattern, types)) {
+ return true;
+ }
+ si++;
+ }
+ return false;
+ default:
+ DbException.throwInternalError();
+ }
+ }
+ return si == sLen;
+ }
+
+ private void initPattern(String p) {
+ patternLength = 0;
+ if (p == null) {
+ patternTypes = null;
+ patternChars = null;
+ return;
+ }
+ int len = p.length();
+ patternChars = new char[len];
+ patternTypes = new int[len];
+ boolean lastAny = false;
+ for (int i = 0; i < len; i++) {
+ char c = p.charAt(i);
+ int type;
+ if (c == '\\') {
+ if (i >= len - 1) {
+ invalidPattern = true;
+ return;
+ }
+ c = p.charAt(++i);
+ type = MATCH;
+ lastAny = false;
+ } else if (c == '%') {
+ if (lastAny) {
+ continue;
+ }
+ type = ANY;
+ lastAny = true;
+ } else if (c == '_') {
+ type = ONE;
+ } else {
+ type = MATCH;
+ lastAny = false;
+ }
+ patternTypes[patternLength] = type;
+ patternChars[patternLength++] = c;
+ }
+ for (int i = 0; i < patternLength - 1; i++) {
+ if ((patternTypes[i] == ANY) && (patternTypes[i + 1] == ONE)) {
+ patternTypes[i] = ONE;
+ patternTypes[i + 1] = ANY;
+ }
+ }
+ patternString = new String(patternChars, 0, patternLength);
+ }
+
+ public String toString() {
+ return patternString;
+ }
+
+ }
+
}
Modified: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/LengthImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/LengthImpl.java?rev=1295136&r1=1295135&r2=1295136&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/LengthImpl.java (original)
+++ jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/LengthImpl.java Wed Feb 29 14:41:56 2012
@@ -48,7 +48,11 @@ public class LengthImpl extends DynamicO
@Override
Value currentValue() throws RepositoryException {
- String value = propertyValue.currentValue().getString();
+ Value v = propertyValue.currentValue();
+ if (v == null) {
+ return null;
+ }
+ String value = v.getString();
return query.getValueFactory().createValue(value.length());
}
Modified: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/LowerCaseImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/LowerCaseImpl.java?rev=1295136&r1=1295135&r2=1295136&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/LowerCaseImpl.java (original)
+++ jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/LowerCaseImpl.java Wed Feb 29 14:41:56 2012
@@ -48,8 +48,12 @@ public class LowerCaseImpl extends Dynam
@Override
Value currentValue() throws RepositoryException {
- Value value = operand.currentValue();
- return query.getValueFactory().createValue(value.getString().toUpperCase());
+ Value v = operand.currentValue();
+ if (v == null) {
+ return null;
+ }
+ String value = v.getString();
+ return query.getValueFactory().createValue(value.toLowerCase());
}
}
Modified: jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/UpperCaseImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/UpperCaseImpl.java?rev=1295136&r1=1295135&r2=1295136&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/UpperCaseImpl.java (original)
+++ jackrabbit/sandbox/jackrabbit-microkernel/src/main/java/org/apache/jackrabbit/query/qom/tree/UpperCaseImpl.java Wed Feb 29 14:41:56 2012
@@ -48,8 +48,12 @@ public class UpperCaseImpl extends Dynam
@Override
Value currentValue() throws RepositoryException {
- Value value = operand.currentValue();
- return query.getValueFactory().createValue(value.getString().toUpperCase());
+ Value v = operand.currentValue();
+ if (v == null) {
+ return null;
+ }
+ String value = v.getString();
+ return query.getValueFactory().createValue(value.toUpperCase());
}
}
Modified: jackrabbit/sandbox/jackrabbit-microkernel/src/test/resources/queryTest.txt
URL: http://svn.apache.org/viewvc/jackrabbit/sandbox/jackrabbit-microkernel/src/test/resources/queryTest.txt?rev=1295136&r1=1295135&r2=1295136&view=diff
==============================================================================
--- jackrabbit/sandbox/jackrabbit-microkernel/src/test/resources/queryTest.txt (original)
+++ jackrabbit/sandbox/jackrabbit-microkernel/src/test/resources/queryTest.txt Wed Feb 29 14:41:56 2012
@@ -34,3 +34,41 @@ select * from [nt:base] where x is null
- "test"
- "test2"
++ "test": { "name": "Hello" }
++ "test2": { "name": "World!" }
++ "test3": { "name": "Hallo" }
++ "test4": { "name": "10%" }
++ "test5": { "name": "10 percent" }
+
+select * from [nt:base] where length(name) = 5
+/test
+/test3
+
+select * from [nt:base] where upper(name) = 'HELLO'
+/test
+
+select * from [nt:base] where lower(name) = 'world!'
+/test2
+
+select * from [nt:base] where name like 'W%'
+/test2
+
+select * from [nt:base] where name like '%o_%'
+/test2
+
+select * from [nt:base] where name like 'H_llo'
+/test
+/test3
+
+select * from [nt:base] where upper(name) like 'H_LLO'
+/test
+/test3
+
+select * from [nt:base] where upper(name) like 'H\_LLO'
+
+select * from [nt:base] where upper(name) like '10%'
+/test4
+/test5
+
+select * from [nt:base] where upper(name) like '10\%'
+/test4