/*
* See the NOTICE file distributed with this work for additional
* information regarding copyright ownership.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.xwiki.query.xwql.internal;
import org.apache.commons.lang3.StringUtils;
import org.jmock.Expectations;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.xwiki.bridge.DocumentAccessBridge;
import org.xwiki.query.xwql.internal.hql.XWQLtoHQLTranslator;
import org.xwiki.test.jmock.JMockRule;
import static org.junit.Assert.fail;
public class XWQLtoHQLTranslatorTest
{
@Rule
public final JMockRule mockery = new JMockRule();
private DocumentAccessBridge dab = this.mockery.mock(DocumentAccessBridge.class);
private XWQLtoHQLTranslator translator = new XWQLtoHQLTranslator()
{
@Override
public DocumentAccessBridge getDocumentAccessBridge()
{
return dab;
}
};
@Before
public void setUp() throws Exception
{
this.mockery.checking(new Expectations()
{{
allowing(dab).getPropertyType(with(any(String.class)), with(equal("number")));
will(returnValue(null));
allowing(dab).getPropertyType(with(any(String.class)), with(equal("category")));
will(returnValue("DBStringListProperty"));
allowing(dab).getPropertyType(with(any(String.class)), with(equal("stringlist")));
will(returnValue("StringListProperty"));
allowing(dab).getPropertyType(with(any(String.class)), with(any(String.class)));
will(returnValue("StringProperty"));
allowing(dab).isPropertyCustomMapped("Custom.Mapping", "cmprop");
will(returnValue(true));
allowing(dab).isPropertyCustomMapped(with(any(String.class)), with(any(String.class)));
will(returnValue(false));
}});
}
void assertTranslate(String input, String expectedOutput) throws Exception
{
String output = translator.translate(input);
String exp[] = StringUtils.split(expectedOutput, " ");
String actual[] = StringUtils.split(output, " ");
for (int i = 0; i < Math.max(exp.length, actual.length); i++) {
String e = i < exp.length ? exp[i] : null;
String a = i < actual.length ? actual[i] : null;
if (!StringUtils.equalsIgnoreCase(e, a)) {
fail(String.format(
"translate assertion. input = [%s]\n expected output = [%s]\n actual output = [%s]\n first mismatch: [%s]!=[%s]",
input, expectedOutput, output, e, a));
}
}
}
@Test
public void testDocument() throws Exception
{
assertTranslate("select doc from Document as doc", "select doc from XWikiDocument as doc");
assertTranslate("select doc from Document as doc where doc.title like '%test'",
"select doc from XWikiDocument as doc where doc.title like '%test'");
}
@Test
public void testObject() throws Exception
{
assertTranslate("select doc from Document as doc, doc.object('XWiki.XWikiUs\u00E9rs') as user",
"select doc from XWikiDocument as doc , BaseObject as user " +
"where 1=1 and doc.fullName=user.name and user.className='XWiki.XWikiUs\u00E9rs'");
}
@Test
public void testProperty() throws Exception
{
assertTranslate(
"select doc from Document as doc, doc.object(XWiki.XWikiUsers) as user where user.email = 'some'",
"select doc from XWikiDocument as doc , BaseObject as user , StringProperty as user_email1 " +
"where ( user_email1.value = 'some' ) and doc.fullName=user.name and user.className='XWiki.XWikiUsers' and user_email1.id.id=user.id and user_email1.id.name='email'");
}
@Test
public void testShort() throws Exception
{
assertTranslate("", "select doc.fullName from XWikiDocument as doc");
assertTranslate("where doc.title like '%test'",
"select doc.fullName from XWikiDocument as doc where doc.title like '%test'");
assertTranslate("from doc.object(XWiki.XWikiUsers) as user",
"select doc.fullName from XWikiDocument as doc , BaseObject as user " +
"where 1=1 and doc.fullName=user.name and user.className='XWiki.XWikiUsers'");
assertTranslate("from doc.object('XWiki.XWikiUs\u00E9rs') as user where user.email = 'some'",
"select doc.fullName from XWikiDocument as doc , BaseObject as user , StringProperty as user_email1 " +
"where ( user_email1.value = 'some' ) and doc.fullName=user.name and user.className='XWiki.XWikiUs\u00E9rs' and user_email1.id.id=user.id and user_email1.id.name='email'");
}
@Test
public void testObjDeclInWhere() throws Exception
{
assertTranslate("where doc.object('XWiki.XWikiUs\u00E9rs').email = 'some'",
"select doc.fullName from XWikiDocument as doc , BaseObject as _o1, StringProperty as _o1_email2 " +
"where ( _o1_email2.value = 'some' ) and doc.fullName=_o1.name and _o1.className='XWiki.XWikiUs\u00E9rs' and _o1_email2.id.id=_o1.id and _o1_email2.id.name='email'");
}
@Test
public void testObjDeclInWhereWithTwoInstances() throws Exception
{
assertTranslate(
"where doc.object(XWiki.XWikiUsers).email = 'some' and doc.object(XWiki.XWikiUsers).first_name = 'Name'",
"select doc.fullName from XWikiDocument as doc , BaseObject as _o1, " +
"StringProperty as _o1_email2, StringProperty as _o1_first_name3 " +
"where ( _o1_email2.value = 'some' and _o1_first_name3.value = 'Name' ) " +
"and doc.fullName=_o1.name and _o1.className='XWiki.XWikiUsers' " +
"and _o1_email2.id.id=_o1.id and _o1_email2.id.name='email' " +
"and _o1_first_name3.id.id=_o1.id and _o1_first_name3.id.name='first_name'");
}
@Test
public void testOrderBy() throws Exception
{
assertTranslate("order by doc.fullName",
"select doc.fullName from XWikiDocument as doc order by doc.fullName");
assertTranslate("from doc.object(XWiki.XWikiUsers) as user order by user.firstname",
"select doc.fullName from XWikiDocument as doc , BaseObject as user , StringProperty as user_firstname1 " +
"where 1=1 and doc.fullName=user.name and user.className='XWiki.XWikiUsers' and user_firstname1.id.id=user.id and user_firstname1.id.name='firstname' order by user_firstname1.value");
assertTranslate("order by lower(doc.fullName)",
"select doc.fullName from XWikiDocument as doc order by lower ( doc.fullName )");
assertTranslate("order by upper(doc.fullName)",
"select doc.fullName from XWikiDocument as doc order by upper ( doc.fullName )");
assertTranslate("order by trim(doc.fullName)",
"select doc.fullName from XWikiDocument as doc order by trim ( doc.fullName )");
assertTranslate("order by abs(doc.elements)",
"select doc.fullName from XWikiDocument as doc order by abs ( doc.elements )");
}
@Test
public void testGroupBy() throws Exception
{
assertTranslate("where 1=1 group by doc.space",
"select doc.fullName from XWikiDocument as doc where 1 = 1 group by doc.space");
assertTranslate("where 1=1 group by upper(doc.space)",
"select doc.fullName from XWikiDocument as doc where 1 = 1 group by upper ( doc.space )");
assertTranslate("where 1=1 group by lower(doc.space)",
"select doc.fullName from XWikiDocument as doc where 1 = 1 group by lower ( doc.space )");
assertTranslate("where 1=1 group by trim(doc.space)",
"select doc.fullName from XWikiDocument as doc where 1 = 1 group by trim ( doc.space )");
assertTranslate("where 1=1 group by abs(doc.elements)",
"select doc.fullName from XWikiDocument as doc where 1 = 1 group by abs ( doc.elements )");
}
@Test
public void testGroupByAndOrderBy() throws Exception
{
assertTranslate("select obj.property1, count(obj.property2) from Document doc, "
+ "doc.object(Some.Class) as obj group by obj.property1 order by count(obj.property2)",
" select obj_property11.value , count ( obj_property22.value ) "
+ "from XWikiDocument as doc , BaseObject as obj , StringProperty as obj_property11, StringProperty as obj_property22 "
+ "WHERE 1=1 and doc.fullName=obj.name and obj.className='Some.Class' "
+ "and obj_property11.id.id=obj.id and obj_property11.id.name='property1' "
+ "and obj_property22.id.id=obj.id and obj_property22.id.name='property2' "
+ "group by obj_property11.value "
+ "order by count ( obj_property22.value )");
assertTranslate("select obj.property1, sum(obj.property2) from Document doc, "
+ "doc.object(Some.Class) as obj group by obj.property1 order by sum(obj.property2)",
" select obj_property11.value , sum ( obj_property22.value ) "
+ "from XWikiDocument as doc , BaseObject as obj , StringProperty as obj_property11, StringProperty as obj_property22 "
+ "WHERE 1=1 and doc.fullName=obj.name and obj.className='Some.Class' "
+ "and obj_property11.id.id=obj.id and obj_property11.id.name='property1' "
+ "and obj_property22.id.id=obj.id and obj_property22.id.name='property2' "
+ "group by obj_property11.value "
+ "order by sum ( obj_property22.value )");
assertTranslate("select obj.property1, avg(obj.property2) from Document doc, "
+ "doc.object(Some.Class) as obj group by obj.property1 order by avg(obj.property2)",
" select obj_property11.value , avg ( obj_property22.value ) "
+ "from XWikiDocument as doc , BaseObject as obj , StringProperty as obj_property11, StringProperty as obj_property22 "
+ "WHERE 1=1 and doc.fullName=obj.name and obj.className='Some.Class' "
+ "and obj_property11.id.id=obj.id and obj_property11.id.name='property1' "
+ "and obj_property22.id.id=obj.id and obj_property22.id.name='property2' "
+ "group by obj_property11.value "
+ "order by avg ( obj_property22.value )");
assertTranslate("select obj.property1, max(obj.property2) from Document doc, "
+ "doc.object(Some.Class) as obj group by obj.property1 order by max(obj.property2)",
" select obj_property11.value , max ( obj_property22.value ) "
+ "from XWikiDocument as doc , BaseObject as obj , StringProperty as obj_property11, StringProperty as obj_property22 "
+ "WHERE 1=1 and doc.fullName=obj.name and obj.className='Some.Class' "
+ "and obj_property11.id.id=obj.id and obj_property11.id.name='property1' "
+ "and obj_property22.id.id=obj.id and obj_property22.id.name='property2' "
+ "group by obj_property11.value "
+ "order by max ( obj_property22.value )");
assertTranslate("select obj.property1, min(obj.property2) from Document doc, "
+ "doc.object(Some.Class) as obj group by obj.property1 order by min(obj.property2)",
" select obj_property11.value , min ( obj_property22.value ) "
+ "from XWikiDocument as doc , BaseObject as obj , StringProperty as obj_property11, StringProperty as obj_property22 "
+ "WHERE 1=1 and doc.fullName=obj.name and obj.className='Some.Class' "
+ "and obj_property11.id.id=obj.id and obj_property11.id.name='property1' "
+ "and obj_property22.id.id=obj.id and obj_property22.id.name='property2' "
+ "group by obj_property11.value "
+ "order by min ( obj_property22.value )");
}
@Test
public void testInternalProperty() throws Exception
{
assertTranslate("select doc from Document as doc, doc.object('Blog.Categories') as c order by c.number",
"select doc from XWikiDocument as doc , BaseObject as c " +
"where 1=1 and doc.fullName=c.name and c.className='Blog.Categories' order by c.number");
}
@Test
public void testLists() throws Exception
{
// DBStringListProperty
assertTranslate("from doc.object('XWiki.ArticleClass') as a where :cat member of a.category",
"select doc.fullName from XWikiDocument as doc , BaseObject as a , DBStringListProperty as a_category1" +
" where ( :cat in elements( a_category1.list ) ) and doc.fullName=a.name and a.className='XWiki.ArticleClass' and a_category1.id.id=a.id and a_category1.id.name='category'");
// StringListProperty
assertTranslate("from doc.object('XWiki.Class') as c where c.stringlist like '%some%'",
"select doc.fullName from XWikiDocument as doc , BaseObject as c , StringListProperty as c_stringlist1" +
" where ( c_stringlist1.textValue like '%some%' ) and doc.fullName=c.name and c.className='XWiki.Class' and c_stringlist1.id.id=c.id and c_stringlist1.id.name='stringlist'");
// return DBStringListProperty
assertTranslate("select distinct a.category from Document as doc, doc.object('XWiki.ArticleClass') as a",
"select distinct elements(a_category1.list) from XWikiDocument as doc , BaseObject as a , DBStringListProperty as a_category1" +
" where 1=1 and doc.fullName=a.name and a.className='XWiki.ArticleClass' and a_category1.id.id=a.id and a_category1.id.name='category'");
}
@Test
public void testCustomMapping() throws Exception
{
// one CM prop
assertTranslate("select doc from Document as doc, doc.object('Custom.Mapping') as c where c.cmprop='some'",
"select doc from XWikiDocument as doc , BaseObject as c , Custom.Mapping as cCM1 " +
"where ( cCM1.cmprop = 'some' ) and doc.fullName=c.name and c.id=cCM1.id");
// CM and standard props
assertTranslate(
"select doc from Document as doc, doc.object('Custom.Mapping') as c where c.cmprop='some' and c.prop=1",
"select doc from XWikiDocument as doc , BaseObject as c , Custom.Mapping as cCM1, StringProperty as c_prop2 " +
"where ( cCM1.cmprop = 'some' and c_prop2.value = 1 ) and doc.fullName=c.name and c.id=cCM1.id and c_prop2.id.id=c.id and c_prop2.id.name='prop'");
}
}