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 2020/05/20 15:11:24 UTC

[cayenne] branch master updated: CAY-2657 SelectQueryDescriptor should use ObjectSelect

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 fd8eaa2  CAY-2657 SelectQueryDescriptor should use ObjectSelect
fd8eaa2 is described below

commit fd8eaa2a823a72d957cd111d54c64c492c59baf0
Author: Nikita Timofeev <st...@gmail.com>
AuthorDate: Wed May 20 18:11:03 2020 +0300

    CAY-2657 SelectQueryDescriptor should use ObjectSelect
---
 .../apache/cayenne/map/SelectQueryDescriptor.java  | 48 +++++++++++++---------
 .../org/apache/cayenne/query/FluentSelect.java     |  8 ++++
 .../org/apache/cayenne/query/MappedSelect.java     | 10 ++---
 .../org/apache/cayenne/query/ObjectSelect.java     | 20 ++++++++-
 .../access/DataContextPerformQueryAPIIT.java       | 18 +++-----
 .../cayenne/map/SelectQueryDescriptorTest.java     | 26 ++++++------
 .../cayenne/modeler/editor/SelectQueryMainTab.java |  5 +--
 7 files changed, 80 insertions(+), 55 deletions(-)

diff --git a/cayenne-server/src/main/java/org/apache/cayenne/map/SelectQueryDescriptor.java b/cayenne-server/src/main/java/org/apache/cayenne/map/SelectQueryDescriptor.java
index f7b5a88..5ca45ef 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/map/SelectQueryDescriptor.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/map/SelectQueryDescriptor.java
@@ -23,22 +23,24 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
+import org.apache.cayenne.CayenneRuntimeException;
 import org.apache.cayenne.configuration.ConfigurationNodeVisitor;
 import org.apache.cayenne.exp.Expression;
+import org.apache.cayenne.query.ObjectSelect;
 import org.apache.cayenne.query.Ordering;
 import org.apache.cayenne.query.PrefetchTreeNode;
-import org.apache.cayenne.query.SelectQuery;
 import org.apache.cayenne.util.XMLEncoder;
 
 /**
  * @since 4.0
- * @deprecated since 4.2
  */
-@Deprecated
 public class SelectQueryDescriptor extends QueryDescriptor {
 
 	private static final long serialVersionUID = -8798258795351950215L;
 
+    public static final String DISTINCT_PROPERTY = "cayenne.SelectQuery.distinct";
+    public static final boolean DISTINCT_DEFAULT = false;
+
 	protected Expression qualifier;
 
     protected List<Ordering> orderings = new ArrayList<>();
@@ -49,13 +51,12 @@ public class SelectQueryDescriptor extends QueryDescriptor {
     }
 
     public void setDistinct(boolean value) {
-        setProperty(SelectQuery.DISTINCT_PROPERTY, String.valueOf(value));
+        setProperty(DISTINCT_PROPERTY, String.valueOf(value));
     }
 
     public boolean isDistinct() {
-        String distinct = getProperty(SelectQuery.DISTINCT_PROPERTY);
-
-        return distinct != null ? Boolean.valueOf(distinct) : false;
+        String distinct = getProperty(DISTINCT_PROPERTY);
+        return distinct != null ? Boolean.parseBoolean(distinct) : DISTINCT_DEFAULT;
     }
 
     /**
@@ -167,27 +168,34 @@ public class SelectQueryDescriptor extends QueryDescriptor {
     }
 
     @Override
-    public SelectQuery<?> buildQuery() {
-        SelectQuery<Object> selectQuery = new SelectQuery<>();
-        selectQuery.setRoot(this.getRoot());
-        selectQuery.setQualifier(this.getQualifier());
+    public ObjectSelect<?> buildQuery() {
+        // resolve root
+        Object root = getRoot();
+        String rootEntityName;
+        if(root instanceof ObjEntity) {
+            rootEntityName = ((ObjEntity) root).getName();
+        } else if(root instanceof String) {
+            rootEntityName = (String)root;
+        } else {
+            throw new CayenneRuntimeException("Unexpected root for the SelectQueryDescriptor '%s'.", root);
+        }
 
-        List<Ordering> orderings = this.getOrderings();
+        ObjectSelect<?> query = ObjectSelect.query(Object.class, getQualifier());
+        query.entityName(rootEntityName);
+        query.setRoot(root);
 
+        List<Ordering> orderings = this.getOrderings();
         if (orderings != null && !orderings.isEmpty()) {
-            selectQuery.addOrderings(orderings);
+            query.orderBy(orderings);
         }
 
         if (prefetchesMap != null) {
-            for (Map.Entry<String, Integer> entry : prefetchesMap.entrySet()) {
-                selectQuery.addPrefetch(PrefetchTreeNode.withPath(entry.getKey(), entry.getValue()));
-            }
+            prefetchesMap.forEach(query::prefetch);
         }
 
-        // init properties
-        selectQuery.initWithProperties(this.getProperties());
-
-        return selectQuery;
+        // TODO: apply DISTINCT property
+        query.initWithProperties(this.getProperties());
+        return query;
     }
 
     @Override
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 d11c491..f886732 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
@@ -21,6 +21,7 @@ package org.apache.cayenne.query;
 
 import java.util.Collection;
 import java.util.List;
+import java.util.Map;
 
 import org.apache.cayenne.CayenneRuntimeException;
 import org.apache.cayenne.ObjectContext;
@@ -214,4 +215,11 @@ public abstract class FluentSelect<T> extends AbstractQuery implements Select<T>
     public boolean isDistinct() {
         return false;
     }
+
+    /**
+     * @since 4.2
+     */
+    public void initWithProperties(Map<String, String> properties) {
+        getBaseMetaData().initWithProperties(properties);
+    }
 }
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/query/MappedSelect.java b/cayenne-server/src/main/java/org/apache/cayenne/query/MappedSelect.java
index be7a378..18e5f66 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/query/MappedSelect.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/query/MappedSelect.java
@@ -199,18 +199,18 @@ public class MappedSelect<T> extends AbstractMappedQuery implements Select<T> {
 
         switch (descriptor.getType()) {
             case QueryDescriptor.SELECT_QUERY:
-                SelectQuery selectQuery = (SelectQuery) query;
+                ObjectSelect<?> selectQuery = (ObjectSelect<?>) query;
                 if (fetchLimit != null) {
-                    selectQuery.setFetchLimit(fetchLimit);
+                    selectQuery.limit(fetchLimit);
                 }
                 if (fetchOffset != null) {
-                    selectQuery.setFetchOffset(fetchOffset);
+                    selectQuery.offset(fetchOffset);
                 }
                 if (statementFetchSize != null) {
-                    selectQuery.setStatementFetchSize(statementFetchSize);
+                    selectQuery.statementFetchSize(statementFetchSize);
                 }
                 if (pageSize != null) {
-                    selectQuery.setPageSize(pageSize);
+                    selectQuery.pageSize(pageSize);
                 }
                 if (cacheStrategyOverride != null) {
                     selectQuery.setCacheStrategy(cacheStrategyOverride);
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 d20b5d8..6c728a1 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
@@ -24,6 +24,7 @@ import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
+import java.util.Map;
 
 import org.apache.cayenne.DataRow;
 import org.apache.cayenne.ObjectContext;
@@ -53,7 +54,7 @@ import org.apache.cayenne.map.ObjEntity;
  *
  * @since 4.0
  */
-public class ObjectSelect<T> extends FluentSelect<T> {
+public class ObjectSelect<T> extends FluentSelect<T> implements ParameterizedQuery {
 
     private static final long serialVersionUID = -156124021150949227L;
 
@@ -692,4 +693,21 @@ public class ObjectSelect<T> extends FluentSelect<T> {
     protected BaseQueryMetadata getBaseMetaData() {
         return metaData;
     }
+
+    /**
+     * This method is intended for internal use in a {@link MappedSelect}.
+     *
+     * @param parameters to apply
+     * @return this query with parameters applied to the <b>where</b> qualifier
+     *
+     * @since 4.2
+     */
+    @Override
+    public Query createQuery(Map<String, ?> parameters) {
+        if(where == null) {
+            return this;
+        }
+        where = where.params(parameters, true);
+        return this;
+    }
 }
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/access/DataContextPerformQueryAPIIT.java b/cayenne-server/src/test/java/org/apache/cayenne/access/DataContextPerformQueryAPIIT.java
index 6df993f..b95e229 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/access/DataContextPerformQueryAPIIT.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/access/DataContextPerformQueryAPIIT.java
@@ -207,12 +207,9 @@ public class DataContextPerformQueryAPIIT extends ServerCase {
         List<?> artists = context.performQuery("QueryWithLocalCache", true);
         assertEquals(2, artists.size());
 
-        queryInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
-
-            public void execute() {
-                List<?> artists1 = context.performQuery("QueryWithLocalCache", false);
-                assertEquals(2, artists1.size());
-            }
+        queryInterceptor.runWithQueriesBlocked(() -> {
+            List<?> artists1 = context.performQuery("QueryWithLocalCache", false);
+            assertEquals(2, artists1.size());
         });
     }
 
@@ -223,12 +220,9 @@ public class DataContextPerformQueryAPIIT extends ServerCase {
         List<?> artists = context.performQuery("QueryWithSharedCache", true);
         assertEquals(2, artists.size());
 
-        queryInterceptor.runWithQueriesBlocked(new UnitTestClosure() {
-
-            public void execute() {
-                List<?> artists1 = context2.performQuery("QueryWithSharedCache", false);
-                assertEquals(2, artists1.size());
-            }
+        queryInterceptor.runWithQueriesBlocked(() -> {
+            List<?> artists1 = context2.performQuery("QueryWithSharedCache", false);
+            assertEquals(2, artists1.size());
         });
     }
 }
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/map/SelectQueryDescriptorTest.java b/cayenne-server/src/test/java/org/apache/cayenne/map/SelectQueryDescriptorTest.java
index a5f1944..29c37bf 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/map/SelectQueryDescriptorTest.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/map/SelectQueryDescriptorTest.java
@@ -20,27 +20,25 @@
 package org.apache.cayenne.map;
 
 import org.apache.cayenne.exp.ExpressionFactory;
-import org.apache.cayenne.query.Query;
+import org.apache.cayenne.query.ObjectSelect;
 import org.apache.cayenne.query.QueryMetadata;
-import org.apache.cayenne.query.SelectQuery;
 import org.junit.Test;
 
 import static org.junit.Assert.*;
 
 /**
  */
-@Deprecated
 public class SelectQueryDescriptorTest {
 
     @Test
-    public void testGetQueryType() throws Exception {
+    public void testGetQueryType() {
         SelectQueryDescriptor builder = QueryDescriptor.selectQueryDescriptor();
         builder.setRoot("FakeRoot");
-        assertTrue(builder.buildQuery() instanceof SelectQuery);
+        assertTrue(builder.buildQuery() instanceof ObjectSelect);
     }
 
     @Test
-    public void testGetQueryRoot() throws Exception {
+    public void testGetQueryRoot() {
         DataMap map = new DataMap();
         ObjEntity entity = new ObjEntity("A");
         map.addObjEntity(entity);
@@ -48,31 +46,31 @@ public class SelectQueryDescriptorTest {
         SelectQueryDescriptor builder = QueryDescriptor.selectQueryDescriptor();
         builder.setRoot(entity);
 
-        assertTrue(builder.buildQuery() instanceof SelectQuery);
+        assertTrue(builder.buildQuery() instanceof ObjectSelect);
         assertSame(entity, builder.buildQuery().getRoot());
     }
 
     @Test
-    public void testGetQueryQualifier() throws Exception {
+    public void testGetQueryQualifier() {
         SelectQueryDescriptor builder = QueryDescriptor.selectQueryDescriptor();
         builder.setRoot("FakeRoot");
         builder.setQualifier(ExpressionFactory.exp("abc = 5"));
 
-        SelectQuery query = builder.buildQuery();
+        ObjectSelect<?> query = builder.buildQuery();
 
-        assertEquals(ExpressionFactory.exp("abc = 5"), query.getQualifier());
+        assertEquals(ExpressionFactory.exp("abc = 5"), query.getWhere());
     }
 
     @Test
-    public void testGetQueryProperties() throws Exception {
+    public void testGetQueryProperties() {
         SelectQueryDescriptor builder = QueryDescriptor.selectQueryDescriptor();
         builder.setRoot("FakeRoot");
         builder.setProperty(QueryMetadata.FETCH_LIMIT_PROPERTY, "5");
         builder.setProperty(QueryMetadata.STATEMENT_FETCH_SIZE_PROPERTY, "6");
 
-        SelectQuery<?> query = builder.buildQuery();
-        assertTrue(query instanceof SelectQuery);
-        assertEquals(5, query.getFetchLimit());
+        ObjectSelect<?> query = builder.buildQuery();
+        assertTrue(query instanceof ObjectSelect);
+        assertEquals(5, query.getLimit());
         assertEquals(6, query.getStatementFetchSize());
 
         // TODO: test other properties...
diff --git a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/SelectQueryMainTab.java b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/SelectQueryMainTab.java
index 4049bc8..e63b40b 100644
--- a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/SelectQueryMainTab.java
+++ b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/SelectQueryMainTab.java
@@ -36,7 +36,6 @@ import org.apache.cayenne.map.Entity;
 import org.apache.cayenne.map.ObjEntity;
 import org.apache.cayenne.map.QueryDescriptor;
 import org.apache.cayenne.map.SelectQueryDescriptor;
-import org.apache.cayenne.query.SelectQuery;
 import org.apache.cayenne.swing.components.JCayenneCheckBox;
 import org.apache.cayenne.modeler.ProjectController;
 import org.apache.cayenne.modeler.util.Comparators;
@@ -134,7 +133,7 @@ public class SelectQueryMainTab extends BaseQueryMainTab {
         distinct.addItemListener(e -> {
             QueryDescriptor query = getQuery();
             if (query != null) {
-                query.setProperty(SelectQuery.DISTINCT_PROPERTY, Boolean.toString(distinct.isSelected()));
+                query.setProperty(SelectQueryDescriptor.DISTINCT_PROPERTY, Boolean.toString(distinct.isSelected()));
                 mediator.fireQueryEvent(new QueryEvent(this, query));
             }
         });
@@ -155,7 +154,7 @@ public class SelectQueryMainTab extends BaseQueryMainTab {
         SelectQueryDescriptor query = (SelectQueryDescriptor) descriptor;
 
         name.setText(query.getName());
-        distinct.setSelected(Boolean.valueOf(query.getProperties().get(SelectQuery.DISTINCT_PROPERTY)));
+        distinct.setSelected(Boolean.parseBoolean(query.getProperties().get(SelectQueryDescriptor.DISTINCT_PROPERTY)));
         qualifier.setText(query.getQualifier() != null ? query
                 .getQualifier()
                 .toString() : null);