From: Anjo K. <an...@us...> - 2006-03-29 12:55:56
|
Update of /cvsroot/wonder/Wonder/Common/Frameworks/ERExtensions/Sources/er/extensions In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv7037/ERExtensions/Sources/er/extensions Modified Files: ERXDatabaseContextDelegate.java Added Files: ERXArrayFaultCache.java Log Message: ERXArrayFaultCache added --- NEW FILE: ERXArrayFaultCache.java --- package er.extensions; import java.util.*; import com.webobjects.eoaccess.*; import com.webobjects.eocontrol.*; import com.webobjects.foundation.*; /** * Provides a cache for to-many faults. Useful when you have a lot (say a * few thousand) objects for which you need to access a to-many relationship * that hasn't been fetched yet. * * The idea is that instead of batch-faulting you could fetch all the entries * for a given to-many relationship in one fetch (as raw rows), group them in * memory and register the faults here. Then you set up your EODatabaseContext * delegate to use this object to try and clear the fault first. * * @author ak * */ public class ERXArrayFaultCache { private NSMutableDictionary cache = new NSMutableDictionary(); /** * Register the to-many faults by entity name and relationship name. The entries * are a dictionary where the key is the source EOGlobalID for the relationship * and the values are arrays of global IDs for the destination. * @param entityName * @param relationshipName * @param entries */ public void registerRelationshipCacheEntries(String entityName, String relationshipName, NSDictionary entries) { synchronized (cache) { if(entries == null) { cache.removeObjectForKey(entityName + "\0" + relationshipName); } else { cache.setObjectForKey(entries.immutableClone(), entityName + "\0" + relationshipName); } } } private NSDictionary relationshipCacheEntriesForEntity(String entityName, String relationshipName) { synchronized (cache) { return (NSDictionary) cache.objectForKey(entityName + "\0" + relationshipName); } } /** * Attempts to clear a fault by looking up the source global id and faulting in the corresponding * destination values. * @param obj * @return true if the fault could be cleared or it wasn't a fault in the first place, false if not */ public boolean clearFault(Object obj) { if(!EOFaultHandler.isFault(obj)) { return true; } EOFaulting fault = (EOFaulting)obj; if (fault.faultHandler() instanceof EOAccessArrayFaultHandler) { EOAccessArrayFaultHandler handler = (EOAccessArrayFaultHandler) fault.faultHandler(); EOKeyGlobalID sourceGid = handler.sourceGlobalID(); EOEditingContext ec = handler.editingContext(); EOEntity entity = ERXEOAccessUtilities.entityNamed(ec, sourceGid.entityName()); synchronized (cache) { NSDictionary entries = (NSDictionary) relationshipCacheEntriesForEntity(sourceGid.entityName(), handler.relationshipName()); if(entries != null) { NSMutableArray snapshots = (NSMutableArray) entries.objectForKey(sourceGid); if(snapshots != null) { NSMutableArray gids = new NSMutableArray(snapshots.count()); for (Enumeration enumerator = snapshots.objectEnumerator(); enumerator.hasMoreElements();) { EOGlobalID gid = (EOGlobalID) enumerator.nextElement(); EOEnterpriseObject eo = ec.faultForGlobalID(gid, ec); gids.addObject(eo); } EOFaultHandler.clearFault(obj); ((NSMutableArray)fault).addObjectsFromArray(gids); return true; } } } } return false; } } Index: ERXDatabaseContextDelegate.java =================================================================== RCS file: /cvsroot/wonder/Wonder/Common/Frameworks/ERExtensions/Sources/er/extensions/ERXDatabaseContextDelegate.java,v retrieving revision 1.28 retrieving revision 1.29 diff -C2 -d -r1.28 -r1.29 *** ERXDatabaseContextDelegate.java 18 Jan 2006 17:12:10 -0000 1.28 --- ERXDatabaseContextDelegate.java 29 Mar 2006 12:55:46 -0000 1.29 *************** *** 35,38 **** --- 35,39 ---- /** defines if the JDBC connection should be switched to read only on certain database operations or not. Default is not. */ private Boolean switchReadWrite = null; + private ERXArrayFaultCache arrayFaultCache = null; /** Returns the singleton of the database context delegate */ *************** *** 40,44 **** return _defaultDelegate; } ! /** * Provides for a hook to get at the original exceptions from the JDBC driver, as opposed to the cooked --- 41,53 ---- return _defaultDelegate; } ! ! public ERXArrayFaultCache arrayFaultCache() { ! return arrayFaultCache; ! } ! ! public void setArrayFaultCache(ERXArrayFaultCache value) { ! arrayFaultCache = value; ! } ! /** * Provides for a hook to get at the original exceptions from the JDBC driver, as opposed to the cooked *************** *** 199,203 **** Delegate method. Will switch the connection to read only. **/ ! public boolean databaseContextShouldFetchArrayFault(EODatabaseContext eodatabasecontext, Object obj) { if(log.isDebugEnabled()) { log.debug("databaseContextShouldFetchArrayFault.. Setting it to ReadOnly"); --- 208,218 ---- Delegate method. Will switch the connection to read only. **/ ! public boolean databaseContextShouldFetchArrayFault(EODatabaseContext eodatabasecontext, Object obj) { ! if(arrayFaultCache != null) { ! arrayFaultCache.clearFault(obj); ! if(!EOFaultHandler.isFault(obj)) { ! return false; ! } ! } if(log.isDebugEnabled()) { log.debug("databaseContextShouldFetchArrayFault.. Setting it to ReadOnly"); |