cayenne-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Mike Kienenberger <mkien...@gmail.com>
Subject Re: No willPerform(Generic)Query support for prefetching queries in 3.1?
Date Tue, 24 Sep 2013 16:00:05 GMT
Here's one possible way to add support for intercepting prefetch
queries.   I'm not entirely certain it's the best way, but I didn't
see another obvious point.

What I did was to call
QueryRouter.willPerformQuery(PrefetchSelectQuery query) before routing
the newly-created prefetch select query.

For DataDomainQueryAction, this will call context.willPerformQuery()
if there's a non-null context.
For anything else (DataDomainLegacyQueryAction, MockQueryRouter), it's a noop.

If the returned query is null, then we skip routing the query and
return either true or false.   I picked true since it might be useful
to process children of the prefetch even if the prefetch is not
skipped.   My own use case is never going to return null, so I'm fine
with false.

There's also no reason why I picked
QueryRouter.willPerformQuery(PrefetchSelectQuery query) instead of
QueryRouter.willPerformQuery(Query query) other than it made it more
obvious that this method was only being used for
PrefetchSelectQueries.   But there may be other kinds of queries which
should also be going through this method.   The more I think about
this, the more reasonable it seems have it be Query since developers
might be writing their own Query types, and any Queries being created
internally should be exposed through
DataContextDelegate.willPerformQuery, and the QueryRouter is the most
likely place to be able to forward such new queries.

This has solved my issues with prefetching under 3.1.   I'm still open
to suggestions for solving my specific problem another way in the
application code (adding database table views isn't an option), but I
think exposing prefetch queries (as well as others) is something we
should be supporting in Cayenne.


Index: framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DataDomainLegacyQueryAction.java
===================================================================
--- framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DataDomainLegacyQueryAction.java
   (revision 1524993)
+++ framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DataDomainLegacyQueryAction.java
   (working copy)
@@ -27,6 +27,7 @@

 import org.apache.cayenne.CayenneRuntimeException;
 import org.apache.cayenne.map.DataMap;
+import org.apache.cayenne.query.PrefetchSelectQuery;
 import org.apache.cayenne.query.Query;
 import org.apache.cayenne.query.QueryMetadata;
 import org.apache.cayenne.query.QueryRouter;
@@ -163,4 +164,8 @@

         return q != null ? q : executedQuery;
     }
+
+    public Query willPerformQuery(PrefetchSelectQuery prefetchQuery) {
+        return prefetchQuery;
+    }
 }
Index: framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DataDomainQueryAction.java
===================================================================
--- framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DataDomainQueryAction.java
   (revision 1524993)
+++ framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/access/DataDomainQueryAction.java
   (working copy)
@@ -772,4 +772,14 @@
             }
         }
     }
+
+    public Query willPerformQuery(PrefetchSelectQuery prefetchQuery) {
+        // Notify DataContextDelegate that we have created a new
PrefetchSelectQuery
+        if (null != context) {
+            Query transformedQuery =
context.nonNullDelegate().willPerformQuery(context, prefetchQuery);
+            return transformedQuery;
+        } else {
+            return prefetchQuery;
+        }
+    }
 }
Index: framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/query/QueryRouter.java
===================================================================
--- framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/query/QueryRouter.java
   (revision 1524993)
+++ framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/query/QueryRouter.java
   (working copy)
@@ -49,4 +49,6 @@
      * @throws NullPointerException if a map parameter is null.
      */
     QueryEngine engineForDataMap(DataMap map);
+
+    Query willPerformQuery(PrefetchSelectQuery prefetchQuery);
 }
Index: framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/query/SelectQueryPrefetchRouterAction.java
===================================================================
--- framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/query/SelectQueryPrefetchRouterAction.java
   (revision 1524993)
+++ framework/cayenne-jdk1.5-unpublished/src/main/java/org/apache/cayenne/query/SelectQueryPrefetchRouterAction.java
   (working copy)
@@ -114,9 +114,15 @@

         // pass prefetch subtree to enable joint prefetches...
         prefetchQuery.setPrefetchTree(node);
-
+
+        Query transformedQuery = router.willPerformQuery(prefetchQuery);
+        if (null == transformedQuery) {
+            // Not sure if we want to return false instead.
Returning true seems safer.
+            return true;
+        }
+
         // route...
-        prefetchQuery.route(router, resolver, null);
+        transformedQuery.route(router, resolver, null);
         return true;
     }

Index: framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/query/MockQueryRouter.java
===================================================================
--- framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/query/MockQueryRouter.java
   (revision 1524993)
+++ framework/cayenne-jdk1.5-unpublished/src/test/java/org/apache/cayenne/query/MockQueryRouter.java
   (working copy)
@@ -50,4 +50,8 @@
     public QueryEngine engineForDataMap(DataMap map) {
         return new MockQueryEngine();
     }
+
+    public Query willPerformQuery(PrefetchSelectQuery prefetchQuery) {
+        return prefetchQuery;
+    }
 }



On Mon, Sep 23, 2013 at 7:04 PM, Mike Kienenberger <mkienenb@gmail.com> wrote:
> All of my tests pass now, but I'm still hitting a few issues for 3.1
> that the tests didn't reveal.
>
> In previous versions (not sure when it changed), there existed the
> ability to intercept prefetch queries using
> DataContextDelegate.willPerformQuery() or willPerformGenericQuery().
>  Those queries are no longer available -- only the original query with
> the prefetchTree goes through those methods.
>
> It's the end of the day here, so I haven't traced through the code yet
> to see what's going on, but I still need a way to filter all query
> types for specific entities to filter out certain entities (appending
> "where INVALIDATED = 'N'").   I've got this working for select
> queries, relationship queries, objectIdQueries, but not prefetch
> queries.
>
> And I'm still wondering what the difference between
> willPerformGenericQuery and willPerformQuery might be.   So far, I
> just forward willPerformGenericQuery requests through my
> willPerformQuery code.

Mime
View raw message