Return-Path: Delivered-To: apmail-incubator-jackrabbit-commits-archive@www.apache.org Received: (qmail 71318 invoked from network); 28 Jan 2005 09:52:44 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (209.237.227.199) by minotaur-2.apache.org with SMTP; 28 Jan 2005 09:52:44 -0000 Received: (qmail 99716 invoked by uid 500); 28 Jan 2005 09:52:43 -0000 Mailing-List: contact jackrabbit-commits-help@incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: jackrabbit-dev@incubator.apache.org Delivered-To: mailing list jackrabbit-commits@incubator.apache.org Received: (qmail 99691 invoked by uid 500); 28 Jan 2005 09:52:43 -0000 Delivered-To: apmail-incubator-jackrabbit-cvs@incubator.apache.org Received: (qmail 99680 invoked by uid 99); 28 Jan 2005 09:52:43 -0000 X-ASF-Spam-Status: No, hits=-9.8 required=10.0 tests=ALL_TRUSTED,NO_REAL_NAME X-Spam-Check-By: apache.org Received: from minotaur.apache.org (HELO minotaur.apache.org) (209.237.227.194) by apache.org (qpsmtpd/0.28) with SMTP; Fri, 28 Jan 2005 01:52:41 -0800 Received: (qmail 71201 invoked by uid 65534); 28 Jan 2005 09:52:40 -0000 Date: 28 Jan 2005 09:52:40 -0000 Message-ID: <20050128095240.71196.qmail@minotaur.apache.org> From: mreutegg@apache.org To: jackrabbit-cvs@incubator.apache.org Subject: 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 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 X-Virus-Checked: Checked X-Spam-Rating: minotaur-2.apache.org 1.6.2 0/1000/N 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 @@ lucene lucene - 1.3 + 1.4.3 xerces 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 ChildAxisScorer. @@ -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 UnsupportedOperationException. + */ + 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 UnsupportedOperationException. - */ - 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 DescendantSelfAxisScorer. @@ -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 maxDoc has reached. - * - * @param hc the HitCollector from the underlying - * lucene query. - * @param maxDoc collect hits until maxDoc 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: + * ' ', '_', 'x', '0', '2', 'a', 'b', '{', encodes and decodes + * the sequences and test whether the initial sequence equals the resulting + * sequence that went through the encoding / decoding process. + *

+ * The test takes about 30 seconds on my 1.2G P3. + *

+ * 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; }