Intercepting BatchQueries after sql is generated

From: Mike Kienenberger (mkienen..mail.com)
Date: Sat Aug 26 2006 - 15:58:14 EDT

  • Next message: Jonathan Bélisle: "DataContext synchronization bug ?"

    > On Dec 30, 2005, at 11:27 PM, Mike Kienenberger wrote:
    > > I don't quite understand what you're proposing. How would one get
    > > the needed information out of a batch query?

    Now that I've looked at the BatchQuery object, this was a naive question :-)
    The BatchQuery contains EXACTLY the information I need. Thanks for
    being patient :-)

    Furthermore, I don't think I need to set relationships if I'm using
    the direct values. The only question will be how I can get the
    foreign keys injected into my Log object relationships without
    breaking them. Probably not insurmountable.

    It looks like the best place to intercept the queries is in
    DataDomainFlushAction.flush(), right between runQueries() and
    postprocess(context). Since we have access to the DataContext, this
    seems like it'd be a reasonable place to call a
    DataContextDelegate.queriesDidRun(List queries) method.

    So I need to set a user-managed transaction, create a
    DataContextDelegate that reparses all of the queries, turning them
    into Log objects (or into datarows), let the first commit finish, then
    recommit again with the new Log objects and close out the user
    transaction.

    On 12/31/05, Andrus Adamchik <andru..bjectstyle.org> wrote:
    >
    >
    > BatchQuery contain a matrix of values keyed by DbAttribute - this is
    > what you need for audit, right? Still need to think how to handle
    > deferred generated keys, but if we intercept the query at the right
    > moment, they can be already there, solving your other problem as well.
    >
    > BatchQuery q;
    > List dbAttributes = q.getDbAttributes();
    > while(q.next()) {
    > for(int i = 0; i < q.size(); i++) {
    > DbAttribute a = (DbAttribute) dbAttributes.get(i);
    > Object value = q.getValue(i);
    >
    > // append this data to the audit log
    > // ...
    >
    > // note that in UPDATE batches attribute can be either
    > // from 'UpdatedAttributes' or 'QualifierAttributes'
    > }
    > }
    >
    > // reset the batch so that Cayenne could process it again later
    > q.reset();
    >
    >
    > > And then add new objects to the commit? The process of adding
    > > more inserts is
    > > probably the two-stage commit that you're talking about.
    >
    > Yes. If possible you can simply append the audit log to your own
    > InsertBatchQuery (maybe attaching it to the DataContext via
    > "setUserProperty"). If not, you can create unregistered DataObjects
    > (you won't have any relationships in them, right?), register them in
    > DataContext after the first commit stage is done, and then commit again.
    >
    >
    > > Sounds interesting, but I need something that works in the present,
    > > and it
    > > sounds like this might require a lot of work before it's ready for
    > > use.
    >
    > This may not be as bad, but it will certainly require some attention.
    > I'll log a Jira improvement task.
    >
    >
    > > What I'm doing now works. It isn't clean, but it works.
    >
    > I agree and realize that you need a solution now. And I think you
    > don't need a patch to use your approach. Subclassing would be enough.
    > The trick is to put your subclass in org.objectstyle.cayenne.access
    > package (inside your application source tree of course). The fields
    > you need to access are not private, they are just not public, so by
    > doing that you'll get full access to these methods:
    >
    > package org.objectstyle.cayenne.access;
    >
    > public class MyDataContext extends DataContext {
    > ...
    >
    > public List newFlattenedObjects()
    > {
    > // maybe wrap in new ArrayList() first....
    > return getObjectStore().getFlattenedInserts();
    > }
    > public List deletedFlattenedObjects()
    > {
    > // maybe wrap in new ArrayList() first....
    > return getObjectStore().getFlattenedDeletes();
    > }
    >
    > ...
    > }
    >
    >



    This archive was generated by hypermail 2.0.0 : Sat Aug 26 2006 - 15:58:38 EDT