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/02/08 10:36:59 UTC
svn commit: r152654 - in incubator/jackrabbit/trunk/src:
java/org/apache/jackrabbit/core/ java/org/apache/jackrabbit/core/search/
java/org/apache/jackrabbit/core/search/lucene/
java/org/apache/jackrabbit/core/search/sql/
test/org/apache/jackrabbit/test/search/
Author: mreutegg
Date: Tue Feb 8 01:36:54 2005
New Revision: 152654
URL: http://svn.apache.org/viewcvs?view=rev&rev=152654
Log:
Simplify QueryHandler. Added support for jcr:score and jcr:path.
Modified:
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/SearchManager.java
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/Constants.java
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/QueryHandler.java
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/QueryManagerImpl.java
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/LuceneQueryBuilder.java
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/NodeIteratorImpl.java
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/QueryImpl.java
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/QueryResultImpl.java
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/RowIteratorImpl.java
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/SearchIndex.java
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/sql/JCRSQLQueryBuilder.java
incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/sql/QueryFormat.java
incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/search/OrderByTest.java
incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/search/SelectClauseTest.java
Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/SearchManager.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/SearchManager.java?view=diff&r1=152653&r2=152654
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/SearchManager.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/SearchManager.java Tue Feb 8 01:36:54 2005
@@ -23,14 +23,15 @@
import org.apache.jackrabbit.core.observation.EventImpl;
import org.apache.jackrabbit.core.observation.SynchronousEventListener;
import org.apache.jackrabbit.core.search.QueryHandler;
+import org.apache.jackrabbit.core.search.QueryImpl;
import org.apache.jackrabbit.core.state.ItemStateException;
import org.apache.jackrabbit.core.state.NodeState;
import org.apache.log4j.Logger;
-import javax.jcr.ItemNotFoundException;
import javax.jcr.NamespaceException;
import javax.jcr.NamespaceRegistry;
import javax.jcr.RepositoryException;
+import javax.jcr.Node;
import javax.jcr.observation.Event;
import javax.jcr.observation.EventIterator;
import javax.jcr.query.InvalidQueryException;
@@ -43,7 +44,7 @@
/**
* Acts as a global entry point to execute queries and index nodes.
*
- * @todo The SearchManager currently uses the system session to obtain an
+ * todo The SearchManager currently uses the system session to obtain an
* ItemStateManager from where it reads persistent ItemStates. This is kind
* of nasty, because the system session it is possible to change content through
* the system session as well.
@@ -203,7 +204,7 @@
String statement,
String language)
throws InvalidQueryException, RepositoryException {
- return handler.createQuery(session, itemMgr, statement, language);
+ return new QueryImpl(session, itemMgr, handler, statement, language);
}
/**
@@ -212,18 +213,17 @@
* @param session the session of the user executing the query.
* @param itemMgr the item manager of the user executing the query. Needed
* to return <code>Node</code> instances in the result set.
- * @param absPath absolute path to a node of type nt:query.
+ * @param node a node of type nt:query.
* @return a <code>Query</code> instance to execute.
* @throws InvalidQueryException if <code>absPath</code> is not a valid
* persisted query (that is, a node of type nt:query)
- * @throws ItemNotFoundException if there is no node at <code>absPath</code>.
* @throws RepositoryException if any other error occurs.
*/
public Query createQuery(SessionImpl session,
ItemManager itemMgr,
- String absPath)
- throws InvalidQueryException, ItemNotFoundException, RepositoryException {
- return handler.createQuery(session, itemMgr, absPath);
+ Node node)
+ throws InvalidQueryException, RepositoryException {
+ return new QueryImpl(session, itemMgr, handler, node);
}
//---------------< EventListener interface >--------------------------------
Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/Constants.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/Constants.java?view=diff&r1=152653&r2=152654
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/Constants.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/Constants.java Tue Feb 8 01:36:54 2005
@@ -16,11 +16,34 @@
*/
package org.apache.jackrabbit.core.search;
+import org.apache.jackrabbit.core.QName;
+import org.apache.jackrabbit.core.NamespaceRegistryImpl;
+
/**
* This interface defines constants for data types and operation types
* used in queries.
*/
public interface Constants {
+
+ /**
+ * QName for jcr:score
+ */
+ public static final QName JCR_SCORE = new QName(NamespaceRegistryImpl.NS_JCR_URI, "score");
+
+ /**
+ * QName for jcr:path
+ */
+ public static final QName JCR_PATH = new QName(NamespaceRegistryImpl.NS_JCR_URI, "path");
+
+ /**
+ * QName for jcr:statement
+ */
+ public static final QName JCR_STATEMENT = new QName(NamespaceRegistryImpl.NS_JCR_URI, "statement");
+
+ /**
+ * QName for jcr:language
+ */
+ public static final QName JCR_LANGUAGE = new QName(NamespaceRegistryImpl.NS_JCR_URI, "language");
/**
* long data type
Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/QueryHandler.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/QueryHandler.java?view=diff&r1=152653&r2=152654
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/QueryHandler.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/QueryHandler.java Tue Feb 8 01:36:54 2005
@@ -25,7 +25,7 @@
import javax.jcr.query.Query;
import javax.jcr.query.InvalidQueryException;
import javax.jcr.RepositoryException;
-import javax.jcr.ItemNotFoundException;
+import javax.jcr.Node;
import java.io.IOException;
/**
@@ -83,25 +83,8 @@
* @throws InvalidQueryException if statement is invalid or language is unsupported.
* @return A <code>Query</code> object.
*/
- public Query createQuery(SessionImpl session,
+ public ExecutableQuery createExecutableQuery(SessionImpl session,
ItemManager itemMgr,
String statement,
String language) throws InvalidQueryException;
-
- /**
- * Retrieves an existing persistent query. If <code>node</code>
- * is not a valid persisted query (that is, a node of type
- * <code>nt:query</code>), an <code>InvalidQueryException</code>
- * is thrown.
- *
- * @param absPath path to a persisted query (that is, a node of type
- * <code>nt:query</code>).
- * @throws InvalidQueryException If <code>absPath</code> is not a valid persisted query
- * (that is, a node of type <code>nt:query</code>).
- * @throws RepositoryException if another error occurs
- * @return a <code>Query</code> object.
- */
- public Query createQuery(SessionImpl session,
- ItemManager itemMgr,
- String absPath) throws ItemNotFoundException, RepositoryException;
}
Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/QueryManagerImpl.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/QueryManagerImpl.java?view=diff&r1=152653&r2=152654
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/QueryManagerImpl.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/QueryManagerImpl.java Tue Feb 8 01:36:54 2005
@@ -93,7 +93,7 @@
public Query getQuery(Node node)
throws InvalidQueryException, RepositoryException {
- return searchMgr.createQuery(session, itemMgr, node.getPath());
+ return searchMgr.createQuery(session, itemMgr, node);
}
/**
Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/LuceneQueryBuilder.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/LuceneQueryBuilder.java?view=diff&r1=152653&r2=152654
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/LuceneQueryBuilder.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/LuceneQueryBuilder.java Tue Feb 8 01:36:54 2005
@@ -134,18 +134,6 @@
public Object visit(QueryRootNode node, Object data) {
BooleanQuery root = new BooleanQuery();
- QName[] props = node.getSelectProperties();
- for (int i = 0; i < props.length; i++) {
- try {
- String prop = props[i].toJCRName(nsMappings);
- // @todo really search nodes that have non null values?
- root.add(new MatchAllQuery(prop), true, false);
- } catch (NoPrefixDeclaredException e) {
- // should never happen actually. prefixes are dynamically created
- exceptions.add(e);
- }
- }
-
Query wrapped = root;
if (node.getLocationNode() != null) {
wrapped = (Query) node.getLocationNode().accept(this, root);
Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/NodeIteratorImpl.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/NodeIteratorImpl.java?view=diff&r1=152653&r2=152654
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/NodeIteratorImpl.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/NodeIteratorImpl.java Tue Feb 8 01:36:54 2005
@@ -38,6 +38,9 @@
/** The UUIDs of the nodes in the result set */
private final String[] uuids;
+ /** The score values for the nodes in the result set */
+ private final Float[] scores;
+
/** ItemManager to turn UUIDs into Node instances */
private final ItemManager itemMgr;
@@ -49,11 +52,14 @@
* @param itemMgr the <code>ItemManager</code> to turn UUIDs into
* <code>Node</code> instances.
* @param uuids the UUIDs of the result nodes.
+ * @param scores the corresponding score values for each result node.
*/
NodeIteratorImpl(ItemManager itemMgr,
- String[] uuids) {
+ String[] uuids,
+ Float[] scores) {
this.itemMgr = itemMgr;
this.uuids = uuids;
+ this.scores = scores;
}
/**
@@ -128,9 +134,22 @@
}
/**
+ * Returns the score of the node returned by {@link #nextNode()}. In other
+ * words, this method returns the score value of the next <code>Node</code>.
+ * @return the score of the node returned by {@link #nextNode()}.
+ * @throws NoSuchElementException if there is no next node.
+ */
+ float getScore() {
+ if (!hasNext()) {
+ throw new NoSuchElementException();
+ }
+ return scores[pos].floatValue();
+ }
+
+ /**
* Returns the next <code>Node</code> in the result set.
* @return the next <code>Node</code> in the result set.
- * @throws java.util.NoSuchElementException if iteration has no more
+ * @throws NoSuchElementException if iteration has no more
* <code>Node</code>s.
*/
NodeImpl nextNodeImpl() {
Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/QueryImpl.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/QueryImpl.java?view=diff&r1=152653&r2=152654
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/QueryImpl.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/QueryImpl.java Tue Feb 8 01:36:54 2005
@@ -25,64 +25,56 @@
import org.apache.jackrabbit.core.search.LocationStepQueryNode;
import org.apache.jackrabbit.core.search.NodeTypeQueryNode;
import org.apache.jackrabbit.core.search.DefaultQueryNodeVisitor;
+import org.apache.jackrabbit.core.search.ExecutableQuery;
import org.apache.jackrabbit.core.QName;
-import org.apache.jackrabbit.core.NamespaceRegistryImpl;
import org.apache.jackrabbit.core.SessionImpl;
import org.apache.jackrabbit.core.ItemManager;
-import org.apache.jackrabbit.core.Path;
-import org.apache.jackrabbit.core.MalformedPathException;
-import org.apache.jackrabbit.core.NoPrefixDeclaredException;
import org.apache.jackrabbit.core.AccessManagerImpl;
import org.apache.jackrabbit.core.NodeId;
import org.apache.jackrabbit.core.AccessManager;
-import org.apache.jackrabbit.core.NamespaceResolver;
import org.apache.lucene.search.Hits;
import org.apache.lucene.search.Query;
+import org.apache.log4j.Logger;
-import javax.jcr.nodetype.ConstraintViolationException;
-import javax.jcr.nodetype.NodeType;
-import javax.jcr.nodetype.NodeTypeManager;
import javax.jcr.nodetype.PropertyDef;
import javax.jcr.query.InvalidQueryException;
import javax.jcr.query.QueryResult;
-import javax.jcr.*;
-import javax.jcr.lock.LockException;
-import javax.jcr.version.VersionException;
+import javax.jcr.RepositoryException;
import java.util.List;
import java.util.ArrayList;
import java.util.Collections;
import java.io.IOException;
/**
+ * Implements the {@link ExecutableQuery} interface.
*/
-class QueryImpl implements javax.jcr.query.Query {
+class QueryImpl implements ExecutableQuery {
- /**
- * jcr:statement
- */
- private static final QName PROP_STATEMENT =
- new QName(NamespaceRegistryImpl.NS_JCR_URI, "statement");
-
- /**
- * jcr:language
- */
- private static final QName PROP_LANGUAGE =
- new QName(NamespaceRegistryImpl.NS_JCR_URI, "language");
+ /** The logger instance for this class */
+ private static final Logger log = Logger.getLogger(QueryImpl.class);
+ /** The root node of the query tree */
private final QueryRootNode root;
+ /** The session of the user executing this query */
private final SessionImpl session;
+ /** The item manager of the user executing this query */
private final ItemManager itemMgr;
+ /** The actual search index */
private final SearchIndex index;
- private final String statement;
-
- private final String language;
-
- private Path path;
-
+ /**
+ * Creates a new query instance from a query string.
+ * @param session the session of the user executing this query.
+ * @param itemMgr the item manager of the session executing this query.
+ * @param index the search index.
+ * @param statement the query statement.
+ * @param language the syntax of the query statement.
+ * @throws InvalidQueryException if the query statement is invalid according
+ * to the specified <code>language</code>.
+ */
public QueryImpl(SessionImpl session,
ItemManager itemMgr,
SearchIndex index,
@@ -91,56 +83,17 @@
this.session = session;
this.itemMgr = itemMgr;
this.index = index;
- this.statement = statement;
- this.language = language;
-
// parse query according to language
// build query tree
this.root = QueryParser.parse(statement, language, session.getNamespaceResolver());
}
- public QueryImpl(SessionImpl session,
- ItemManager itemMgr,
- SearchIndex index,
- String absPath)
- throws ItemNotFoundException, InvalidQueryException, RepositoryException {
-
- this.session = session;
- this.itemMgr = itemMgr;
- this.index = index;
-
- try {
- Node query = null;
- String relPath = absPath.substring(1);
- if (session.getRootNode().hasNode(relPath)) {
- query = session.getRootNode().getNode(relPath);
- // assert query has mix:referenceable
- query.getUUID();
- NodeTypeManager ntMgr = session.getWorkspace().getNodeTypeManager();
- NodeType ntQuery = ntMgr.getNodeType(NodeTypeRegistry.NT_QUERY.toJCRName(session.getNamespaceResolver()));
- if (!query.getPrimaryNodeType().equals(ntQuery)) {
- throw new InvalidQueryException("node is not of type nt:query");
- }
- } else {
- throw new ItemNotFoundException(absPath);
- }
-
- path = Path.create(absPath, session.getNamespaceResolver(), true);
-
- statement = query.getProperty(PROP_STATEMENT.toJCRName(session.getNamespaceResolver())).getString();
- language = query.getProperty(PROP_LANGUAGE.toJCRName(session.getNamespaceResolver())).getString();
-
- // parse query according to language
- // build query tree and pass to QueryImpl
- QueryRootNode root = QueryParser.parse(statement, language, session.getNamespaceResolver());
- this.root = root;
- } catch (NoPrefixDeclaredException e) {
- throw new InvalidQueryException(e.getMessage(), e);
- } catch (MalformedPathException e) {
- throw new ItemNotFoundException(absPath, e);
- }
- }
-
+ /**
+ * Executes this query and returns a <code>{@link QueryResult}</code>.
+ *
+ * @return a <code>QueryResult</code>
+ * @throws RepositoryException if an error occurs
+ */
public QueryResult execute() throws RepositoryException {
// build lucene query
Query query = LuceneQueryBuilder.createQuery(root,
@@ -163,21 +116,27 @@
List uuids;
+ List scores;
AccessManagerImpl accessMgr = session.getAccessManager();
// execute it
try {
Hits result = index.executeQuery(query, orderProperties, ascSpecs);
uuids = new ArrayList(result.length());
+ scores = new ArrayList(result.length());
+
for (int i = 0; i < result.length(); i++) {
String uuid = result.doc(i).get(FieldNames.UUID);
// check access
if (accessMgr.isGranted(new NodeId(uuid), AccessManager.READ)) {
uuids.add(uuid);
+ scores.add(new Float(result.score(i)));
}
}
} catch (IOException e) {
+ log.error("Exception while executing query: ", e);
uuids = Collections.EMPTY_LIST;
+ scores = Collections.EMPTY_LIST;
}
// get select properties
@@ -209,65 +168,8 @@
// return QueryResult
return new QueryResultImpl(itemMgr,
(String[]) uuids.toArray(new String[uuids.size()]),
+ (Float[]) scores.toArray(new Float[scores.size()]),
selectProps,
session.getNamespaceResolver());
}
-
- public String getStatement() {
- return statement;
- }
-
- public String getLanguage() {
- return language;
- }
-
- public String getPersistentQueryPath() throws ItemNotFoundException {
- if (path == null) {
- throw new ItemNotFoundException("not a persistent query");
- }
- try {
- return path.toJCRPath(session.getNamespaceResolver());
- } catch (NoPrefixDeclaredException e) {
- // should not happen actually
- throw new ItemNotFoundException(path.toString());
- }
- }
-
- public void save(String absPath)
- throws ItemExistsException,
- PathNotFoundException,
- VersionException,
- ConstraintViolationException,
- LockException,
- UnsupportedRepositoryOperationException,
- RepositoryException {
- try {
- NamespaceResolver resolver = session.getNamespaceResolver();
- Path p = Path.create(absPath, resolver, true);
- if (!p.isAbsolute()) {
- throw new RepositoryException(absPath + " is not absolut");
- }
- if (!session.getRootNode().hasNode(p.getAncestor(1).toJCRPath(resolver).substring(1))) {
- throw new PathNotFoundException(p.getAncestor(1).toJCRPath(resolver));
- }
- String relPath = p.toJCRPath(resolver).substring(1);
- if (session.getRootNode().hasNode(relPath)) {
- throw new ItemExistsException(p.toJCRPath(resolver));
- }
- Node queryNode = session.getRootNode().addNode(relPath,
- NodeTypeRegistry.NT_QUERY.toJCRName(resolver));
- // set properties
- queryNode.setProperty(PROP_LANGUAGE.toJCRName(resolver), language);
- queryNode.setProperty(PROP_STATEMENT.toJCRName(resolver), statement);
- // add mixin referenceable
- queryNode.addMixin(NodeTypeRegistry.MIX_REFERENCEABLE.toJCRName(resolver));
- // FIXME do anything else?
- queryNode.getParent().save();
- } catch (MalformedPathException e) {
- throw new RepositoryException(e.getMessage(), e);
- } catch (NoPrefixDeclaredException e) {
- throw new RepositoryException(e.getMessage(), e);
- }
- }
-
}
Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/QueryResultImpl.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/QueryResultImpl.java?view=diff&r1=152653&r2=152654
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/QueryResultImpl.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/QueryResultImpl.java Tue Feb 8 01:36:54 2005
@@ -32,21 +32,39 @@
*/
class QueryResultImpl implements QueryResult {
+ /** The logger instance for this class */
private static final Logger log = Logger.getLogger(QueryResultImpl.class);
+ /** The item manager of the session executing the query */
private final ItemManager itemMgr;
+ /** The UUIDs of the result nodes */
private final String[] uuids;
+ /** The scores of the result nodes */
+ private final Float[] scores;
+
+ /** The select properties */
private final QName[] selectProps;
+ /** The namespace resolver of the session executing the query */
private final NamespaceResolver resolver;
+ /**
+ * Creates a new query result.
+ * @param itemMgr the item manager of the session executing the query.
+ * @param uuids the UUIDs of the result nodes.
+ * @param scores the score values of the result nodes.
+ * @param selectProps the select properties of the query.
+ * @param resolver the namespace resolver of the session executing the query.
+ */
public QueryResultImpl(ItemManager itemMgr,
String[] uuids,
+ Float[] scores,
QName[] selectProps,
NamespaceResolver resolver) {
this.uuids = uuids;
+ this.scores = scores;
this.itemMgr = itemMgr;
this.selectProps = selectProps;
this.resolver = resolver;
@@ -75,13 +93,13 @@
* @see QueryResult#getNodes()
*/
public NodeIterator getNodes() throws RepositoryException {
- return new NodeIteratorImpl(itemMgr, uuids);
+ return new NodeIteratorImpl(itemMgr, uuids, scores);
}
/**
* @see QueryResult#getRows()
*/
public RowIterator getRows() throws RepositoryException {
- return new RowIteratorImpl(new NodeIteratorImpl(itemMgr, uuids), selectProps, resolver);
+ return new RowIteratorImpl(new NodeIteratorImpl(itemMgr, uuids, scores), selectProps, resolver);
}
}
Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/RowIteratorImpl.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/RowIteratorImpl.java?view=diff&r1=152653&r2=152654
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/RowIteratorImpl.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/lucene/RowIteratorImpl.java Tue Feb 8 01:36:54 2005
@@ -22,12 +22,15 @@
import org.apache.jackrabbit.core.PropertyImpl;
import org.apache.jackrabbit.core.IllegalNameException;
import org.apache.jackrabbit.core.UnknownPrefixException;
+import org.apache.jackrabbit.core.search.Constants;
import javax.jcr.query.RowIterator;
import javax.jcr.query.Row;
import javax.jcr.Value;
import javax.jcr.RepositoryException;
import javax.jcr.ItemNotFoundException;
+import javax.jcr.PathValue;
+import javax.jcr.LongValue;
import java.util.Arrays;
import java.util.Set;
import java.util.HashSet;
@@ -70,7 +73,7 @@
* <code>Row</code>s.
*/
public Row nextRow() {
- return new RowImpl(nodes.nextNodeImpl());
+ return new RowImpl(nodes.getScore(), nodes.nextNodeImpl());
}
/**
@@ -143,6 +146,9 @@
*/
class RowImpl implements Row {
+ /** The score for this result row */
+ private final float score;
+
/** The underlying <code>Node</code> of this result row. */
private final NodeImpl node;
@@ -154,9 +160,11 @@
/**
* Creates a new <code>RowImpl</code> instance based on <code>node</code>.
+ * @param score the score value for this result row
* @param node the underlying <code>Node</code> for this <code>Row</code>.
*/
- RowImpl(NodeImpl node) {
+ RowImpl(float score, NodeImpl node) {
+ this.score = score;
this.node = node;
}
@@ -182,8 +190,14 @@
tmp[i] = null;
}
} else {
- // property not set
- tmp[i] = null;
+ // property not set or jcr:path / jcr:score
+ if (Constants.JCR_PATH.equals(properties[i])) {
+ tmp[i] = PathValue.valueOf(node.getPath());
+ } else if (Constants.JCR_SCORE.equals(properties[i])) {
+ tmp[i] = new LongValue((int) (score * 1000f));
+ } else {
+ tmp[i] = null;
+ }
}
}
values = tmp;
@@ -218,7 +232,14 @@
if (node.hasProperty(prop)) {
return node.getProperty(prop).getValue();
} else {
- return null;
+ // either jcr:score / jcr:path or not set
+ if (Constants.JCR_PATH.equals(prop)) {
+ return PathValue.valueOf(node.getPath());
+ } else if (Constants.JCR_SCORE.equals(prop)) {
+ return new LongValue((int) (score * 1000f));
+ } else {
+ return null;
+ }
}
} catch (IllegalNameException e) {
throw new RepositoryException(e.getMessage(), e);
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&r1=152653&r2=152654
==============================================================================
--- 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 Tue Feb 8 01:36:54 2005
@@ -20,6 +20,8 @@
import org.apache.jackrabbit.core.fs.FileSystemException;
import org.apache.jackrabbit.core.fs.FileSystemResource;
import org.apache.jackrabbit.core.search.AbstractQueryHandler;
+import org.apache.jackrabbit.core.search.Constants;
+import org.apache.jackrabbit.core.search.ExecutableQuery;
import org.apache.jackrabbit.core.state.NodeState;
import org.apache.jackrabbit.core.SessionImpl;
import org.apache.jackrabbit.core.ItemManager;
@@ -37,7 +39,6 @@
import javax.jcr.query.InvalidQueryException;
import javax.jcr.RepositoryException;
-import javax.jcr.ItemNotFoundException;
import java.io.IOException;
/**
@@ -163,7 +164,7 @@
* @throws InvalidQueryException if statement is invalid or language is unsupported.
* @return A <code>Query</code> object.
*/
- public javax.jcr.query.Query createQuery(SessionImpl session,
+ public ExecutableQuery createExecutableQuery(SessionImpl session,
ItemManager itemMgr,
String statement,
String language)
@@ -172,26 +173,6 @@
}
/**
- * Retrieves an existing persistent query. If <code>node</code>
- * is not a valid persisted query (that is, a node of type
- * <code>nt:query</code>), an <code>InvalidQueryException</code>
- * is thrown.
- *
- * @param absPath path to a persisted query (that is, a node of type
- * <code>nt:query</code>).
- * @throws InvalidQueryException If <code>absPath</code> is not a valid persisted query
- * (that is, a node of type <code>nt:query</code>).
- * @throws RepositoryException if another error occurs
- * @return a <code>Query</code> object.
- */
- public javax.jcr.query.Query createQuery(SessionImpl session,
- ItemManager itemMgr,
- String absPath)
- throws ItemNotFoundException, RepositoryException {
- return new QueryImpl(session, itemMgr, this, absPath);
- }
-
- /**
* Closes this <code>QueryHandler</code> and frees resources attached
* to this handler.
*/
@@ -214,19 +195,22 @@
try {
readWriteLock.readLock().acquire();
} catch (InterruptedException e) {
- // FIXME: ??? do logging, simply return?
- return null;
+ throw new IOException("Unable to obtain read lock on search index.");
}
SortField[] sortFields = new SortField[orderProps.length];
for (int i = 0; i < orderProps.length; i++) {
String prop = null;
- try {
- prop = orderProps[i].toJCRName(nsMappings);
- } catch (NoPrefixDeclaredException e) {
- // will never happen
+ if (Constants.JCR_SCORE.equals(orderProps[i])) {
+ sortFields[i] = new SortField(null, SortField.SCORE, !orderSpecs[i]);
+ } else {
+ try {
+ prop = orderProps[i].toJCRName(nsMappings);
+ } catch (NoPrefixDeclaredException e) {
+ // will never happen
+ }
+ sortFields[i] = new SortField(prop, SortField.STRING, !orderSpecs[i]);
}
- sortFields[i] = new SortField(prop, SortField.STRING, !orderSpecs[i]);
}
Hits hits = null;
Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/sql/JCRSQLQueryBuilder.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/sql/JCRSQLQueryBuilder.java?view=diff&r1=152653&r2=152654
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/sql/JCRSQLQueryBuilder.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/sql/JCRSQLQueryBuilder.java Tue Feb 8 01:36:54 2005
@@ -31,7 +31,6 @@
import org.apache.jackrabbit.core.search.LocationStepQueryNode;
import org.apache.jackrabbit.core.NamespaceResolver;
import org.apache.jackrabbit.core.QName;
-import org.apache.jackrabbit.core.NamespaceRegistryImpl;
import org.apache.jackrabbit.core.IllegalNameException;
import org.apache.jackrabbit.core.UnknownPrefixException;
import org.apache.jackrabbit.core.nodetype.NodeTypeRegistry;
@@ -57,11 +56,6 @@
*/
private static final String DATE_PATTERN = "yyyy-MM-dd";
- /**
- * QName for jcr:path
- */
- static final QName JCR_PATH = new QName(NamespaceRegistryImpl.NS_JCR_URI, "path");
-
/** The root node of the sql query syntax tree */
private final ASTQuery stmt;
@@ -74,10 +68,6 @@
/** Query node to gather the constraints defined in the WHERE clause */
private final AndQueryNode constraintNode = new AndQueryNode(null);
- public JCRSQLQueryBuilder() {
- stmt = null;
- }
-
/**
* Creates a new <code>JCRSQLQueryBuilder</code>.
* @param statement the root node of the SQL syntax tree.
@@ -212,7 +202,7 @@
}, data);
QName identifier = tmp[0];
- if (identifier.equals(JCR_PATH)) {
+ if (identifier.equals(Constants.JCR_PATH)) {
if (node.children[1] instanceof ASTIdentifier) {
// simply ignore, this is a join of a mixin node type
} else {
Modified: incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/sql/QueryFormat.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/sql/QueryFormat.java?view=diff&r1=152653&r2=152654
==============================================================================
--- incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/sql/QueryFormat.java (original)
+++ incubator/jackrabbit/trunk/src/java/org/apache/jackrabbit/core/search/sql/QueryFormat.java Tue Feb 8 01:36:54 2005
@@ -265,7 +265,7 @@
public Object visit(PathQueryNode node, Object data) {
StringBuffer sb = (StringBuffer) data;
try {
- sb.append(JCRSQLQueryBuilder.JCR_PATH.toJCRName(resolver));
+ sb.append(Constants.JCR_PATH.toJCRName(resolver));
sb.append(" LIKE '");
LocationStepQueryNode[] steps = node.getPathSteps();
for (int i = 0; i < steps.length; i++) {
Modified: 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=diff&r1=152653&r2=152654
==============================================================================
--- incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/search/OrderByTest.java (original)
+++ incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/search/OrderByTest.java Tue Feb 8 01:36:54 2005
@@ -157,6 +157,32 @@
checkResultOrder(result, new String[]{"node1", "node2", "node3"});
}
+ public void testOrderByScore() throws RepositoryException {
+ 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();
+
+ String sql = "SELECT value, jcr:score FROM nt:unstructured WHERE " +
+ "jcr:path LIKE '/" + testRoot + "/%' ORDER BY jcr:score, value";
+ Query q = superuser.getWorkspace().getQueryManager().createQuery(sql, Query.SQL);
+ QueryResult result = q.execute();
+ checkResult(result, 3);
+
+ String xpath = "/" + testRoot + "/*[@jcr:primaryType='nt:unstructured'] order by @jcr:score, @value";
+ q = superuser.getWorkspace().getQueryManager().createQuery(xpath, Query.XPATH);
+ result = q.execute();
+ checkResult(result, 3);
+ }
+
//------------------< internal >--------------------------------------------
private void populate(String[] values) throws RepositoryException {
Modified: incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/search/SelectClauseTest.java
URL: http://svn.apache.org/viewcvs/incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/search/SelectClauseTest.java?view=diff&r1=152653&r2=152654
==============================================================================
--- incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/search/SelectClauseTest.java (original)
+++ incubator/jackrabbit/trunk/src/test/org/apache/jackrabbit/test/search/SelectClauseTest.java Tue Feb 8 01:36:54 2005
@@ -36,20 +36,20 @@
testRootNode.save();
- String sql = "SELECT myvalue FROM \"" + ntBase
- + "\" WHERE \"jcr:path\" LIKE '" + testRoot + "/%'";
+ String sql = "SELECT myvalue FROM " + ntBase + " WHERE " +
+ "jcr:path LIKE '" + testRoot + "/%' AND myvalue IS NOT NULL";
Query q = superuser.getWorkspace().getQueryManager().createQuery(sql, Query.SQL);
QueryResult result = q.execute();
checkResult(result, 2);
- sql = "SELECT myvalue FROM \"" + ntBase
- + "\" WHERE \"jcr:path\" LIKE '" + testRoot + "/%'"
- + " AND yourvalue = 'foo'";
+ sql = "SELECT myvalue FROM " + ntBase
+ + " WHERE jcr:path LIKE '" + testRoot + "/%'"
+ + " AND yourvalue = 'foo' AND myvalue IS NOT NULL";
q = superuser.getWorkspace().getQueryManager().createQuery(sql, Query.SQL);
result = q.execute();
checkResult(result, 0);
- sql = "SELECT myvalue FROM \"" + ntBase + "\"";
+ sql = "SELECT myvalue FROM " + ntBase + " WHERE myvalue IS NOT NULL";
q = superuser.getWorkspace().getQueryManager().createQuery(sql, Query.SQL);
result = q.execute();
checkResult(result, 2);
@@ -65,26 +65,26 @@
testRootNode.save();
- String sql = "SELECT myvalue FROM \"" + ntBase
- + "\" WHERE \"jcr:path\" LIKE '" + testRoot + "/%'";
+ String sql = "SELECT myvalue FROM " + ntBase + " WHERE " +
+ "jcr:path LIKE '" + testRoot + "/%' AND myvalue IS NOT NULL";
Query q = superuser.getWorkspace().getQueryManager().createQuery(sql, Query.SQL);
QueryResult result = q.execute();
checkResult(result, 2, 2);
- sql = "SELECT myvalue FROM \"" + ntBase
- + "\" WHERE \"jcr:path\" LIKE '" + testRoot + "/%'"
- + " AND yourvalue = 'foo'";
+ sql = "SELECT myvalue FROM " + ntBase
+ + " WHERE jcr:path LIKE '" + testRoot + "/%'"
+ + " AND yourvalue = 'foo' AND myvalue IS NOT NULL";
q = superuser.getWorkspace().getQueryManager().createQuery(sql, Query.SQL);
result = q.execute();
checkResult(result, 0, 0);
- sql = "SELECT myvalue FROM \"" + ntBase + "\"";
+ sql = "SELECT myvalue FROM " + ntBase + " WHERE myvalue IS NOT NULL";
q = superuser.getWorkspace().getQueryManager().createQuery(sql, Query.SQL);
result = q.execute();
checkResult(result, 2, 2);
- sql = "SELECT * FROM \"" + ntBase
- + "\" WHERE \"jcr:path\" LIKE '" + testRoot + "/%'"
+ sql = "SELECT * FROM " + ntBase
+ + " WHERE jcr:path LIKE '" + testRoot + "/%'"
+ " AND myvalue LIKE '%'";
q = superuser.getWorkspace().getQueryManager().createQuery(sql, Query.SQL);
result = q.execute();
@@ -101,8 +101,8 @@
testRootNode.save();
- String sql = "SELECT myvalue FROM \"" + ntBase
- + "\" WHERE \"jcr:path\" LIKE '" + testRoot + "/node'";
+ String sql = "SELECT myvalue FROM " + ntBase + " WHERE " +
+ "jcr:path LIKE '" + testRoot + "/node' AND myvalue IS NOT NULL";
Query q = superuser.getWorkspace().getQueryManager().createQuery(sql, Query.SQL);
QueryResult result = q.execute();
checkResult(result, 2, 2);