You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jackrabbit.apache.org by mr...@apache.org on 2005/01/28 10:52:40 UTC
svn commit: r148868 - in incubator/jackrabbit/trunk: . src/java/org/apache/jackrabbit/core/search/lucene src/java/org/apache/jackrabbit/core/search/xpath src/test/org/apache/jackrabbit/test/search
Author: mreutegg
Date: Fri Jan 28 01:52:38 2005
New Revision: 148868
URL: http://svn.apache.org/viewcvs?view=rev&rev=148868
Log:
Upgraded to Lucene 1.4.3 and implemented order by in queries
Added:
incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/search/ISO9075Test.java (contents, props changed)
incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/search/OrderByTest.java (contents, props changed)
Modified:
incubator/jackrabbit/trunk/project.xml
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/ChildAxisQuery.java
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/DescendantSelfAxisQuery.java
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/MatchAllScorer.java
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/SearchIndex.java
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/WildcardTermEnum.java
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/xpath/XPathQueryBuilder.java
incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/search/TestAll.java
Modified: incubator/jackrabbit/trunk/project.xml
Url: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/project.xml?view=diff&rev=148868&p1=incubator/jackrabbit/trunk/project.xml&r1=148867&p2=incubator/jackrabbit/trunk/project.xml&r2=148868
==============================================================================
--- incubator/jackrabbit/trunk/project.xml (original)
+++ incubator/jackrabbit/trunk/project.xml Fri Jan 28 01:52:38 2005
@@ -264,7 +264,7 @@
<dependency>
<groupId>lucene</groupId>
<artifactId>lucene</artifactId>
- <version>1.3</version>
+ <version>1.4.3</version>
</dependency>
<dependency>
<groupId>xerces</groupId>
Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/ChildAxisQuery.java
Url: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/ChildAxisQuery.java?view=diff&rev=148868&p1=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/ChildAxisQuery.java&r1=148867&p2=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/ChildAxisQuery.java&r2=148868
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/ChildAxisQuery.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/ChildAxisQuery.java Fri Jan 28 01:52:38 2005
@@ -158,7 +158,7 @@
private List uuids = null;
/** The next document id to return */
- private int nextDoc = 0;
+ private int nextDoc = -1;
/**
* Creates a new <code>ChildAxisScorer</code>.
@@ -172,9 +172,48 @@
}
/**
- * @see Scorer#score(org.apache.lucene.search.HitCollector, int)
+ * @see Scorer#score(org.apache.lucene.search.HitCollector)
*/
- public void score(HitCollector hc, int maxDoc) throws IOException {
+ public void score(HitCollector hc) throws IOException {
+ calculateChildren();
+
+ int next = hits.nextSetBit(0);
+ while (next > -1) {
+ hc.collect(next, 1.0f);
+ // move to next doc
+ next = hits.nextSetBit(next + 1);
+ }
+ }
+
+ public boolean next() throws IOException {
+ calculateChildren();
+ nextDoc = hits.nextSetBit(nextDoc + 1);
+ return nextDoc > -1;
+ }
+
+ public int doc() {
+ return nextDoc;
+ }
+
+ public float score() throws IOException {
+ // todo implement
+ return 1.0f;
+ }
+
+ public boolean skipTo(int target) throws IOException {
+ nextDoc = hits.nextSetBit(target);
+ return nextDoc > -1;
+ }
+
+ /**
+ * @exception UnsupportedOperationException this implementation always
+ * throws an <code>UnsupportedOperationException</code>.
+ */
+ public Explanation explain(int doc) throws IOException {
+ throw new UnsupportedOperationException();
+ }
+
+ private void calculateChildren() throws IOException {
if (uuids == null) {
uuids = new ArrayList();
contextScorer.score(new HitCollector() {
@@ -182,7 +221,7 @@
// @todo maintain cache of doc id hierarchy
hits.set(doc);
}
- }, reader.maxDoc()); // find all
+ }); // find all
for (int i = hits.nextSetBit(0); i >= 0; i = hits.nextSetBit(i + 1)) {
String uuid = reader.document(i).get(FieldNames.UUID);
uuids.add(uuid);
@@ -195,22 +234,7 @@
hits.set(children.doc());
}
}
- nextDoc = hits.nextSetBit(0);
- }
-
- while (nextDoc > -1 && nextDoc < maxDoc) {
- hc.collect(nextDoc, 1.0f);
- // move to next doc
- nextDoc = hits.nextSetBit(nextDoc + 1);
}
- }
-
- /**
- * @exception UnsupportedOperationException this implementation always
- * throws an <code>UnsupportedOperationException</code>.
- */
- public Explanation explain(int doc) throws IOException {
- throw new UnsupportedOperationException();
}
}
}
Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/DescendantSelfAxisQuery.java
Url: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/DescendantSelfAxisQuery.java?view=diff&rev=148868&p1=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/DescendantSelfAxisQuery.java&r1=148867&p2=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/DescendantSelfAxisQuery.java&r2=148868
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/DescendantSelfAxisQuery.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/DescendantSelfAxisQuery.java Fri Jan 28 01:52:38 2005
@@ -172,7 +172,7 @@
private Set contextUUIDs = null;
/** The next document id to return */
- private int nextDoc = 0;
+ private int nextDoc = -1;
/**
* Creates a new <code>DescendantSelfAxisScorer</code>.
@@ -187,34 +187,18 @@
}
/**
- * @see Scorer#score(org.apache.lucene.search.HitCollector, int)
+ * @see Scorer#score(org.apache.lucene.search.HitCollector)
*/
- public void score(HitCollector hc, int maxDoc) throws IOException {
- if (contextUUIDs == null) {
- contextUUIDs = new HashSet();
- contextScorer.score(new HitCollector() {
- public void collect(int doc, float score) {
- // @todo maintain cache of doc id hierarchy
- hits.set(doc);
- }
- }, reader.maxDoc()); // find all
- for (int i = hits.nextSetBit(0); i >= 0; i = hits.nextSetBit(i + 1)) {
- contextUUIDs.add(reader.document(i).get(FieldNames.UUID));
- }
-
- // reuse for final hits
- hits.clear();
-
- subScorer.score(new HitCollector() {
- public void collect(int doc, float score) {
- subHits.set(doc);
- }
- }, reader.maxDoc());
-
- nextDoc = subHits.nextSetBit(0);
+ public void score(HitCollector hc) throws IOException {
+ while (next()) {
+ hc.collect(doc(), score());
}
+ }
- while (nextDoc > -1 && nextDoc < maxDoc) {
+ public boolean next() throws IOException {
+ calculateSubHits();
+ nextDoc = subHits.nextSetBit(nextDoc + 1);
+ while (nextDoc > -1) {
// check if nextDoc is really valid
String parentUUID = reader.document(nextDoc).get(FieldNames.PARENT);
while (parentUUID != null && !contextUUIDs.contains(parentUUID)) {
@@ -230,12 +214,48 @@
}
}
if (parentUUID != null) {
- // match
- hc.collect(nextDoc, 1.0f);
+ return true;
}
- // move to next doc
+ // try next
nextDoc = subHits.nextSetBit(nextDoc + 1);
+ }
+ return false;
+ }
+
+ public int doc() {
+ return nextDoc;
+ }
+
+ public float score() throws IOException {
+ return 1.0f;
+ }
+ public boolean skipTo(int target) throws IOException {
+ nextDoc = target - 1;
+ return next();
+ }
+
+ private void calculateSubHits() throws IOException {
+ if (contextUUIDs == null) {
+ contextUUIDs = new HashSet();
+ contextScorer.score(new HitCollector() {
+ public void collect(int doc, float score) {
+ // @todo maintain cache of doc id hierarchy
+ hits.set(doc);
+ }
+ }); // find all
+ for (int i = hits.nextSetBit(0); i >= 0; i = hits.nextSetBit(i + 1)) {
+ contextUUIDs.add(reader.document(i).get(FieldNames.UUID));
+ }
+
+ // reuse for final hits
+ hits.clear();
+
+ subScorer.score(new HitCollector() {
+ public void collect(int doc, float score) {
+ subHits.set(doc);
+ }
+ });
}
}
Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/MatchAllScorer.java
Url: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/MatchAllScorer.java?view=diff&rev=148868&p1=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/MatchAllScorer.java&r1=148867&p2=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/MatchAllScorer.java&r2=148868
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/MatchAllScorer.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/MatchAllScorer.java Fri Jan 28 01:52:38 2005
@@ -34,9 +34,9 @@
class MatchAllScorer extends Scorer {
/**
- * current doc number
+ * next doc number
*/
- private int docNo = 0;
+ private int nextDoc = 0;
/**
* IndexReader giving access to index
@@ -86,23 +86,43 @@
}
/**
- * Scores documents until <code>maxDoc</code> has reached.
- *
- * @param hc the <code>HitCollector</code> from the underlying
- * lucene query.
- * @param maxDoc collect hits until <code>maxDoc</code> has reached.
- */
- public void score(HitCollector hc, int maxDoc) {
- float score = getSimilarity().tf(1) * weight.getValue();
- while (docNo < maxDoc) {
- if (!reader.isDeleted(docNo)) {
- // check docFilter
- if (docFilter.get(docNo)) {
- hc.collect(docNo, score);
- }
- }
- docNo++;
+ * @see Scorer#score(org.apache.lucene.search.HitCollector)
+ */
+ public void score(HitCollector hc) throws IOException {
+ while (next()) {
+ hc.collect(doc(), score());
}
+ }
+
+
+ /**
+ * @see org.apache.lucene.search.Scorer#next()
+ */
+ public boolean next() throws IOException {
+ nextDoc = docFilter.nextSetBit(nextDoc + 1);
+ return nextDoc > -1;
+ }
+
+ /**
+ * @see org.apache.lucene.search.Scorer#doc()
+ */
+ public int doc() {
+ return nextDoc;
+ }
+
+ /**
+ * @see org.apache.lucene.search.Scorer#score()
+ */
+ public float score() throws IOException {
+ return 1.0f;
+ }
+
+ /**
+ * @see org.apache.lucene.search.Scorer#skipTo(int)
+ */
+ public boolean skipTo(int target) throws IOException {
+ nextDoc = target - 1;
+ return next();
}
/**
Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/SearchIndex.java
Url: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/SearchIndex.java?view=diff&rev=148868&p1=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/SearchIndex.java&r1=148867&p2=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/SearchIndex.java&r2=148868
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/SearchIndex.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/SearchIndex.java Fri Jan 28 01:52:38 2005
@@ -24,6 +24,7 @@
import org.apache.jackrabbit.core.SessionImpl;
import org.apache.jackrabbit.core.ItemManager;
import org.apache.jackrabbit.core.QName;
+import org.apache.jackrabbit.core.NoPrefixDeclaredException;
import org.apache.log4j.Logger;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
@@ -31,6 +32,8 @@
import org.apache.lucene.index.Term;
import org.apache.lucene.search.Hits;
import org.apache.lucene.search.Query;
+import org.apache.lucene.search.SortField;
+import org.apache.lucene.search.Sort;
import javax.jcr.query.InvalidQueryException;
import javax.jcr.RepositoryException;
@@ -215,16 +218,25 @@
return null;
}
- /*
SortField[] sortFields = new SortField[orderProps.length];
for (int i = 0; i < orderProps.length; i++) {
- sortFields[i] = new SortField(orderProps[i], SortField.STRING, !ascending);
+ String prop = null;
+ try {
+ prop = orderProps[i].toJCRName(nsMappings);
+ } catch (NoPrefixDeclaredException e) {
+ // will never happen
+ }
+ sortFields[i] = new SortField(prop, SortField.STRING, !orderSpecs[i]);
}
-*/
+
Hits hits = null;
try {
- hits = persistentIndex.getIndexSearcher().search(query
- /*, new Sort(sortFields) */);
+ if (sortFields.length > 0) {
+ hits = persistentIndex.getIndexSearcher().search(query,
+ new Sort(sortFields));
+ } else {
+ hits = persistentIndex.getIndexSearcher().search(query);
+ }
} finally {
readWriteLock.readLock().release();
}
Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/WildcardTermEnum.java
Url: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/WildcardTermEnum.java?view=diff&rev=148868&p1=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/WildcardTermEnum.java&r1=148867&p2=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/WildcardTermEnum.java&r2=148868
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/WildcardTermEnum.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/WildcardTermEnum.java Fri Jan 28 01:52:38 2005
@@ -34,12 +34,20 @@
private boolean endEnum = false;
public WildcardTermEnum(IndexReader reader, Term term) throws IOException {
- super(reader, term);
pattern = createRegexp(term.text());
field = term.field();
- // FIXME optimize term enum. find start term text
- setEnum(reader.terms(new Term(term.field(), "")));
+ int idx = 0;
+ while (idx < term.text().length()
+ && Character.isLetterOrDigit(term.text().charAt(idx))) {
+ idx++;
+ }
+ // because IndexReader.terms() starts with the term after the given
+ // one start with idx - 1
+ if (idx > 0) {
+ idx--;
+ }
+ setEnum(reader.terms(new Term(term.field(), term.text().substring(0, idx))));
}
protected boolean termCompare(Term term) {
Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/xpath/XPathQueryBuilder.java
Url: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/xpath/XPathQueryBuilder.java?view=diff&rev=148868&p1=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/xpath/XPathQueryBuilder.java&r1=148867&p2=incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/xpath/XPathQueryBuilder.java&r2=148868
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/xpath/XPathQueryBuilder.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/xpath/XPathQueryBuilder.java Fri Jan 28 01:52:38 2005
@@ -350,7 +350,6 @@
root.addSelectProperty(name);
} else if (queryNode instanceof OrderQueryNode) {
QName name = ISO9075.decode(QName.fromJCRName(child.getValue(), resolver));
- // todo implement properly
root.getOrderNode().addOrderSpec(name, true);
}
} catch (IllegalNameException e) {
Added: incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/search/ISO9075Test.java
Url: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/search/ISO9075Test.java?view=auto&rev=148868
==============================================================================
--- (empty file)
+++ incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/search/ISO9075Test.java Fri Jan 28 01:52:38 2005
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2004-2005 The Apache Software Foundation or its licensors,
+ * as applicable.
+ *
+ * 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 org.apache.jackrabbit.test.search;
+
+import org.apache.jackrabbit.core.QName;
+import org.apache.jackrabbit.core.search.xpath.ISO9075;
+import org.apache.xerces.util.XMLChar;
+import junit.framework.TestCase;
+
+/**
+ * Test cases for ISO9075 encode / decode.
+ */
+public class ISO9075Test extends TestCase {
+
+ public void testSpecExamples() {
+ assertEquals("My_x0020_Documents", ISO9075.encode("My Documents"));
+ assertEquals("_x0031_234id", ISO9075.encode("1234id"));
+ assertEquals("merry_x005f_xmas", ISO9075.encode("merry_xmas"));
+ assertEquals("merry_christmas", ISO9075.encode("merry_christmas"));
+ }
+
+ /**
+ * This is a disabled brute force test. It tests permutations of characters:
+ * <code>' ', '_', 'x', '0', '2', 'a', 'b', '{'</code>, encodes and decodes
+ * the sequences and test whether the initial sequence equals the resulting
+ * sequence that went through the encoding / decoding process.
+ * </p>
+ * The test takes about 30 seconds on my 1.2G P3.
+ * </p>
+ * To enable the test remove the 'disabled_' refix from the method name.
+ */
+ public void disabled_testBrute() {
+ char[] chars = new char[] {' ', '_', 'x', '0', '2', 'a', 'b', '{'};
+ long start = Long.parseLong("1000000", 8);
+ long end = Long.parseLong("7777777", 8);
+ for (long i = start; i < end; i++) {
+ String s = Long.toString(i, chars.length);
+ StringBuffer b = new StringBuffer(s.length());
+ for (int j = 0; j < s.length(); j++) {
+ b.append(chars[s.charAt(j) - '0']);
+ }
+ // encode and decode
+ QName initial = new QName("", b.toString());
+ if ((i % 100000) == 0) {
+ System.out.println(initial);
+ }
+ QName encoded = ISO9075.encode(initial);
+ assertTrue(XMLChar.isValidName(encoded.getLocalName()));
+ QName decoded = ISO9075.decode(encoded);
+ assertEquals(initial, decoded);
+ }
+ }
+
+}
Added: incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/search/OrderByTest.java
Url: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/search/OrderByTest.java?view=auto&rev=148868
==============================================================================
--- (empty file)
+++ incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/search/OrderByTest.java Fri Jan 28 01:52:38 2005
@@ -0,0 +1,238 @@
+/*
+ * $Id: $
+ *
+ * Copyright 1997-2004 Day Management AG
+ * Barfuesserplatz 6, 4001 Basel, Switzerland
+ * All Rights Reserved.
+ *
+ * This software is the confidential and proprietary information of
+ * Day Management AG, ("Confidential Information"). You shall not
+ * disclose such Confidential Information and shall use it only in
+ * accordance with the terms of the license agreement you entered into
+ * with Day.
+ */
+
+package org.apache.jackrabbit.test.search;
+
+import javax.jcr.Node;
+import javax.jcr.NodeIterator;
+import javax.jcr.RepositoryException;
+import javax.jcr.query.Query;
+import javax.jcr.query.QueryResult;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Calendar;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.TimeZone;
+
+/**
+ * Tests queries with order by.
+ */
+public class OrderByTest extends AbstractQueryTest {
+
+ public void testStringOrder() throws Exception {
+ populate(new String[]{"aaaa", "cccc", "bbbb", "dddd"});
+ checkOrder(new int[]{1, 3, 2, 4});
+ }
+
+ public void testIntegerOrder() throws Exception {
+ populate(new int[]{0, -1, 1, 5});
+ checkOrder(new int[]{2, 1, 3, 4});
+ }
+
+ public void testDateOrder() throws Exception {
+ Calendar c1 = Calendar.getInstance();
+ c1.set(2000, 4, 20, 14, 35, 14);
+ Calendar c2 = Calendar.getInstance();
+ c2.set(2000, 5, 20, 14, 35, 14);
+ Calendar c3 = Calendar.getInstance();
+ c3.set(2000, 4, 20, 14, 35, 13);
+ populate(new Calendar[]{c1, c2, c3});
+ checkOrder(new int[]{3, 1, 2});
+ }
+
+ public void testDateOrderMillis() throws Exception {
+ Calendar c1 = Calendar.getInstance();
+ c1.set(2000, 6, 12, 14, 35, 19);
+ c1.set(Calendar.MILLISECOND, 10);
+ Calendar c2 = Calendar.getInstance();
+ c2.set(2000, 6, 12, 14, 35, 19);
+ c2.set(Calendar.MILLISECOND, 9);
+ Calendar c3 = Calendar.getInstance();
+ c3.set(2000, 6, 12, 14, 35, 19);
+ c3.set(Calendar.MILLISECOND, 11);
+ populate(new Calendar[]{c1, c2, c3});
+ checkOrder(new int[]{2, 1, 3});
+ }
+
+ public void testDateOrderPositiveTimeZone() throws Exception {
+ Calendar c1 = Calendar.getInstance(TimeZone.getTimeZone("GMT+1:00"));
+ c1.set(2000, 6, 12, 15, 35, 19);
+ c1.set(Calendar.MILLISECOND, 10);
+ Calendar c2 = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
+ c2.set(2000, 6, 12, 14, 35, 19);
+ c2.set(Calendar.MILLISECOND, 9);
+ Calendar c3 = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
+ c3.set(2000, 6, 12, 14, 35, 19);
+ c3.set(Calendar.MILLISECOND, 11);
+ populate(new Calendar[]{c1, c2, c3});
+ checkOrder(new int[]{2, 1, 3});
+ }
+
+ public void testDateOrderNegativeTimeZone() throws Exception {
+ Calendar c1 = Calendar.getInstance(TimeZone.getTimeZone("GMT-1:00"));
+ c1.set(2000, 6, 12, 13, 35, 19);
+ c1.set(Calendar.MILLISECOND, 10);
+ Calendar c2 = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
+ c2.set(2000, 6, 12, 14, 35, 19);
+ c2.set(Calendar.MILLISECOND, 9);
+ Calendar c3 = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
+ c3.set(2000, 6, 12, 14, 35, 19);
+ c3.set(Calendar.MILLISECOND, 11);
+ populate(new Calendar[]{c1, c2, c3});
+ checkOrder(new int[]{2, 1, 3});
+ }
+
+ public void testDoubleOrder1() throws Exception {
+ populate(new double[]{-2.4, 4.3, 0.0});
+ checkOrder(new int[]{1, 3, 2});
+ }
+
+ public void testDoubleOrder2() throws Exception {
+ populate(new double[]{-1.5, -1.4, -1.39});
+ checkOrder(new int[]{1, 2, 3});
+ }
+
+ public void testMultipleOrder() throws Exception {
+ Node n1 = testRootNode.addNode("node1");
+ Node n2 = testRootNode.addNode("node2");
+ Node n3 = testRootNode.addNode("node3");
+
+ n1.setProperty("text", "aaa");
+ n1.setProperty("value", 3);
+ n2.setProperty("text", "bbb");
+ n2.setProperty("value", 2);
+ n3.setProperty("text", "ccc");
+ n3.setProperty("value", 2);
+
+ testRootNode.save();
+
+ // both ascending
+ String sql = "SELECT value FROM nt:unstructured WHERE " +
+ "jcr:path LIKE '/" + testRoot + "/%' ORDER BY value, text";
+ Query q = superuser.getWorkspace().getQueryManager().createQuery(sql, "sql");
+ QueryResult result = q.execute();
+ checkResultOrder(result, new String[]{"node2", "node3", "node1"});
+
+ String xpath = "/" + testRoot + "/*[@jcr:primaryType='nt:unstructured'] order by @value, @text";
+ q = superuser.getWorkspace().getQueryManager().createQuery(xpath, Query.XPATH_DOCUMENT_VIEW);
+ result = q.execute();
+ checkResultOrder(result, new String[]{"node2", "node3", "node1"});
+
+ // both descending
+ sql = "SELECT value FROM nt:unstructured WHERE " +
+ "jcr:path LIKE '/" + testRoot + "/%' ORDER BY value DESC, text DESC";
+ q = superuser.getWorkspace().getQueryManager().createQuery(sql, "sql");
+ result = q.execute();
+ checkResultOrder(result, new String[]{"node1", "node3", "node2"});
+
+ xpath = "/" + testRoot + "/*[@jcr:primaryType='nt:unstructured'] order by @value descending, @text descending";
+ q = superuser.getWorkspace().getQueryManager().createQuery(xpath, Query.XPATH_DOCUMENT_VIEW);
+ result = q.execute();
+ checkResultOrder(result, new String[]{"node1", "node3", "node2"});
+
+ // mixed ascending and descending
+ sql = "SELECT value FROM nt:unstructured WHERE " +
+ "jcr:path LIKE '/" + testRoot + "/%' ORDER BY value DESC, text";
+ q = superuser.getWorkspace().getQueryManager().createQuery(sql, "sql");
+ result = q.execute();
+ checkResultOrder(result, new String[]{"node1", "node2", "node3"});
+
+ xpath = "/" + testRoot + "/*[@jcr:primaryType='nt:unstructured'] order by @value descending, @text";
+ q = superuser.getWorkspace().getQueryManager().createQuery(xpath, Query.XPATH_DOCUMENT_VIEW);
+ result = q.execute();
+ checkResultOrder(result, new String[]{"node1", "node2", "node3"});
+ }
+
+ //------------------< internal >--------------------------------------------
+
+ private void populate(String[] values) throws RepositoryException {
+ for (int i = 0; i < values.length; i++) {
+ Node node = testRootNode.addNode("node" + (i + 1));
+ node.setProperty("value", values[i]);
+ }
+ testRootNode.save();
+ }
+
+ private void populate(Calendar[] values) throws RepositoryException {
+ for (int i = 0; i < values.length; i++) {
+ Node node = testRootNode.addNode("node" + (i + 1));
+ node.setProperty("value", values[i]);
+ }
+ testRootNode.save();
+ }
+
+ private void populate(int[] values) throws RepositoryException {
+ for (int i = 0; i < values.length; i++) {
+ Node node = testRootNode.addNode("node" + (i + 1));
+ node.setProperty("value", values[i]);
+ }
+ testRootNode.save();
+ }
+
+ private void populate(double[] values) throws RepositoryException {
+ for (int i = 0; i < values.length; i++) {
+ Node node = testRootNode.addNode("node" + (i + 1));
+ node.setProperty("value", values[i]);
+ }
+ testRootNode.save();
+ }
+
+ private void checkOrder(int[] order) throws RepositoryException {
+ String nodeNames[] = new String[order.length];
+ for (int i = 0; i < order.length; i++) {
+ nodeNames[i] = "node" + order[i];
+ }
+ // first check ascending
+ String sql = "SELECT value FROM nt:unstructured WHERE " +
+ "jcr:path LIKE '/" + testRoot + "/%' ORDER BY value";
+ Query q = superuser.getWorkspace().getQueryManager().createQuery(sql, "sql");
+ QueryResult result = q.execute();
+ checkResultOrder(result, nodeNames);
+
+ String xpath = "/" + testRoot + "/*[@jcr:primaryType='nt:unstructured'] order by @value";
+ q = superuser.getWorkspace().getQueryManager().createQuery(xpath, Query.XPATH_DOCUMENT_VIEW);
+ result = q.execute();
+ checkResultOrder(result, nodeNames);
+
+ // then check descending
+ Collections.reverse(Arrays.asList(nodeNames));
+
+ sql = "SELECT value FROM nt:unstructured WHERE " +
+ "jcr:path LIKE '/" + testRoot + "/%' ORDER BY value DESC";
+ q = superuser.getWorkspace().getQueryManager().createQuery(sql, "sql");
+ result = q.execute();
+ checkResultOrder(result, nodeNames);
+
+ xpath = "/" + testRoot + "/*[@jcr:primaryType='nt:unstructured'] order by @value descending";
+ q = superuser.getWorkspace().getQueryManager().createQuery(xpath, Query.XPATH_DOCUMENT_VIEW);
+ result = q.execute();
+ checkResultOrder(result, nodeNames);
+ }
+
+ private void checkResultOrder(QueryResult result, String[] nodeNames)
+ throws RepositoryException {
+ List nodes = new ArrayList();
+ for (NodeIterator it = result.getNodes(); it.hasNext();) {
+ nodes.add(it.nextNode());
+ }
+ assertEquals("Wrong hit count:", nodeNames.length, nodes.size());
+
+ for (int i = 0; i < nodeNames.length; i++) {
+ String name = ((Node) nodes.get(i)).getName();
+ assertEquals("Wrong order of nodes:", nodeNames[i], name);
+ }
+ }
+
+}
Modified: incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/search/TestAll.java
Url: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/search/TestAll.java?view=diff&rev=148868&p1=incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/search/TestAll.java&r1=148867&p2=incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/search/TestAll.java&r2=148868
==============================================================================
--- incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/search/TestAll.java (original)
+++ incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/search/TestAll.java Fri Jan 28 01:52:38 2005
@@ -35,10 +35,12 @@
public static Test suite() {
TestSuite suite = new TestSuite("Search tests");
+ suite.addTestSuite(ISO9075Test.class);
suite.addTestSuite(SimpleQueryTest.class);
suite.addTestSuite(FulltextQueryTest.class);
suite.addTestSuite(SelectClauseTest.class);
suite.addTestSuite(SQLTest.class);
+ suite.addTestSuite(OrderByTest.class);
return suite;
}