/* * Copyright 2014 - 2017 Blazebit. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.blazebit.persistence.testsuite; import static com.googlecode.catchexception.CatchException.verifyException; import static org.junit.Assert.assertEquals; import com.blazebit.persistence.testsuite.base.category.NoDatanucleus; import com.googlecode.catchexception.CatchException; import org.junit.Assert; import org.junit.Test; import com.blazebit.persistence.Criteria; import com.blazebit.persistence.CriteriaBuilder; import com.blazebit.persistence.PaginatedCriteriaBuilder; import com.blazebit.persistence.impl.ConfigurationProperties; import com.blazebit.persistence.impl.expression.SyntaxErrorException; import com.blazebit.persistence.spi.CriteriaBuilderConfiguration; import com.blazebit.persistence.testsuite.entity.Document; import org.junit.experimental.categories.Category; /** * * @author Christian Beikov * @author Moritz Becker * @since 1.0 */ public class OrderByTest extends AbstractCoreTest { @Test public void testOrderByAscNullsFirst() { CriteriaBuilder<Document> criteria = cbf.create(em, Document.class, "d"); criteria.orderBy("d.age", true, true); assertEquals("SELECT d FROM Document d ORDER BY " + renderNullPrecedence("d.age", "ASC", "FIRST"), criteria.getQueryString()); criteria.getResultList(); } @Test public void testOrderByAscNullsLast() { CriteriaBuilder<Document> criteria = cbf.create(em, Document.class, "d"); criteria.orderBy("d.age", true, false); assertEquals("SELECT d FROM Document d ORDER BY " + renderNullPrecedence("d.age", "ASC", "LAST"), criteria.getQueryString()); criteria.getResultList(); } @Test public void testOrderByDescNullsFirst() { CriteriaBuilder<Document> criteria = cbf.create(em, Document.class, "d"); criteria.orderBy("d.age", false, true); assertEquals("SELECT d FROM Document d ORDER BY " + renderNullPrecedence("d.age", "DESC", "FIRST"), criteria.getQueryString()); criteria.getResultList(); } @Test public void testOrderByDescNullsLast() { CriteriaBuilder<Document> criteria = cbf.create(em, Document.class, "d"); criteria.orderBy("d.age", false, false); assertEquals("SELECT d FROM Document d ORDER BY " + renderNullPrecedence("d.age", "DESC", "LAST"), criteria.getQueryString()); criteria.getResultList(); } @Test public void testOrderByNested() { CriteriaBuilder<Document> criteria = cbf.create(em, Document.class, "d"); criteria.orderBy("d.versions.document.age", false, false); assertEquals( "SELECT d FROM Document d LEFT JOIN d.versions versions_1 LEFT JOIN versions_1.document document_1 ORDER BY " + renderNullPrecedence("document_1.age", "DESC", "LAST"), criteria.getQueryString()); criteria.getResultList(); } @Test public void testOrderByMultiple() { CriteriaBuilder<Document> criteria = cbf.create(em, Document.class, "d"); criteria.orderBy("d.partners.ownedDocuments.age", false, false).orderBy("d.partners.partnerDocument.age", true, true); assertEquals( "SELECT d FROM Document d LEFT JOIN d.partners partners_1 LEFT JOIN partners_1.ownedDocuments ownedDocuments_1 LEFT JOIN partners_1.partnerDocument partnerDocument_1 ORDER BY " + renderNullPrecedence("ownedDocuments_1.age", "DESC", "LAST") + ", " + renderNullPrecedence("partnerDocument_1.age", "ASC", "FIRST"), criteria.getQueryString()); criteria.getResultList(); } @Test public void testOrderByNullAlias() { CriteriaBuilder<Document> criteria = cbf.create(em, Document.class, "d"); try { criteria.orderBy(null, false, false); Assert.fail("Expected NullPointerException"); } catch (NullPointerException e) { } } @Test public void testOrderByEmptyAlias() { CriteriaBuilder<Document> criteria = cbf.create(em, Document.class, "d"); try { criteria.orderBy("", false, false); Assert.fail("Expected IllegalArgumentException"); } catch (IllegalArgumentException e) { } } @Test public void testOrderByFunctionCompatibleMode(){ CriteriaBuilderConfiguration config = Criteria.getDefault(); config = configure(config); config.setProperty(ConfigurationProperties.COMPATIBLE_MODE, "true"); cbf = config.createCriteriaBuilderFactory(em.getEntityManagerFactory()); CriteriaBuilder<Document> criteria = cbf.create(em, Document.class, "d"); verifyException(criteria, SyntaxErrorException.class).orderByAsc("SIZE(d.partners)"); } @Test public void testOrderByFunctionExpression(){ PaginatedCriteriaBuilder<String> criteria = cbf.create(em, String.class) .from(Document.class, "d") .select("COALESCE(d.owner.name, 'a')", "asd") .orderByAsc("asd") .orderByAsc("id") .page(0, 1); String expectedQuery = "SELECT d.id, COALESCE(owner_1.name,'a') AS asd FROM Document d " + "JOIN d.owner owner_1 " + "GROUP BY " + groupBy("d.id", renderNullPrecedenceGroupBy(groupByPathExpressions("COALESCE(owner_1.name,'a')", "owner_1.name")), renderNullPrecedenceGroupBy("d.id")) + " ORDER BY " + renderNullPrecedence("asd", "COALESCE(owner_1.name,'a')", "ASC", "LAST") + ", " + renderNullPrecedence("d.id", "ASC", "LAST"); assertEquals(expectedQuery, criteria.getPageIdQueryString()); } @Test // TODO: Report datanucleus issue @Category({ NoDatanucleus.class }) public void testOrderByAliasedCaseWhen() { CriteriaBuilder<Document> criteria = cbf.create(em, Document.class, "d"); criteria.select("CASE WHEN (nameObject.primaryName IS NULL OR LENGTH(TRIM(nameObject.primaryName)) = 0) THEN name ELSE nameObject.primaryName END", "abc"); criteria.orderByAsc("abc"); String caseWhen = "CASE WHEN d.nameObject.primaryName IS NULL OR LENGTH(TRIM(BOTH FROM d.nameObject.primaryName)) = 0 THEN d.name ELSE d.nameObject.primaryName END"; String expected = "SELECT " + caseWhen + " AS abc " + "FROM Document d " + "ORDER BY " + renderNullPrecedence("abc", caseWhen, "ASC", "LAST"); assertEquals(expected, criteria.getQueryString()); criteria.getResultList(); } @Test public void testOrderByConcatParameter(){ CriteriaBuilder<Document> criteria = cbf.create(em, Document.class, "d"); criteria.orderByAsc("CONCAT(:prefix, name)"); assertEquals("SELECT d FROM Document d ORDER BY " + renderNullPrecedence("CONCAT(:prefix,d.name)", "ASC", "LAST"), criteria.getQueryString()); criteria.setParameter("prefix", "test").getResultList(); } @Test public void testOrderByFunctionExperimental(){ CriteriaBuilder<Document> criteria = cbf.create(em, Document.class, "d"); criteria.orderByDesc("FUNCTION('zero',FUNCTION('zero',d.id,FUNCTION('zero',FUNCTION('zero',:colors))),1)"); assertEquals("SELECT d FROM Document d ORDER BY " + renderNullPrecedence(function("zero", function("zero", "d.id", function("zero", function("zero", ":colors"))), "1"), "DESC", "LAST"), criteria.getQueryString()); } @Test public void testOrderBySize(){ CriteriaBuilder<Document> criteria = cbf.create(em, Document.class, "d"); criteria.select("d.id").orderByAsc("SIZE(d.partners)"); final String expected = "SELECT d.id FROM Document d LEFT JOIN d.partners partners_1 GROUP BY d.id ORDER BY " + renderNullPrecedence(function("COUNT_TUPLE", "partners_1.id"), "ASC", "LAST"); assertEquals(expected, criteria.getQueryString()); criteria.getResultList(); } @Test public void testOrderBySizeMultiple(){ CriteriaBuilder<Document> criteria = cbf.create(em, Document.class, "d"); criteria.select("d.id").orderByAsc("SIZE(d.partners)").orderByDesc("SIZE(d.versions)"); final String expected = "SELECT d.id FROM Document d LEFT JOIN d.partners partners_1 LEFT JOIN d.versions versions_1 GROUP BY d.id ORDER BY " + renderNullPrecedence(function("COUNT_TUPLE", "'DISTINCT'", "partners_1.id"), "ASC", "LAST") + ", " + renderNullPrecedence(function("COUNT_TUPLE", "'DISTINCT'", "versions_1.id"), "DESC", "LAST"); assertEquals(expected, criteria.getQueryString()); criteria.getResultList(); } }