I did something like that once... Not sure I can share the code... I don't own it... :-(
But I implemented it as follows:
BatchEditor batchEditor = new BatchEditor(anEditingContext);
// modify your EOs here ...
/// then save your editing context anEditingContext.saveChanges();
The BatchEditor function as a delegate of the EOAdaptorContext objects registered for the eomodels. Then by combining adaptor operations for updates and deletes into a single operations. For update operations as long as the entity and the changes are the same, the operations can be combined by ORing their qualifiers into a single operation. For delete operations, as long as the entity is the same the operations can be combined by ORing their qualifiers together.
The BatchEditor is a one time use only. It removes itself as a delegate once it accomplishes its function or once it's garbash collected.
The BatchEditor implements the delegate method:
public NSArray adaptorChannelWillPerformOperations(EOAdaptorChannel channel, NSArray operations) {
It then iterates over the EOAdaptorOperation objects in the operations NSArray.
For example for each operation.adaptorOperator() that is equal to EODatabaseOperation.AdaptorDeleteOperator I look at the operation.entity(). I keep a dictionary where the keys are entity names and the values are NSMutableArrays of these EOAdaptorOperations. So for example, if two operations have the same entity they both end up in the same NSMutableArray in my dictionary, i.e. groups.objectForKey("Foo") returns an NSMutableArray with the two EOAdaptorOperation objects that have "Foo" as their entity.
Then you create a new array for the merged operations. Let's say you have op1 and op2 which are delete operations for "Foo". You can :
EOQualifier combinedQualifier = ERXQ.or(op1.qualifier(), op2.qualifier());
op1.setQualifier(combinedQualifier);
then you add op1 to the resulting operations array:
mergedOperations.addObject(op1);
then your adaptorChannelWillPerformOperations() returns an NSArray with the operations that you were not able to merge (combine).
Then EOF will perform those operations (the ones that you could not merge)... so what about the merged oeprations. Well those are taken care of a bit later by the editor by implementing adaptorChannelDidPerformOperations() delegate method. This gets called after the operations have been performed and in here we take care of performing the merged operations:
public Throwable adaptorChannelDidPerformOperations(EOAdaptorChannel sender, NSArray operations, Throwable exception) {
...
in here you do iterate over the merged operations array and do this:
sender.performAdaptorOperation(op);
you have to wrap this call to performAdaptorOperation() with a try-catch because EOF will throw an exception when it sees that more than one row was updated/deleted. if that's the case you ignore the exception and continue with the next merged operation. Other exceptions you do need to re throw them so they are handled at a higher level.
Anyways, that's the idea and it worked for us.
It would be nice if EOF did this for us, or had the option to turn it on/off.
I'm amazed by how the hooks into EOF allow you to extend it in ways like this. This is one way I extended it to combine hundreds of deletes and updates to EOs into single update/delete statements.
It got complicated though when we ran into limits with ORACLE when combining a large number of qualifiers into a big OR qualifier. So the code started relatively simple and then grew when we added handling for this situation.
On Apr 17, 2009, at 1:06 PM, Dan Grec wrote: Hey all,
So we're still kicking this idea around, and my brain won't let it rest.
We're a little afraid of using the ERXEOAccessUtilities apprach as we really don't want to deal with the object graph being in a funny state.
So I've been wondering if we can influence the SQL that is generated when EditingContext.saveChanges() is called. At that point, all the notifications have been sent out and all of that stuff. So when it creates the SQL for deletedObjects, instead of going over each EO one at a time and making "delete from foo where id=bar" could it possibly check to see if there are many EOs of the same class and making a "delete from foo where id in "bar,bar2,bar3" type of dealy-o. I also understand that it needs to visit each EO one at a time to call things like EO.willDelete() on them, I'm wondering if it could do all that, then make the one line of SQL and run it... I'm going as deep as I can with Jad, but I'm way over my head.
It seems like a pretty nice optimization to me.
Is this possible or am I completely off base?
-Dan On 16-Apr-09, at 12:08 PM, Chuck Hill wrote: On Apr 16, 2009, at 6:30 AM, Vaughan Van Der Merwe wrote: So if we happen to be using multiple instances as well as a 'Wonder
cross-instance synching thingy' we could potentially end up in a
weird state by using this?
I think a more correct statement would be that the 'Wonder cross- instance synching thingy' eliminates (or at least greatly reduces) weird states and using this can bring them back. If you are not using it, you have to deal with the weird states. Or, as I suspect most people do, just not worry about them. Chuck
On 15-Apr-09, at 4:34 PM, Chuck Hill wrote:
On Apr 15, 2009, at 3:07 PM, Mike Schrag wrote:
Wonder's ERXEOAccessUtilities is what you want. This bypasses all
the
EOF validations and delete rules as well, so be aware of that.
and leaves your object graph in an inconsistent state, so you need
to
manually refresh it ...
Or just not worry about it. :-) If you are running multiple instances
and not using the Wonder cross-instance synching thingy, then this is
the same situation as EOF processing the deletes in another instance.
Chuck
--
Chuck Hill Senior Consultant / VP Development
Practical WebObjects - for developers who want to increase their
overall knowledge of WebObjects or who are trying to solve specific
problems.
http://www.global-village.net/products/practical_webobjects
------------------------------------------------------------------------------
Stay on top of everything new and different, both inside and
around Java (TM) technology - register by April 22, and save
$200 on the JavaOne (SM) conference, June 2-5, 2009, San Francisco.
300 plus technical and hands-on sessions. Register today.
Use priority code J9JMT32. http://p.sf.net/sfu/p
_______________________________________________
Wonder-disc mailing list
email@hidden
https://lists.sourceforge.net/lists/listinfo/wonder-disc
-- Chuck Hill Senior Consultant / VP Development Practical WebObjects - for developers who want to increase their overall knowledge of WebObjects or who are trying to solve specific problems. http://www.global-village.net/products/practical_webobjects------------------------------------------------------------------------------ Stay on top of everything new and different, both inside and around Java (TM) technology - register by April 22, and save $200 on the JavaOne (SM) conference, June 2-5, 2009, San Francisco. 300 plus technical and hands-on sessions. Register today. Use priority code J9JMT32. http://p.sf.net/sfu/p_______________________________________________ Wonder-disc mailing list email@hiddenhttps://lists.sourceforge.net/lists/listinfo/wonder-disc
------------------------------------------------------------------------------ Stay on top of everything new and different, both inside and around Java (TM) technology - register by April 22, and save $200 on the JavaOne (SM) conference, June 2-5, 2009, San Francisco. 300 plus technical and hands-on sessions. Register today. Use priority code J9JMT32. http://p.sf.net/sfu/p_______________________________________________ Wonder-disc mailing list email@hidden https://lists.sourceforge.net/lists/listinfo/wonder-disc
|