Repository: cayenne
Updated Branches:
  refs/heads/master 44bad6412 -> c21831862


CAY-2194 Function expressions support in Ordering


Project: http://git-wip-us.apache.org/repos/asf/cayenne/repo
Commit: http://git-wip-us.apache.org/repos/asf/cayenne/commit/c2183186
Tree: http://git-wip-us.apache.org/repos/asf/cayenne/tree/c2183186
Diff: http://git-wip-us.apache.org/repos/asf/cayenne/diff/c2183186

Branch: refs/heads/master
Commit: c21831862a47ea3e064e91e02184604db68b1df3
Parents: 44bad64
Author: Nikita Timofeev <stari...@gmail.com>
Authored: Thu Jan 26 15:02:44 2017 +0300
Committer: Nikita Timofeev <stari...@gmail.com>
Committed: Thu Jan 26 15:02:44 2017 +0300

----------------------------------------------------------------------
 .../translator/select/OrderingTranslator.java   |  9 +++
 .../java/org/apache/cayenne/query/Ordering.java |  9 +++
 .../cayenne/access/DataContextOrderingIT.java   |  5 +-
 .../translator/select/OrderingTranslatorIT.java | 25 +++++++
 .../query/ObjectSelect_PrimitiveColumnsIT.java  | 31 +++++---
 .../org/apache/cayenne/query/OrderingTest.java  | 76 ++++++++++++++++++++
 6 files changed, 142 insertions(+), 13 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cayenne/blob/c2183186/cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/OrderingTranslator.java
----------------------------------------------------------------------
diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/OrderingTranslator.java
 
b/cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/OrderingTranslator.java
index 7a7ba4f..4079b0a 100644
--- 
a/cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/OrderingTranslator.java
+++ 
b/cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/OrderingTranslator.java
@@ -80,6 +80,8 @@ public class OrderingTranslator extends QueryAssemblerHelper {
                                        appendObjPath(exp);
                                } else if (exp.getType() == Expression.DB_PATH) 
{
                                        appendDbPath(exp);
+                               } else if (exp.getType() == 
Expression.FUNCTION_CALL) {
+                                       appendFunction(exp);
                                } else {
                                        throw new 
CayenneRuntimeException("Unsupported ordering expression: " + exp);
                                }
@@ -107,6 +109,13 @@ public class OrderingTranslator extends 
QueryAssemblerHelper {
                }
        }
 
+       protected void appendFunction(Expression exp) {
+               QualifierTranslator qualifierTranslator = 
queryAssembler.getAdapter().getQualifierTranslator(queryAssembler);
+               qualifierTranslator.setQualifier(exp);
+               StringBuilder builder = qualifierTranslator.appendPart(new 
StringBuilder());
+               out.append(builder.toString());
+       }
+
        /**
         * Returns the column expressions (not Expressions) used in the order by
         * clause. E.g., in the case of an case-insensitive order by, an 
element of

http://git-wip-us.apache.org/repos/asf/cayenne/blob/c2183186/cayenne-server/src/main/java/org/apache/cayenne/query/Ordering.java
----------------------------------------------------------------------
diff --git 
a/cayenne-server/src/main/java/org/apache/cayenne/query/Ordering.java 
b/cayenne-server/src/main/java/org/apache/cayenne/query/Ordering.java
index 9e26991..cb82a2a 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/query/Ordering.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/query/Ordering.java
@@ -147,6 +147,15 @@ public class Ordering implements Comparator<Object>, 
Serializable, XMLSerializab
                return true;
        }
 
+       @Override
+       public int hashCode() {
+               int result = sortSpecString != null ? sortSpecString.hashCode() 
: 0;
+               result = 31 * result + (sortOrder != null ? 
sortOrder.hashCode() : 0);
+               result = 31 * result + (pathExceptionSuppressed ? 1 : 0);
+               result = 31 * result + (nullSortedFirst ? 1 : 0);
+               return result;
+       }
+
        /**
         * Sets sortSpec to be an expression represented by string argument.
         * 

http://git-wip-us.apache.org/repos/asf/cayenne/blob/c2183186/cayenne-server/src/test/java/org/apache/cayenne/access/DataContextOrderingIT.java
----------------------------------------------------------------------
diff --git 
a/cayenne-server/src/test/java/org/apache/cayenne/access/DataContextOrderingIT.java
 
b/cayenne-server/src/test/java/org/apache/cayenne/access/DataContextOrderingIT.java
index a9f2039..68506d2 100644
--- 
a/cayenne-server/src/test/java/org/apache/cayenne/access/DataContextOrderingIT.java
+++ 
b/cayenne-server/src/test/java/org/apache/cayenne/access/DataContextOrderingIT.java
@@ -118,10 +118,7 @@ public class DataContextOrderingIT extends ServerCase {
         assertEquals(2, list1.size());
     }
 
-    /**
-     * For now Ordering doesn't support custom expression
-     */
-    @Test(expected = CayenneRuntimeException.class)
+    @Test
     public void testCustomPropertySort() throws Exception {
         Calendar c = Calendar.getInstance();
 

http://git-wip-us.apache.org/repos/asf/cayenne/blob/c2183186/cayenne-server/src/test/java/org/apache/cayenne/access/translator/select/OrderingTranslatorIT.java
----------------------------------------------------------------------
diff --git 
a/cayenne-server/src/test/java/org/apache/cayenne/access/translator/select/OrderingTranslatorIT.java
 
b/cayenne-server/src/test/java/org/apache/cayenne/access/translator/select/OrderingTranslatorIT.java
index ba21af7..cca9c9b 100644
--- 
a/cayenne-server/src/test/java/org/apache/cayenne/access/translator/select/OrderingTranslatorIT.java
+++ 
b/cayenne-server/src/test/java/org/apache/cayenne/access/translator/select/OrderingTranslatorIT.java
@@ -23,8 +23,11 @@ import static org.junit.Assert.assertEquals;
 
 import java.util.Arrays;
 
+import org.apache.cayenne.CayenneRuntimeException;
 import org.apache.cayenne.access.DataNode;
 import org.apache.cayenne.di.Inject;
+import org.apache.cayenne.exp.ExpressionFactory;
+import org.apache.cayenne.exp.FunctionExpressionFactory;
 import org.apache.cayenne.query.Ordering;
 import org.apache.cayenne.query.SelectQuery;
 import org.apache.cayenne.query.SortOrder;
@@ -97,6 +100,28 @@ public class OrderingTranslatorIT extends ServerCase {
                doTestAppendPart("UPPER(ta.ARTIST_NAME), 
UPPER(ta.ESTIMATED_PRICE)", o1, o2);
        }
 
+       @Test
+       public void testAppendFunctionExpression1() throws Exception {
+               Ordering o1 = new 
Ordering(FunctionExpressionFactory.absExp("paintingArray.estimatedPrice"));
+
+               doTestAppendPart("ABS(ta.ESTIMATED_PRICE)", o1);
+       }
+
+       @Test
+       public void testAppendFunctionExpression2() throws Exception {
+               Ordering o1 = new 
Ordering(FunctionExpressionFactory.countExp(ExpressionFactory.pathExp("dateOfBirth")),
 SortOrder.ASCENDING_INSENSITIVE);
+               Ordering o2 = new 
Ordering(FunctionExpressionFactory.modExp("paintingArray.estimatedPrice", 3), 
SortOrder.DESCENDING);
+
+               doTestAppendPart("UPPER(COUNT(ta.DATE_OF_BIRTH)), 
MOD(ta.ESTIMATED_PRICE, ?) DESC", o1, o2);
+       }
+
+       @Test(expected = CayenneRuntimeException.class)
+       public void testAppendIllegalExpression() throws Exception {
+               Ordering o1 = new 
Ordering(ExpressionFactory.and(ExpressionFactory.expTrue(), 
ExpressionFactory.expFalse()));
+               // should throw exception
+               doTestAppendPart("TRUE AND FALSE", o1);
+       }
+
        private void doTestAppendPart(String expectedSQL, Ordering... 
orderings) {
 
                SelectQuery<Artist> q = SelectQuery.query(Artist.class);

http://git-wip-us.apache.org/repos/asf/cayenne/blob/c2183186/cayenne-server/src/test/java/org/apache/cayenne/query/ObjectSelect_PrimitiveColumnsIT.java
----------------------------------------------------------------------
diff --git 
a/cayenne-server/src/test/java/org/apache/cayenne/query/ObjectSelect_PrimitiveColumnsIT.java
 
b/cayenne-server/src/test/java/org/apache/cayenne/query/ObjectSelect_PrimitiveColumnsIT.java
index 14f0d71..15326e6 100644
--- 
a/cayenne-server/src/test/java/org/apache/cayenne/query/ObjectSelect_PrimitiveColumnsIT.java
+++ 
b/cayenne-server/src/test/java/org/apache/cayenne/query/ObjectSelect_PrimitiveColumnsIT.java
@@ -54,9 +54,11 @@ public class ObjectSelect_PrimitiveColumnsIT extends 
ServerCase {
     @Inject
     private UnitDbAdapter unitDbAdapter;
 
+    private TableHelper tPrimitives;
+
     @Before
     public void createTestRecords() throws Exception {
-        TableHelper tPrimitives = new TableHelper(dbHelper, "PRIMITIVES_TEST");
+        tPrimitives = new TableHelper(dbHelper, "PRIMITIVES_TEST");
         tPrimitives.setColumns("ID", "BOOLEAN_COLUMN", "INT_COLUMN");
         for (int i = 1; i <= 20; i++) {
             tPrimitives.insert(i, (i % 2 == 0), i * 10);
@@ -165,23 +167,34 @@ public class ObjectSelect_PrimitiveColumnsIT extends 
ServerCase {
 
     @Test
     public void testSum() throws Exception {
-        Property<Long> sumProp = 
Property.create(sumExp(PrimitivesTestEntity.INT_COLUMN.path()), Long.class);
-
-        long sum = ObjectSelect.query(PrimitivesTestEntity.class)
-                .column(sumProp)
+        int sum = ObjectSelect.query(PrimitivesTestEntity.class)
+                .sum(PrimitivesTestEntity.INT_COLUMN)
                 .selectOne(context);
         assertEquals(2100, sum);
     }
 
     @Test
     public void testAvg() throws Exception {
-        Property<Double> avgProp = 
Property.create(avgExp(PrimitivesTestEntity.INT_COLUMN.path()), Double.class);
-
-        double avg = ObjectSelect.query(PrimitivesTestEntity.class)
-                .column(avgProp)
+        int avg = ObjectSelect.query(PrimitivesTestEntity.class)
+                .avg(PrimitivesTestEntity.INT_COLUMN)
                 .selectOne(context);
         assertEquals(105.0, avg, 0.00001);
     }
 
+    @Test
+    public void testOrderByCount() throws Exception {
+        tPrimitives.insert(21, true, 210);
+
+        List<Object[]> res = ObjectSelect
+                .columnQuery(PrimitivesTestEntity.class, 
PrimitivesTestEntity.BOOLEAN_COLUMN, PrimitivesTestEntity.INT_COLUMN.count())
+                .orderBy(PrimitivesTestEntity.INT_COLUMN.count().asc())
+                .select(context);
+        assertEquals(2, res.size());
+
+        assertEquals(false, res.get(0)[0]);
+        assertEquals(true, res.get(1)[0]);
 
+        assertEquals(10L, res.get(0)[1]);
+        assertEquals(11L, res.get(1)[1]);
+    }
 }

http://git-wip-us.apache.org/repos/asf/cayenne/blob/c2183186/cayenne-server/src/test/java/org/apache/cayenne/query/OrderingTest.java
----------------------------------------------------------------------
diff --git 
a/cayenne-server/src/test/java/org/apache/cayenne/query/OrderingTest.java 
b/cayenne-server/src/test/java/org/apache/cayenne/query/OrderingTest.java
index c6c7d55..66cb4a1 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/query/OrderingTest.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/query/OrderingTest.java
@@ -19,6 +19,8 @@
 
 package org.apache.cayenne.query;
 
+import org.apache.cayenne.exp.Expression;
+import org.apache.cayenne.exp.FunctionExpressionFactory;
 import org.apache.cayenne.testdo.testmap.Painting;
 import org.apache.cayenne.unit.util.TstBean;
 import org.junit.Test;
@@ -124,6 +126,19 @@ public class OrderingTest {
     }
 
     @Test
+    public void testOrderingWithExpression() {
+        Expression exp = FunctionExpressionFactory.absExp("x");
+        Ordering ord = new Ordering();
+        ord.setSortSpec(exp);
+        ord.setSortOrder(SortOrder.ASCENDING);
+
+        Ordering ord2 = new Ordering(exp);
+        assertEquals(ord, ord2);
+        assertEquals(exp, ord2.getSortSpec());
+        assertEquals(SortOrder.ASCENDING, ord2.getSortOrder());
+    }
+
+    @Test
     public void testCompare3() {
         Painting p1 = new Painting();
         p1.setEstimatedPrice(new BigDecimal(1000.00));
@@ -268,6 +283,67 @@ public class OrderingTest {
         assertEquals(shouldBe5, orderedList.get(5));
     }
 
+    @Test
+    public void testOrderListWithFunction() {
+        Collection<TstBean> set = new HashSet<>(6);
+
+        TstBean shouldBe0 = new TstBean("", 0);
+        TstBean shouldBe1 = new TstBean("", -1);
+        TstBean shouldBe2 = new TstBean("", -2);
+        TstBean shouldBe3 = new TstBean("", 5);
+        TstBean shouldBe4 = new TstBean("", -6);
+        TstBean shouldBe5 = new TstBean("", -30);
+
+        set.add(shouldBe4);
+        set.add(shouldBe2);
+        set.add(shouldBe1);
+        set.add(shouldBe5);
+        set.add(shouldBe0);
+        set.add(shouldBe3);
+
+        List<TstBean> orderedList = new 
Ordering(FunctionExpressionFactory.absExp("integer"), 
SortOrder.ASCENDING).orderedList(set);
+
+        assertEquals(shouldBe0, orderedList.get(0));
+        assertEquals(shouldBe1, orderedList.get(1));
+        assertEquals(shouldBe2, orderedList.get(2));
+        assertEquals(shouldBe3, orderedList.get(3));
+        assertEquals(shouldBe4, orderedList.get(4));
+        assertEquals(shouldBe5, orderedList.get(5));
+    }
+
+    @Test
+    public void testOrderListWithFunction_Static() {
+        Collection<TstBean> set = new HashSet<>(6);
+
+        TstBean shouldBe0 = new TstBean("cx", -2);
+        TstBean shouldBe1 = new TstBean("cf", -1);
+        TstBean shouldBe2 = new TstBean("basa", 2);
+        TstBean shouldBe3 = new TstBean("abcd", -1);
+        TstBean shouldBe4 = new TstBean("bdsasd", -2);
+        TstBean shouldBe5 = new TstBean("bdsadf", 1);
+
+        set.add(shouldBe4);
+        set.add(shouldBe2);
+        set.add(shouldBe1);
+        set.add(shouldBe5);
+        set.add(shouldBe0);
+        set.add(shouldBe3);
+
+        List<Ordering> orderings = asList(
+                new Ordering(FunctionExpressionFactory.lengthExp("string"), 
SortOrder.ASCENDING),
+                new Ordering(FunctionExpressionFactory.absExp("integer"), 
SortOrder.DESCENDING)
+        );
+
+        List<TstBean> orderedList = Ordering.orderedList(set, orderings);
+
+        assertEquals(shouldBe0, orderedList.get(0));
+        assertEquals(shouldBe1, orderedList.get(1));
+        assertEquals(shouldBe2, orderedList.get(2));
+        assertEquals(shouldBe3, orderedList.get(3));
+        assertEquals(shouldBe4, orderedList.get(4));
+        assertEquals(shouldBe5, orderedList.get(5));
+    }
+
     public static class B1 {
 
         private B2 b2;

Reply via email to