Index: oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/query/runner/LinkedQueryBinder.java =================================================================== --- oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/query/runner/LinkedQueryBinder.java (revision 0) +++ oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/query/runner/LinkedQueryBinder.java (working copy) @@ -0,0 +1,51 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.oak.jcr.query.runner; + +/** + * Allows specify more variables binding or setting the query limit/offset. + * + * @since 0.6 + */ +public interface LinkedQueryBinder extends QueryExecutor { + + /** + * Prepare a a property name in the query statement to be bound to a value. + * + * @param varName a String representing a variable name in the query statement + * that has to be bound to a value + * @return a {@code ValueBinder} instance + */ + ValueBinder and(String variableName); + + /** + * Sets the maximum size of the result set to {@code limit}. + * + * @param limit the maximum size of the result + * @return a {@link LinkedQueryBinder} instance + */ + LinkedQueryBinder limit(long limit); + + /** + * Sets the start offset of the result set to {@code offset}. + * + * @param the start offset of the result + * @return a {@link LinkedQueryBinder} instance + */ + LinkedQueryBinder offset(long offset); + +} Property changes on: oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/query/runner/LinkedQueryBinder.java ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Date Author Id Revision HeadURL \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Index: oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/query/runner/QueryBinder.java =================================================================== --- oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/query/runner/QueryBinder.java (revision 0) +++ oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/query/runner/QueryBinder.java (working copy) @@ -0,0 +1,35 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.oak.jcr.query.runner; + +/** + * Allows binding a property name in a query statement to a related value. + * + * @since 0.6 + */ +public interface QueryBinder extends QueryExecutor { + + /** + * Prepare a a property name in the query statement to be bound to a value. + * + * @param varName a String representing a variable name in the query statement + * that has to be bound to a value + * @return a {@code ValueBinder} instance + */ + ValueBinder where(String varName); + +} Property changes on: oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/query/runner/QueryBinder.java ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Date Author Id Revision HeadURL \ No newline at end of property Index: oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/query/runner/QueryExecutor.java =================================================================== --- oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/query/runner/QueryExecutor.java (revision 0) +++ oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/query/runner/QueryExecutor.java (working copy) @@ -0,0 +1,38 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.oak.jcr.query.runner; + +import javax.jcr.RepositoryException; + +/** + * Delegate to execute the built query. + * + * @since 0.6 + */ +public interface QueryExecutor { + + /** + * Executes the built query and returns a result object. + * + * @param the type of object that the handler returns + * @param handler the handler used to create the result object from the {@code QueryResult} + * @return an object generated by the handler + * @throws RepositoryException if any error occurs + */ + T execute(QueryResultHandler handler) throws RepositoryException; + +} Property changes on: oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/query/runner/QueryExecutor.java ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Date Author Id Revision HeadURL \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Index: oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/query/runner/QueryResultHandler.java =================================================================== --- oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/query/runner/QueryResultHandler.java (revision 0) +++ oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/query/runner/QueryResultHandler.java (working copy) @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.oak.jcr.query.runner; + +import javax.jcr.RepositoryException; +import javax.jcr.query.QueryResult; + +/** + * Implementations of this interface convert {@code QueryResult} into other objects. + * + * @param the target type the input {@code QueryResult} will be converted to. + * @since 0.6 + */ +public interface QueryResultHandler { + + /** + * Turn the {@code QueryResult} into an Object. + * + * @param queryResult The {@code QueryResult} to handle + * @return An Object initialized with {@code QueryResult} data + * @throws RepositoryException if a repository error occurs + */ + T handle(QueryResult queryResult) throws RepositoryException; + +} Property changes on: oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/query/runner/QueryResultHandler.java ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Date Author Id Revision HeadURL \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Index: oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/query/runner/QueryRunner.java =================================================================== --- oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/query/runner/QueryRunner.java (revision 0) +++ oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/query/runner/QueryRunner.java (working copy) @@ -0,0 +1,261 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.oak.jcr.query.runner; + +import static javax.jcr.query.Query.JCR_JQOM; +import static javax.jcr.query.Query.JCR_SQL2; +import static javax.jcr.query.Query.SQL; +import static javax.jcr.query.Query.XPATH; +import static com.google.common.base.Preconditions.checkArgument; + +import java.math.BigDecimal; +import java.util.Calendar; + +import javax.jcr.Binary; +import javax.jcr.RepositoryException; +import javax.jcr.Value; +import javax.jcr.query.InvalidQueryException; +import javax.jcr.query.Query; +import javax.jcr.query.QueryManager; +import javax.jcr.query.QueryResult; + +import org.apache.jackrabbit.value.BinaryValue; +import org.apache.jackrabbit.value.BooleanValue; +import org.apache.jackrabbit.value.DateValue; +import org.apache.jackrabbit.value.DecimalValue; +import org.apache.jackrabbit.value.DoubleValue; +import org.apache.jackrabbit.value.LongValue; +import org.apache.jackrabbit.value.StringValue; + +/** + * Executes SQL queries with pluggable strategies for handling {@code QueryResult}s. + * + * @since 0.6 + */ +public final class QueryRunner { + + /** + * Create a new {@code QueryRunner} adapting an existing {@code QueryManager} instance. + * + * @param queryManager the delegated {@code QueryManager} instance to execute queries. + * @return a new {@code QueryRunner} instance + */ + public static QueryRunner on(QueryManager queryManager) { + checkArgument(queryManager != null, "Impossible to set QueryManager"); + return new QueryRunner(queryManager); + } + + /** + * The adapted {@code QueryManager} to execute queries. + */ + private final QueryManager queryManager; + + /** + * Constructor for QueryRunner that takes a {@code QueryManager} to use. + * + * @param queryManager the QueryManager to use + */ + private QueryRunner(QueryManager queryManager) { + this.queryManager = queryManager; + } + + /** + * Shortcut to build a {@code JCR-JQOM} query. + * + * @param statement a string representing a {@code JCR-JQOM} statement. + * @return a {@link QueryBinder} instance + * @throws InvalidQueryException if the query statement is syntactically invalid + * @throws RepositoryException if another error occurs + */ + public QueryBinder jqomQuery(String statement) throws InvalidQueryException, RepositoryException { + return newQueryBinder(statement, JCR_JQOM); + } + + /** + * Shortcut to build a {@code JCR-SQL2} query. + * + * @param statement a string representing a {@code JCR-SQL2} statement. + * @return a {@link QueryBinder} instance + * @throws InvalidQueryException if the query statement is syntactically invalid + * @throws RepositoryException if another error occurs + */ + public QueryBinder sql2Query(String statement) throws InvalidQueryException, RepositoryException { + return newQueryBinder(statement, JCR_SQL2); + } + + /** + * Shortcut to build a {@code sql} query. + * + * @param statement a string representing a {@code sql} statement. + * @return a {@link QueryBinder} instance + * @throws InvalidQueryException if the query statement is syntactically invalid + * @throws RepositoryException if another error occurs + * @deprecated As of JCR 2.0, this language is deprecated. + */ + @Deprecated + public QueryBinder sqlQuery(String statement) throws InvalidQueryException, RepositoryException { + return newQueryBinder(statement, SQL); + } + + /** + * Shortcut to build a {@code xpath} query. + * + * @param statement a string representing a {@code xpath} statement. + * @return a {@link QueryBinder} instance + * @throws InvalidQueryException if the query statement is syntactically invalid + * @throws RepositoryException if another error occurs + * @deprecated As of JCR 2.0, this language is deprecated. + */ + @Deprecated + public QueryBinder xPathQuery(String statement) throws InvalidQueryException, RepositoryException { + return newQueryBinder(statement, XPATH); + } + + private QueryBinder newQueryBinder(String statement, String language) throws InvalidQueryException, RepositoryException { + checkArgument(statement != null, "Null language not admitted"); + Query query = queryManager.createQuery(statement, language); + return new DefaultQueryBinder(query); + } + + private static abstract class DefaultQueryExecutor implements QueryExecutor { + + private final Query query; + + public DefaultQueryExecutor(Query query) { + this.query = query; + } + + Query getQuery() { + return query; + } + + public ValueBinder bind(String variableName) { + checkArgument(variableName != null, "Impossible to bind a null variable name"); + return new DefaultValueBinder(variableName, query); + } + + @Override + public final T execute(QueryResultHandler handler) throws RepositoryException { + checkArgument(handler != null, "QueryResultHandler cannot be null"); + QueryResult queryResult = query.execute(); + return handler.handle(queryResult); + } + + } + + private static final class DefaultQueryBinder + extends DefaultQueryExecutor + implements QueryBinder { + + public DefaultQueryBinder(Query query) { + super(query); + } + + @Override + public ValueBinder where(String variableName) { + return bind(variableName); + } + + } + + private static final class DefaultLinkedQueryBinder + extends DefaultQueryExecutor + implements LinkedQueryBinder { + + public DefaultLinkedQueryBinder(Query query) { + super(query); + } + + @Override + public ValueBinder and(String variableName) { + return bind(variableName); + } + + @Override + public LinkedQueryBinder limit(long limit) { + getQuery().setLimit(limit); + return this; + } + + @Override + public LinkedQueryBinder offset(long offset) { + getQuery().setOffset(offset); + return this; + } + + } + + private static final class DefaultValueBinder implements ValueBinder { + + private final String variableName; + + private final Query query; + + public DefaultValueBinder(String variableName, Query query) { + this.variableName = variableName; + this.query = query; + } + + @Override + public LinkedQueryBinder is(Binary binary) throws RepositoryException { + checkArgument(binary != null, "Impossible to bind %s variable to a null binary", variableName); + return is(new BinaryValue(binary)); + } + + @Override + public LinkedQueryBinder is(boolean value) throws RepositoryException { + return is(new BooleanValue(value)); + } + + @Override + public LinkedQueryBinder is(Calendar date) throws RepositoryException { + checkArgument(date != null, "Impossible to bind %s variable to a null date", variableName); + return is(new DateValue(date)); + } + + @Override + public LinkedQueryBinder is(BigDecimal decimal) throws RepositoryException { + checkArgument(decimal != null, "Impossible to bind %s variable to a null decimal", variableName); + return is(new DecimalValue(decimal)); + } + + @Override + public LinkedQueryBinder is(double doubleValue) throws RepositoryException { + return is(new DoubleValue(doubleValue)); + } + + @Override + public LinkedQueryBinder is(long longValue) throws RepositoryException { + return is(new LongValue(longValue)); + } + + @Override + public LinkedQueryBinder is(String value) throws RepositoryException { + checkArgument(value != null, "Impossible to bind %s variable to a null String", variableName); + return is(new StringValue(value)); + } + + @Override + public LinkedQueryBinder is(Value value) throws RepositoryException { + checkArgument(value != null, "Impossible to bind %s variable to a null value", variableName); + query.bindValue(variableName, value); + return new DefaultLinkedQueryBinder(query); + } + + } + +} Property changes on: oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/query/runner/QueryRunner.java ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Date Author Id Revision HeadURL \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Index: oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/query/runner/ValueBinder.java =================================================================== --- oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/query/runner/ValueBinder.java (revision 0) +++ oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/query/runner/ValueBinder.java (working copy) @@ -0,0 +1,105 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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.oak.jcr.query.runner; + +import java.math.BigDecimal; +import java.util.Calendar; + +import javax.jcr.Binary; +import javax.jcr.RepositoryException; +import javax.jcr.Value; + +/** + * Properties name to value binder. + * + * @since 0.6 + */ +public interface ValueBinder { + + /** + * Binds the given {@code value} to the previous set variable name. + * + * @param binaryValue value to bind + * @return a {@link LinkedQueryBinder} instance + * @throws RepositoryException if an error occurs + */ + LinkedQueryBinder is(Binary binaryValue) throws RepositoryException; + + /** + * Binds the given {@code value} to the previous set variable name. + * + * @param binaryValue value to bind + * @return a {@link LinkedQueryBinder} instance + * @throws RepositoryException if an error occurs + */ + LinkedQueryBinder is(boolean valueValue) throws RepositoryException; + + /** + * Binds the given {@code value} to the previous set variable name. + * + * @param binaryValue value to bind + * @return a {@link LinkedQueryBinder} instance + * @throws RepositoryException if an error occurs + */ + LinkedQueryBinder is(Calendar dateValue) throws RepositoryException; + + /** + * Binds the given {@code value} to the previous set variable name. + * + * @param binaryValue value to bind + * @return a {@link LinkedQueryBinder} instance + * @throws RepositoryException if an error occurs + */ + LinkedQueryBinder is(BigDecimal decimalValue) throws RepositoryException; + + /** + * Binds the given {@code value} to the previous set variable name. + * + * @param binaryValue value to bind + * @return a {@link LinkedQueryBinder} instance + * @throws RepositoryException if an error occurs + */ + LinkedQueryBinder is(double doubleValue) throws RepositoryException; + + /** + * Binds the given {@code value} to the previous set variable name. + * + * @param binaryValue value to bind + * @return a {@link LinkedQueryBinder} instance + * @throws RepositoryException if an error occurs + */ + LinkedQueryBinder is(long longValue) throws RepositoryException; + + /** + * Binds the given {@code value} to the previous set variable name. + * + * @param binaryValue value to bind + * @return a {@link LinkedQueryBinder} instance + * @throws RepositoryException if an error occurs + */ + LinkedQueryBinder is(String value) throws RepositoryException; + + /** + * Binds the given {@code value} to the previous set variable name. + * + * @param binaryValue value to bind + * @return a {@link LinkedQueryBinder} instance + * @throws RepositoryException if an error occurs + */ + LinkedQueryBinder is(Value value) throws RepositoryException; + +} Property changes on: oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/query/runner/ValueBinder.java ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Date Author Id Revision HeadURL \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Index: oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/query/runner/package-info.java =================================================================== --- oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/query/runner/package-info.java (revision 0) +++ oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/query/runner/package-info.java (working copy) @@ -0,0 +1,23 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ + +/** + * Fluent interfaces to run JCR queries. + * + * @since 0.6 + */ +package org.apache.jackrabbit.oak.jcr.query.runner; Property changes on: oak-jcr/src/main/java/org/apache/jackrabbit/oak/jcr/query/runner/package-info.java ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Date Author Id Revision HeadURL \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Index: oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/query/runner/QueryRunnerTestCase.java =================================================================== --- oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/query/runner/QueryRunnerTestCase.java (revision 0) +++ oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/query/runner/QueryRunnerTestCase.java (working copy) @@ -0,0 +1,156 @@ +package org.apache.jackrabbit.oak.jcr.query.runner; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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. + */ + +import static junit.framework.Assert.assertEquals; +import static junit.framework.Assert.assertTrue; +import static org.apache.jackrabbit.oak.jcr.query.runner.QueryRunner.on; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; + +import java.util.LinkedList; +import java.util.List; + +import javax.jcr.Node; +import javax.jcr.RepositoryException; +import javax.jcr.Session; +import javax.jcr.ValueFactory; +import javax.jcr.query.Query; +import javax.jcr.query.QueryManager; +import javax.jcr.query.QueryResult; +import javax.jcr.query.Row; +import javax.jcr.query.RowIterator; + +import org.apache.jackrabbit.oak.jcr.AbstractRepositoryTest; +import org.junit.Test; + +public class QueryRunnerTestCase extends AbstractRepositoryTest { + + @Test + @SuppressWarnings("deprecation") + public void simple() throws Exception { + Session session = getAdminSession(); + Node hello = session.getRootNode().addNode("hello"); + hello.setProperty("id", "1"); + hello.setProperty("text", "hello_world"); + session.save(); + Node hello2 = session.getRootNode().addNode("hello2"); + hello2.setProperty("id", "2"); + hello2.setProperty("text", "hello world"); + session.save(); + + QueryManager qm = session.getWorkspace().getQueryManager(); + + QueryResultHandler textHandler = new TextPropertyResultHandler(); + + // SQL-2 + + String text = on(qm) + .sql2Query("select text from [nt:base] where id = $id") + .where("id").is("1") + .execute(textHandler); + assertEquals("hello_world", text); + + // SQL + + text = on(qm) + .sqlQuery("select text from [nt:base] where text like 'hello\\_world' escape '\\'") + .execute(textHandler); + assertEquals("hello_world", text); + } + + private static final class TextPropertyResultHandler + implements QueryResultHandler { + + @Override + public String handle(QueryResult queryResult) + throws RepositoryException { + + RowIterator it = queryResult.getRows(); + if (it.hasNext()) { + Row row = it.nextRow(); + return row.getValue("text").getString(); + } + + return null; + } + + } + + @Test + public void limit() throws RepositoryException { + Session session = getAdminSession(); + Node hello1 = session.getRootNode().addNode("hello1"); + hello1.setProperty("id", "1"); + hello1.setProperty("data", "x"); + session.save(); + Node hello3 = session.getRootNode().addNode("hello3"); + hello3.setProperty("id", "3"); + hello3.setProperty("data", "z"); + session.save(); + Node hello2 = session.getRootNode().addNode("hello2"); + hello2.setProperty("id", "2"); + hello2.setProperty("data", "y"); + session.save(); + QueryManager qm = session.getWorkspace().getQueryManager(); + + for (int limit = 0; limit < 5; limit++) { + for (int offset = 0; offset < 3; offset++) { + on(qm) + .sql2Query("select id from [nt:base] where data >= $data order by id") + .where("data").is("x") + .limit(limit) + .offset(offset) + .execute(new LimitHandler(limit, offset)); + } + } + } + + private static final class LimitHandler implements QueryResultHandler { + + private final int limit, offset; + + public LimitHandler(int limit, int offset) { + super(); + this.limit = limit; + this.offset = offset; + } + + @Override + public Void handle(QueryResult queryResult) throws RepositoryException { + RowIterator it = queryResult.getRows(); + int l = Math.min(Math.max(0, 3 - offset), limit); + assertEquals(l, queryResult.getRows().getSize()); + assertEquals(l, queryResult.getNodes().getSize()); + Row row; + + for (int x = offset + 1, i = 0; i < limit && x < 4; i++, x++) { + assertTrue(it.hasNext()); + row = it.nextRow(); + assertEquals("" + x, row.getValue("id").getString()); + } + assertFalse(it.hasNext()); + + return null; + } + + } + +} Property changes on: oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/query/runner/QueryRunnerTestCase.java ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +Date Author Id Revision HeadURL \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property