Yes, you can set some things if you use ERCoreBusinessLogic
It handles the number of objects in a list page (displayed objects) and sort
order preferences, for example.
David
On 2011-11-24, at 3:38 PM, Chuck Hill wrote:
> Yes, but I am not going to tell you the name of that class, you have to find
> it for yourself. :-P
>
> There might also be a model with preferences in it, maybe that was user
> preferences?
>
>
> Chuck
>
> On 2011-11-24, at 3:35 PM, Pascal Robert wrote:
>
>> 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
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>
>
> --
> 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/programmingosx%40mac.com
>
> This email sent to [email protected]
_______________________________________________
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]