You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cayenne.apache.org by nt...@apache.org on 2017/01/26 12:02:53 UTC

cayenne git commit: CAY-2194 Function expressions support in Ordering

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 <st...@gmail.com>
Authored: Thu Jan 26 15:02:44 2017 +0300
Committer: Nikita Timofeev <st...@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;