cayenne-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Andrus Adamchik <and...@objectstyle.org>
Subject Re: No willPerform(Generic)Query support for prefetching queries in 3.1?
Date Tue, 24 Sep 2013 16:07:56 GMT
>> I still need a way to filter all query
>> types for specific entities to filter out certain entities (appending
>> "where INVALIDATED = 'N'"). 

Is this a global rule, or does it depend on some context (like user role)? If it's the former,
you can add a qualifier to affected entities in the Modeler. 

Andrus

On Sep 24, 2013, at 7:00 PM, Mike Kienenberger <mkienenb@gmail.com> wrote:

> 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