Package org.apache.jackrabbit.oak.jcr.query

Source Code of org.apache.jackrabbit.oak.jcr.query.QueryTest

/*
* 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;

import static com.google.common.collect.Sets.newHashSet;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertTrue;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.fail;

import java.io.ByteArrayInputStream;
import java.util.Arrays;
import java.util.HashSet;
import java.util.NoSuchElementException;
import java.util.Set;

import javax.jcr.Node;
import javax.jcr.NodeIterator;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.ValueFactory;
import javax.jcr.query.InvalidQueryException;
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.commons.JcrUtils;
import org.apache.jackrabbit.oak.jcr.AbstractRepositoryTest;
import org.apache.jackrabbit.oak.jcr.NodeStoreFixture;
import org.junit.Ignore;
import org.junit.Test;

/**
* Tests the query feature.
*/
public class QueryTest extends AbstractRepositoryTest {

    public QueryTest(NodeStoreFixture fixture) {
        super(fixture);
    }
   
    @Test
    public void unicode() throws Exception {
        Session session = getAdminSession();
        Node content = session.getRootNode().addNode("test");
        String[][] list = {
                {"three", "\u00e4\u00f6\u00fc"},
                {"two", "123456789"},
                {"one", "\u3360\u3361\u3362\u3363\u3364\u3365\u3366\u3367\u3368\u3369"},
        };
        for (String[] pair : list) {
            content.addNode(pair[0]).setProperty("prop",
                    "propValue testSearch " + pair[1] + " data");
        }
        session.save();
        for (String[] pair : list) {
            String query = "//*[jcr:contains(., '" + pair[1] + "')]";
            QueryResult r = session.getWorkspace().
                    getQueryManager().createQuery(
                    query, "xpath").execute();
            NodeIterator it = r.getNodes();
            assertTrue(it.hasNext());
            String path = it.nextNode().getPath();
            assertEquals("/test/" + pair[0], path);
            assertFalse(it.hasNext());
        }       
    }
   
    @Test
    @Ignore("OAK-1215")
    public void anyChildNodeProperty() throws Exception {
        Session session = getAdminSession();
        Node content = session.getRootNode().addNode("test");
        content.addNode("one").addNode("child").setProperty("prop", "hello");
        content.addNode("two").addNode("child").setProperty("prop", "hi");
        session.save();
        String query = "//*[*/@prop = 'hello']";
        QueryResult r = session.getWorkspace().getQueryManager().createQuery(
                query, "xpath").execute();
        NodeIterator it = r.getNodes();
        assertTrue(it.hasNext());
        String path = it.nextNode().getPath();
        assertEquals("/test/one", path);
        assertFalse(it.hasNext());
       
        query = "//*[*/*/@prop = 'hello']";
        r = session.getWorkspace().getQueryManager().createQuery(
                query, "xpath").execute();
        it = r.getNodes();
        assertTrue(it.hasNext());
        path = it.nextNode().getPath();
        assertEquals("/test", path);
        assertFalse(it.hasNext());

    }
   
    @Test
    public void relativeNotExistsProperty() throws Exception {
        Session session = getAdminSession();
        Node content = session.getRootNode().addNode("test");
        content.addNode("one").addNode("child").setProperty("prop", "hello");
        content.addNode("two").addNode("child");
        session.save();
        String query = "//*[not(child/@prop)]";
        QueryResult r = session.getWorkspace().getQueryManager().createQuery(
                query, "xpath").execute();
        NodeIterator it = r.getNodes();
        assertTrue(it.hasNext());
        String path = it.nextNode().getPath();
        assertEquals("/test/two", path);
        assertFalse(it.hasNext());
    }

    @Test
    public void doubleQuote() throws RepositoryException {
        Session session = getAdminSession();
        Node hello = session.getRootNode().addNode("hello");
        hello.setProperty("x", 1);
        Node world = hello.addNode("world");
        world.setProperty("x", 2);
        session.save();
        QueryManager qm = session.getWorkspace().getQueryManager();
        Query q;
        q = qm.createQuery(
                "SELECT * FROM [nt:base] AS s WHERE ISDESCENDANTNODE(s,[/hello])",
                Query.JCR_SQL2);
        assertEquals("/hello/world", getPaths(q));
        q = qm.createQuery(
                "SELECT * FROM [nt:base] AS s WHERE ISDESCENDANTNODE(s,\"/hello\")",
                Query.JCR_SQL2);
        assertEquals("/hello/world", getPaths(q));
        try {
            q = qm.createQuery(
                    "SELECT * FROM [nt:base] AS s WHERE ISDESCENDANTNODE(s,[\"/hello\"])",
                    Query.JCR_SQL2);
            getPaths(q);
            fail();
        } catch (InvalidQueryException e) {
            // expected: absolute path
        }
    }

    @SuppressWarnings("deprecation")
    @Test
    public void or() throws RepositoryException {
        Session session = getAdminSession();
        Node hello = session.getRootNode().addNode("hello");
        hello.setProperty("x", 1);
        Node world = hello.addNode("world");
        world.setProperty("x", 2);
        session.save();
        QueryManager qm = session.getWorkspace().getQueryManager();
        Query q;
       
        q = qm.createQuery("select a.[jcr:path] from [nt:base] as a " +
                    "inner join [nt:base] as b " +
                    "on ischildnode(a, b) " +
                    "where a.x = 1 or a.x = 2 or b.x = 3 or b.x = 4", Query.JCR_SQL2);
        assertEquals("/hello", getPaths(q));

        q = qm.createQuery("//hello[@x=1]/*[@x=2]", Query.XPATH);
        assertEquals("/hello/world", getPaths(q));

    }

    @SuppressWarnings("deprecation")
    @Test
    public void encodedPath() throws RepositoryException {
        Session session = getAdminSession();
        session.getRootNode().addNode("hello").addNode("world");
        session.save();
        QueryManager qm = session.getWorkspace().getQueryManager();
        Query q;
       
        q = qm.createQuery("/jcr:root/hel_x006c_o/*", Query.XPATH);
        assertEquals("/hello/world", getPaths(q));
       
        q = qm.createQuery("//hel_x006c_o", Query.XPATH);
        assertEquals("/hello", getPaths(q));
       
        q = qm.createQuery("//element(hel_x006c_o, nt:base)", Query.XPATH);
        assertEquals("/hello", getPaths(q));

    }
   
    private static String getPaths(Query q) throws RepositoryException {
        QueryResult r = q.execute();
        RowIterator it = r.getRows();
        StringBuilder buff = new StringBuilder();
        if (it.hasNext()) {
            Row row = it.nextRow();
            if (buff.length() > 0) {
                buff.append(", ");
            }
            buff.append(row.getPath());
        }
        return buff.toString();
    }

    @SuppressWarnings("deprecation")
    @Test
    public void simple() throws RepositoryException {
        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();

        ValueFactory vf = session.getValueFactory();

        QueryManager qm = session.getWorkspace().getQueryManager();

        // SQL-2

        Query q = qm.createQuery("select text from [nt:base] where id = $id", Query.JCR_SQL2);
        q.bindValue("id", vf.createValue("1"));
        QueryResult r = q.execute();
        RowIterator it = r.getRows();
        assertTrue(it.hasNext());
        Row row = it.nextRow();
        assertEquals("hello_world", row.getValue("text").getString());
        String[] columns = r.getColumnNames();
        assertEquals(1, columns.length);
        assertEquals("text", columns[0]);
        assertFalse(it.hasNext());

        r = q.execute();
        NodeIterator nodeIt = r.getNodes();
        assertTrue(nodeIt.hasNext());
        Node n = nodeIt.nextNode();
        assertEquals("hello_world", n.getProperty("text").getString());
        assertFalse(it.hasNext());

        // SQL

        q = qm.createQuery("select text from [nt:base] where text like 'hello\\_world' escape '\\'", Query.SQL);
        r = q.execute();
        columns = r.getColumnNames();
        assertEquals(3, columns.length);
        assertEquals("text", columns[0]);
        assertEquals("jcr:path", columns[1]);
        assertEquals("jcr:score", columns[2]);
        nodeIt = r.getNodes();
        assertTrue(nodeIt.hasNext());
        n = nodeIt.nextNode();
        assertEquals("hello_world", n.getProperty("text").getString());
        assertFalse(nodeIt.hasNext());

        // XPath

        q = qm.createQuery("//*[@id=1]", Query.XPATH);
        r = q.execute();
        assertEquals(
                newHashSet("jcr:path", "jcr:score", "jcr:primaryType"),
                newHashSet(r.getColumnNames()));
    }

    @Test
    public void skip() throws RepositoryException {
        Session session = getAdminSession();
        Node hello1 = session.getRootNode().addNode("hello1");
        hello1.setProperty("id""1");
        hello1.setProperty("data""x");
        session.save();
        Node hello3 = hello1.addNode("hello3");
        hello3.setProperty("id""3");
        hello3.setProperty("data""z");
        session.save();
        Node hello2 = hello3.addNode("hello2");
        hello2.setProperty("id""2");
        hello2.setProperty("data""y");
        session.save();
        ValueFactory vf = session.getValueFactory();
        QueryManager qm = session.getWorkspace().getQueryManager();
        Query q = qm.createQuery("select id from [nt:base] where data >= $data order by id", Query.JCR_SQL2);
        q.bindValue("data", vf.createValue("x"));
        for (int i = -1; i < 5; i++) {
            QueryResult r = q.execute();
            RowIterator it = r.getRows();
            assertEquals(3, r.getRows().getSize());
            assertEquals(3, r.getNodes().getSize());
            Row row;
            try {
                it.skip(i);
                assertTrue(i >= 0 && i <= 3);
            } catch (IllegalArgumentException e) {
                assertEquals(-1, i);
            } catch (NoSuchElementException e) {
                assertTrue(i >= 2);
            }
            if (i <= 0) {
                assertTrue(it.hasNext());
                row = it.nextRow();
                assertEquals("1", row.getValue("id").getString());
            }
            if (i <= 1) {
                assertTrue(it.hasNext());
                row = it.nextRow();
                assertEquals("2", row.getValue("id").getString());
            }
            if (i <= 2) {
                assertTrue(it.hasNext());
                row = it.nextRow();
                assertEquals("3", row.getValue("id").getString());
            }
            assertFalse(it.hasNext());
        }
    }
   
    @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();
        ValueFactory vf = session.getValueFactory();
        QueryManager qm = session.getWorkspace().getQueryManager();
        Query q = qm.createQuery("select id from [nt:base] where data >= $data order by id", Query.JCR_SQL2);
        q.bindValue("data", vf.createValue("x"));
        for (int limit = 0; limit < 5; limit++) {
            q.setLimit(limit);
            for (int offset = 0; offset < 3; offset++) {
                q.setOffset(offset);
                QueryResult r = q.execute();
                RowIterator it = r.getRows();
                int l = Math.min(Math.max(0, 3 - offset), limit);
                assertEquals(l, r.getRows().getSize());
                assertEquals(l, r.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());
            }
        }
    }

    @SuppressWarnings("deprecation")
    @Test
    public void nodeTypeConstraint() throws Exception {
        Session session = getAdminSession();
        Node root = session.getRootNode();
        Node folder1 = root.addNode("folder1", "nt:folder");
        Node folder2 = root.addNode("folder2", "nt:folder");
        JcrUtils.putFile(folder1, "file", "text/plain",
                new ByteArrayInputStream("foo bar".getBytes("UTF-8")));
        folder2.addNode("folder3", "nt:folder");
        session.save();

        QueryManager qm = session.getWorkspace().getQueryManager();
        Query q = qm.createQuery("//element(*, nt:folder)", Query.XPATH);
        Set<String> paths = new HashSet<String>();
        for (RowIterator it = q.execute().getRows(); it.hasNext();) {
            paths.add(it.nextRow().getPath());
        }
        assertEquals(new HashSet<String>(Arrays.asList("/folder1", "/folder2", "/folder2/folder3")),
                paths);
    }
   
    @Test
    public void noLiterals() throws RepositoryException {
        Session session = getAdminSession();
        ValueFactory vf = session.getValueFactory();
        QueryManager qm = session.getWorkspace().getQueryManager();
       
        // insecure
        try {
            Query q = qm.createQuery(
                    "select text from [nt:base] where password = 'x'",
                    Query.JCR_SQL2 + "-noLiterals");
            q.execute();
            fail();
        } catch (InvalidQueryException e) {
            assertTrue(e.toString(), e.toString().indexOf(
                    "literals of this type not allowed") > 0);
        }

        // secure
        Query q = qm.createQuery(
                "select text from [nt:base] where password = $p",
                Query.JCR_SQL2 + "-noLiterals");
        q.bindValue("p", vf.createValue("x"));
        q.execute();
    }

    @SuppressWarnings("deprecation")
    @Test
    public void fnNameEncoding() throws Exception {
        Session session = getAdminSession();
        session.getRootNode().addNode("123456_test_name");
        session.save();

        QueryManager qm = session.getWorkspace().getQueryManager();
        Query q;

        q = qm.createQuery("//*[jcr:like(fn:name(), '%123456%')]", Query.XPATH);
        assertEquals("/123456_test_name", getPaths(q));

        q = qm.createQuery("//*[fn:name() = '123456_test_name']", Query.XPATH);
        assertEquals("", getPaths(q));
    }

    /**
     * OAK-1093
     */
    @Test
    public void getValuesOnMvp() throws RepositoryException {
        Session session = getAdminSession();
        Node hello = session.getRootNode().addNode("hello");
        hello.setProperty("id", "1");
        hello.setProperty("properties", new String[] { "p1", "p2" });
        session.save();

        QueryManager qm = session.getWorkspace().getQueryManager();
        Query q = qm.createQuery("select properties from [nt:base] where id = 1",
                Query.JCR_SQL2);

        QueryResult r = q.execute();
        RowIterator it = r.getRows();
        assertTrue(it.hasNext());
        Row row = it.nextRow();
        assertEquals("p1 p2", row.getValues()[0].getString());
    }

    @SuppressWarnings("deprecation")
    @Test
    public void xpathEscapeTest() throws RepositoryException {
        Session writer = createAdminSession();
        Session reader = createAdminSession();
        try {
            Node rootNode = writer.getRootNode();
            Node node = rootNode.addNode("test", "nt:unstructured");
            node.addNode(".tokens");
            writer.save();

            QueryManager qm = reader.getWorkspace().getQueryManager();
            Query q = qm.createQuery("/jcr:root//*[_x002e_tokens/@jcr:primaryType]", Query.XPATH);
            NodeIterator res = q.execute().getNodes();
            assertEquals(1, res.getSize());
        } finally {
            if (reader != null) {
                reader.logout();
            }
            if (writer != null) {
                writer.logout();
            }
        }
    }

    @Test
    public void testOak1096() throws RepositoryException {
        Session writer = createAdminSession();
        Session reader = createAdminSession();
        try {
            Node rootNode = writer.getRootNode();
            Node node = rootNode.addNode("test", "nt:unstructured");
            node.setProperty("text", "find me");
            writer.save();

            QueryManager qm = reader.getWorkspace().getQueryManager();
            Query q = qm.createQuery("select * from 'nt:base' where contains(*, 'find me')", Query.JCR_SQL2);
            NodeIterator res = q.execute().getNodes();
            assertEquals("False amount of hits", 1, res.getSize());
        } finally {
            if (reader != null) {
                reader.logout();
            }
            if (writer != null) {
                writer.logout();
            }
        }
    }
   
    @Test
    public void testOak1128() throws RepositoryException {
        Session session = createAdminSession();
        Node p = session.getRootNode().addNode("etc");
        p.addNode("p1");
        Node r = p.addNode("p2").addNode("r", "nt:unstructured");
        r.setProperty("nt:resourceType", "test");
        session.save();
        Query q = session.getWorkspace().getQueryManager().createQuery(
                "/jcr:root/etc//*["+
                        "(@jcr:primaryType = 'a'  or @jcr:primaryType = 'b') "+
                        "or @nt:resourceType = 'test']", "xpath");
        QueryResult qr = q.execute();
        NodeIterator ni = qr.getNodes();
        Node n = ni.nextNode();
        assertEquals("/etc/p2/r", n.getPath());
    }

    @Test
    public void testOak1171() throws RepositoryException {
        Session session = createAdminSession();
        Node p = session.getRootNode().addNode("etc");
        p.addNode("p1").setProperty("title", "test");
        p.addNode("p2").setProperty("title", 1);
        session.save();

        Query q = session.getWorkspace().getQueryManager()
                .createQuery("//*[@title = 'test']", "xpath");
        QueryResult qr = q.execute();

        NodeIterator ni = qr.getNodes();
        assertTrue(ni.hasNext());
        Node n = ni.nextNode();
        assertEquals("/etc/p1", n.getPath());
        assertFalse(ni.hasNext());
    }

}
TOP

Related Classes of org.apache.jackrabbit.oak.jcr.query.QueryTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.