cayenne-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ntimof...@apache.org
Subject [cayenne] branch master updated: CAY-2518 Add method to append having qualifier expression to ObjectSelect
Date Thu, 07 Feb 2019 09:13:16 GMT
This is an automated email from the ASF dual-hosted git repository.

ntimofeev pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cayenne.git


The following commit(s) were added to refs/heads/master by this push:
     new 46ed9d1  CAY-2518 Add method to append having qualifier expression to ObjectSelect
     new eba14f0  Merge PR #364
46ed9d1 is described below

commit 46ed9d1b7b4da328f97090ef206954c732c71173
Author: Arseni Bulatski <ancarseni@gmail.com>
AuthorDate: Wed Feb 6 16:28:44 2019 +0300

    CAY-2518 Add method to append having qualifier expression to ObjectSelect
---
 RELEASE-NOTES.txt                                  |  1 +
 .../translator/select/ObjectSelectWrapper.java     |  2 +-
 .../org/apache/cayenne/query/ColumnSelect.java     | 28 +---------
 .../org/apache/cayenne/query/FluentSelect.java     | 28 ++++++++++
 .../org/apache/cayenne/query/ObjectSelect.java     | 59 +++++++++++++++-------
 .../apache/cayenne/query/ObjectSelect_RunIT.java   | 19 +++++++
 6 files changed, 92 insertions(+), 45 deletions(-)

diff --git a/RELEASE-NOTES.txt b/RELEASE-NOTES.txt
index fc6fbe7..36274dd 100644
--- a/RELEASE-NOTES.txt
+++ b/RELEASE-NOTES.txt
@@ -19,6 +19,7 @@ CAY-2508 Create api to add aliases in expressions
 CAY-2510 Create builder to load custom modules into plugins and modeler
 CAY-2511 Contribute custom properties for attributes
 CAY-2517 EventManager: optimization of adding listeners
+CAY-2518 Add method to append having qualifier expression to ObjectSelect
 CAY-2520 Split ObjectId into several specialized variants
 
 Bug Fixes:
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/ObjectSelectWrapper.java
b/cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/ObjectSelectWrapper.java
index 272bf83..684245e 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/ObjectSelectWrapper.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/ObjectSelectWrapper.java
@@ -74,7 +74,7 @@ public class ObjectSelectWrapper implements TranslatableQueryWrapper {
 
     @Override
     public Expression getHavingQualifier() {
-        return null;
+        return selectQuery.getHaving();
     }
 
     @Override
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/query/ColumnSelect.java b/cayenne-server/src/main/java/org/apache/cayenne/query/ColumnSelect.java
index fafd258..b96b6bf 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/query/ColumnSelect.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/query/ColumnSelect.java
@@ -67,10 +67,8 @@ import org.apache.cayenne.map.ObjEntity;
 public class ColumnSelect<T> extends FluentSelect<T> {
 
     private Collection<BaseProperty<?>> columns;
-    private boolean havingExpressionIsActive = false;
     // package private for tests
     boolean singleColumn = true;
-    private Expression having;
     boolean distinct;
     boolean suppressDistinct;
 
@@ -88,6 +86,7 @@ public class ColumnSelect<T> extends FluentSelect<T> {
         this.entityName = select.entityName;
         this.dbEntityName = select.dbEntityName;
         this.where = select.where;
+        this.having = select.having;
         this.orderings = select.orderings;
         this.prefetches = select.prefetches;
         this.limit = select.limit;
@@ -102,7 +101,6 @@ public class ColumnSelect<T> extends FluentSelect<T> {
     protected Query createReplacementQuery(EntityResolver resolver) {
         SelectQuery<?> replacement = (SelectQuery)super.createReplacementQuery(resolver);
         replacement.setColumns(columns);
-        replacement.setHavingQualifier(having);
         replacement.setCanReturnScalarValue(singleColumn);
         replacement.setDistinct(distinct);
         replacement.setSuppressDistinct(suppressDistinct);
@@ -658,35 +656,11 @@ public class ColumnSelect<T> extends FluentSelect<T> {
         return this;
     }
 
-    private void setActiveExpression(Expression exp) {
-        if(havingExpressionIsActive) {
-            having = exp;
-        } else {
-            where = exp;
-        }
-        replacementQuery = null;
-    }
-
-    private Expression getActiveExpression() {
-        if(havingExpressionIsActive) {
-            return having;
-        } else {
-            return where;
-        }
-    }
-
     public Collection<BaseProperty<?>> getColumns() {
         return columns;
     }
 
     /**
-     * Returns a HAVING clause Expression of this query.
-     */
-    public Expression getHaving() {
-        return having;
-    }
-
-    /**
      * @since 4.2
      */
     public boolean isDistinct() {
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/query/FluentSelect.java b/cayenne-server/src/main/java/org/apache/cayenne/query/FluentSelect.java
index c5286cb..2d9d1a3 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/query/FluentSelect.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/query/FluentSelect.java
@@ -43,6 +43,7 @@ public abstract class FluentSelect<T> extends IndirectQuery implements
Select<T>
     protected String entityName;
     protected String dbEntityName;
     protected Expression where;
+    protected Expression having;
     protected Collection<Ordering> orderings;
     protected PrefetchTreeNode prefetches;
     protected int limit;
@@ -52,6 +53,8 @@ public abstract class FluentSelect<T> extends IndirectQuery implements
Select<T>
     protected QueryCacheStrategy cacheStrategy;
     protected String cacheGroup;
 
+    boolean havingExpressionIsActive = false;
+
     protected FluentSelect() {
     }
 
@@ -88,6 +91,7 @@ public abstract class FluentSelect<T> extends IndirectQuery implements
Select<T>
         }
 
         replacement.setQualifier(where);
+        replacement.setHavingQualifier(having);
         replacement.addOrderings(orderings);
         replacement.setPrefetchTree(prefetches);
         replacement.setCacheStrategy(cacheStrategy);
@@ -143,6 +147,13 @@ public abstract class FluentSelect<T> extends IndirectQuery implements
Select<T>
         return where;
     }
 
+    /**
+     * Returns a HAVING clause Expression of this query.
+     */
+    public Expression getHaving() {
+        return having;
+    }
+
     public Collection<Ordering> getOrderings() {
         return orderings;
     }
@@ -151,6 +162,23 @@ public abstract class FluentSelect<T> extends IndirectQuery implements
Select<T>
         return prefetches;
     }
 
+    void setActiveExpression(Expression exp) {
+        if(havingExpressionIsActive) {
+            having = exp;
+        } else {
+            where = exp;
+        }
+        replacementQuery = null;
+    }
+
+    Expression getActiveExpression() {
+        if(havingExpressionIsActive) {
+            return having;
+        } else {
+            return where;
+        }
+    }
+
     @Override
     public List<T> select(ObjectContext context) {
         return context.select(this);
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/query/ObjectSelect.java b/cayenne-server/src/main/java/org/apache/cayenne/query/ObjectSelect.java
index e1e6942..f633372 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/query/ObjectSelect.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/query/ObjectSelect.java
@@ -18,26 +18,26 @@
  ****************************************************************/
 package org.apache.cayenne.query;
 
+import java.sql.Statement;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
 import org.apache.cayenne.DataRow;
 import org.apache.cayenne.ObjectContext;
-import org.apache.cayenne.exp.property.BaseProperty;
 import org.apache.cayenne.exp.Expression;
 import org.apache.cayenne.exp.ExpressionFactory;
+import org.apache.cayenne.exp.Property;
+import org.apache.cayenne.exp.property.BaseProperty;
 import org.apache.cayenne.exp.property.ComparableProperty;
 import org.apache.cayenne.exp.property.NumericProperty;
-import org.apache.cayenne.exp.Property;
 import org.apache.cayenne.exp.property.PropertyFactory;
 import org.apache.cayenne.map.DbEntity;
 import org.apache.cayenne.map.EntityResolver;
 import org.apache.cayenne.map.ObjEntity;
 
-import java.sql.Statement;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
-
 /**
  * A selecting query providing chainable API. This is an alternative to
  * {@link SelectQuery} when you want to use a fluent API. For example, the following
@@ -225,6 +225,31 @@ public class ObjectSelect<T> extends FluentSelect<T> {
     }
 
     /**
+     * Appends a having qualifier expression of this query. An equivalent to
+     * {@link #and(Expression...)} that can be used a syntactic sugar.
+     *
+     * @return this object
+     * @since 4.2
+     */
+    public ObjectSelect<T> having(Expression expression) {
+        havingExpressionIsActive = true;
+        return and(expression);
+    }
+
+    /**
+     * Appends a having qualifier expression of this query, using provided expression
+     * String and an array of position parameters. This is an equivalent to
+     * calling "and".
+     *
+     * @return this object
+     * @since 4.2
+     */
+    public ObjectSelect<T> having(String expressionString, Object... parameters) {
+        havingExpressionIsActive = true;
+        return and(ExpressionFactory.exp(expressionString, parameters));
+    }
+
+    /**
      * AND's provided expressions to the existing WHERE clause expression.
      *
      * @return this object
@@ -249,17 +274,17 @@ public class ObjectSelect<T> extends FluentSelect<T> {
         }
 
         Collection<Expression> all;
+        Expression activeExpression = getActiveExpression();
 
-        if (where != null) {
+        if(activeExpression != null) {
             all = new ArrayList<>(expressions.size() + 1);
-            all.add(where);
+            all.add(activeExpression);
             all.addAll(expressions);
         } else {
             all = expressions;
         }
 
-        where = ExpressionFactory.and(all);
-        replacementQuery = null;
+        setActiveExpression(ExpressionFactory.and(all));
         return this;
     }
 
@@ -287,17 +312,17 @@ public class ObjectSelect<T> extends FluentSelect<T> {
         }
 
         Collection<Expression> all;
+        Expression activeExpression = getActiveExpression();
 
-        if (where != null) {
+        if(activeExpression != null) {
             all = new ArrayList<>(expressions.size() + 1);
-            all.add(where);
+            all.add(activeExpression);
             all.addAll(expressions);
         } else {
             all = expressions;
         }
 
-        where = ExpressionFactory.or(all);
-        replacementQuery = null;
+        setActiveExpression(ExpressionFactory.or(all));
         return this;
     }
 
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/query/ObjectSelect_RunIT.java
b/cayenne-server/src/test/java/org/apache/cayenne/query/ObjectSelect_RunIT.java
index c8028b2..242cbd3 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/query/ObjectSelect_RunIT.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/query/ObjectSelect_RunIT.java
@@ -204,4 +204,23 @@ public class ObjectSelect_RunIT extends ServerCase {
 		assertNotNull(a);
 		assertEquals("artist1", a.getArtistName());
 	}
+
+	@Test
+	public void test_Select_Having() {
+		List<Artist> artists = ObjectSelect.query(Artist.class)
+				.having(Artist.PAINTING_ARRAY.count().gt(3L))
+				.select(context);
+
+		assertEquals(5, artists.size());
+	}
+
+	@Test
+	public void test_Select_Where_Having() {
+		List<Artist> artists = ObjectSelect.query(Artist.class)
+				.where(Artist.ARTIST_NAME.eq("artist1"))
+				.having(Artist.PAINTING_ARRAY.count().gt(3L))
+				.select(context);
+
+		assertEquals(1, artists.size());
+	}
 }


Mime
View raw message