Man, does Wonder also have a method to find the meaning of life since it have
something for everything else? :-)
> No question, put them in the database. Use ERXEnterpriseObjectCache to avoid
> needless repeated database trips.
>
> Using the standard WO classes:
>
> /**
> * Creates a standard EO cache object for the passed entity name and
> keypath for all objects of
> * the entity that match restrictingQualifier. If restrictingQualifier is
> null, all objects of this entity are
> * cached.
> *
> * @param entityName name of the EOEntity for the instances that will be
> in the cache
> * @param keyPath key path of unique value in EOs
> * @param restrictingQualifier EOQualifier restricting the set of objects
> in the cache
> * @param shouldFetchInitialValues true if the cache should be fully
> populated on first access
> * @return a standard EO cache object for the passed entity name and
> keypath
> */
> public static ERXEnterpriseObjectCache createCache(String entityName,
> String keyPath, EOQualifier restrictingQualifier, boolean
> shouldFetchInitialValues) {
> /** require [valid_entityName] entityName != null;
> [valid_keyPath] keyPath != null;
> **/
>
> EOEditingContext ec = new EOEditingContext();
> ec.lock();
> try
> {
> EOObjectStoreCoordinator osc = (EOObjectStoreCoordinator)
> ec.rootObjectStore();
> osc.lock();
>
> try
> {
> long timeout = // get this from a property
> boolean shouldRetainObjects = true;
> boolean shouldReturnUnsavedObjects = true; // Needed for
> imports where new objects reference other new objects
> ERXEnterpriseObjectCache cache = new
> ERXEnterpriseObjectCache(entityName, keyPath, restrictingQualifier, timeout,
>
> shouldRetainObjects, shouldFetchInitialValues, shouldReturnUnsavedObjects);
>
> /**
> * OK, things get nasty here. You HAVE been warned!
> *
> * The cache has an interaction with the EOEditingContext
> fetchTimestamp()/defaultFetchTimestampLag(). After
> * the objects have been fetched into the cache, if the
> defaultFetchTimestampLag() passes before they are
> * re-fetched, when they are faulted into a new editing
> context (localInstanceOfObject), the snapshot will be discarded
> * and the objects re-fetched, one by one. This rather
> eliminates the value of the cache.
> *
> * There are a few options to fix this:
> * - use a large defaultFetchTimestampLag() and ensure that
> all the places that need fresh data use
> * a fetch specification that refreshes re-fetched objects.
> This also means that you must pre-fetch all
> * the objects that need fresh data. This makes the
> defaultFetchTimestampLag() rather useless to control
> * data freshness.
> *
> * - use a large defaultFetchTimestampLag() and implement
> ERChangeNotification to keep all the EOF stacks
> * in sync. This ensures current data without needing to
> use defaultFetchTimestampLag().
> *
> * - use a custom EODatabaseContext.delegate and implement the
> delegate method
> * databaseContextShouldFetchObjectFault(EODatabaseContext,
> Object) to use the existing snapshot regardless of age.
> * To implement this, the delegate will need to know that
> the entity is being cached. This can be done by setting
> * a flag in EOEntity.userInfo in this method.
> *
> * - make the objects as "Cache in Memory" in the EOModel.
> The large drawback of this is that the objects will never
> * be refreshed. Refreshing fetch specifications do not
> affect entities cached in memory.
> *
> * - mark the snapshots of the cached objects as expiring at
> some time in the distant future. As they expire from the
> * cache they will be re-fetched and refreshed from the
> database. This option was chosen as it more closely matches
> * what should happen. It does require access to a
> protected method in EODatabase. It is possible that future
> * versions of WebObjects will break this implementation,
> but there should be some way of achieving the result.
> */
> EOEntity entity = EOUtilities.entityNamed(ec, entityName);
> EODatabaseContext dbContext =
> EOUtilities.databaseContextForModelNamed(ec, entity.model().name());
> EODatabase database = dbContext.database();
> NSArray objectsInCache = cache.allObjects(ec);
> for (int i = 0; i < objectsInCache.count(); i++)
> {
> EOEnterpriseObject eo = (EOEnterpriseObject)
> objectsInCache.objectAtIndex(i);
> // Sets the expiration timestamp for the snapshot to
> NSTimestamp.DistantFuture.getTime()
> _setTimestampForCachedGlobalID().invoke(database,
> ec.globalIDForObject(eo));
> }
>
> return cache;
> }
> catch (Exception e)
> {
> throw new ExceptionConverter(e);
> }
> finally
> {
> osc.unlock();
> }
> }
> finally
> {
> ec.unlock();
> ec.dispose();
> }
>
> /** ensure [valid_result] Result != null; **/
> }
>
>
> private static Method _setTimestampForCachedGlobalID = null;
> /**
> * Hack to access protected method in EODatabase.
> * @return Method for protected void
> _setTimestampForCachedGlobalID(EOGlobalID gid)
> */
> private static Method _setTimestampForCachedGlobalID()
> {
> synchronized (GenericRecord.class)
> {
> if (_setTimestampForCachedGlobalID == null)
> {
> try
> {
> _setTimestampForCachedGlobalID =
> EODatabase.class.getDeclaredMethod("_setTimestampForCachedGlobalID",
>
> new Class[] {EOGlobalID.class});
> _setTimestampForCachedGlobalID.setAccessible(true);
> }
> catch (Exception e)
> {
> throw new ExceptionConverter(e);
> }
> }
> }
>
> return _setTimestampForCachedGlobalID;
> }
>
> Chuck
>
>
>
> On 2011-11-24, at 12:45 PM, Pascal Robert wrote:
>
>> I want to add some "system preferences" to SimpleBlog, for things like
>> number of comments per page, if comments are moderated or not, etc. I'm
>> wondering what's the best way to handle that. I was thinking of using a
>> plist and read it at "boot time" so that the preferences are in memory, and
>> writing the file when a pref changes. The problem with this solution is that
>> the file will have to be outside the .woa since the preferences have to
>> survive a upgrade. And if a server have more than one SimpleBlog instance
>> (e.g., "multi tenants"), it would have to be different files.
>>
>> The other solution would be to store the preferences in the database. In the
>> case of multi tenants, each instance would have to have it own databases.
>> The potential problem would be a performance one, we would need to call EOF
>> every time a preference is needed (for display groups, etc.). Sure, I'm not
>> talking about high performance system here, but it would be great to show
>> best practices.
>>
>> So, how would you manage this?
>> _______________________________________________
>> Do not post admin requests to the list. They will be ignored.
>> Webobjects-dev mailing list ([email protected])
>> Help/Unsubscribe/Update your Subscription:
>> http://lists.apple.com/mailman/options/webobjects-dev/chill%40global-village.net
>>
>> This email sent to [email protected]
>
> --
> 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
>
>
>
>
>
>
>
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Webobjects-dev mailing list ([email protected])
Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/webobjects-dev/archive%40mail-archive.com
This email sent to [email protected]