Hi!

On 07/08/2008 01:02 PM Derick Rethans wrote:
> On Tue, 8 Jul 2008, Tobias Schlitt wrote:

>> Refetching objects
>> ==================
>>
>> Problem
>> -------
>>
>> It might be desirable to re-fetch a set of objects during a request. A
>> global switch in the ezcPersistentIdentityMap instance will allow this
>> to happen. If this switch is turned on, ezcPersistentIdentitySession
>> should fetch the values of the affected objects from the database again
>> and cache them.
>>
>> Solution
>> --------
>>
>> The $refetch option will be moved from ezcPersistentIdentityMap to
>> ezcPersistentIdentitySession. If it is turned on, the session will not
>> ask the identity map for an identity, but directly issue the query. The
>> results of this query will be "replaced" into the identity map, using a
>> new replaceObject() method. This method will check, if an identity of
>> the object already exists. Is this the case, it will replace the values
>> in the existing identity with the values of the submitted object and
>> return the existing identity. If no identity exists, the submitted
>> identity will be recorded and returned. The session will always replace
>> the fetched object with the one returned from replaceObject().

> Isn't this too course-grained? What if I just want to re-fetch for one 
> specific object? Now I'd have turn the option globally on, re-fetch the 
> object and turn it back on. Why can't it be a parameter to load() ?

The described case is just relevant if you want to update multiple
identities using a find query. In case you only want to update data for
1 object, you'd use ezcPersistentSession->refresh() anyway. This already
works as desired.

In an open issue in the current design doc I also suggested to enhance
the refresh() method to work on an array of objects and perform a single
SELECT query to refresh all together.

>> Refetching relations
>> ====================
>>
>> Problem
>> -------
>>
>> In PersistentObject 1.5 it shall be possible to pre-fetch related
>> objects. The idea is to provide methods for this pre-fetching and store
>> the fetched objects in the identity map. On calls to getRelatedObjects()
>> the cached results will be returned instead of issueing new SELECT
>> statements.
>>
>> The method ezcPersistentSession->createRelationFindQuery() allows the
>> user to manipulate the query used to fetch related objects (mainly for
>> the WHERE clause). The created query can be used with
>> ezcPersistentSession->find(). If we support relation pre-fetching using
>> the createRelationFindQuery() method, we cannot make sure that the
>> complete set of related objects is fetched, as it would potentially be
>> expected by getRelatedObjects() later.
>>
>> Solution
>> --------
>>
>> ezcPersistentIdentitySession->createRelationFindQuery() will not support
>> pre-fetching of related objects. It will simple work as it does in
>> ezcPersistentSession and only the normal identity mapping is applied,
>> when using find() to issue the created query object.
>>
>> The $refetchRelations and $cacheRelation options will be removed.
>>
>> To provide pre-fetching of relations, dedicated methods are provided:
>>
>> - findWithRelatedObjects( ezcPersistentFindQuery $q, array $related )
>>
>>   This method will not allow the user to influence the WHERE clause of
>>   the relation joins. Only the WHERE clause used to find the source
>>   objects can be manipulated.
>>
>>   The query $q can be created by
>>   ezcPersistentIdentitySession->createFindQuery() or
>>   ->createRelationFindQuery(). Since the decorated ezcQuerySelect is
>>   used here, JOIN operations will be completly forbiddenin this query
>>   object to avoid inconsistencies.

> WHere/how are you decorating ezcQuerySelect?

That was also mentioned earlies in the design discussion.

My idea is to provide a wrapper for the ezcQuerySelect, that contains
meta info for the persistence session. This would also allow us to
deprecate the $class parameter to ezcPersistentSession->find().

It makes sense in several places of the identity map.

The decoration will be performed in the create*Query() methods and will
be transparent for the user.

>>   This behavior ensures that getRelatedObjects() will have the correct
>>   relation sets available, whenever it is called.
>>
>> - createdRelationSetFindQuery( string $class, array $relations,
>>                                string $setName )
>>
>>   This method will return a specially decorated ezcQuerySelect object,
>>   that contains some meta information: The classes that will be
>>   extracted and the name of the set. The next method described here can
>>   be used to fetch this set and store it in a special place in the
>>   identity map. Such sets can only be retrieved from
>>   ezcPersistentIdentitySession using another special method.
>>
>> - findRelatedObjectSet( ezcPersistentRelationSetQuery $q )
>>
>>   Finds relation sets as defined through the query object build by
>>   the createdRelationSetFindQuery() method. The source objects (defined
>>   through the $class attribute to createdRelationSetFindQuery()) are
>>   fetched as they are and their identity is stored. Assigned to these
>>   identities, the related objects (defined through the $relations
>>   parameter to createdRelationSetFindQuery()) are not stored in the
>>   normal relation map inside the identity map. Instead they are stored
>>   in a special relation structure, that reflects the name of the set.
>>
>>   The objects identities themselves are created and retrieved from the
>>   cache as usual.
>>
>> - getRelatedObjectsSet( object $source, string $class,
>>                         string $relationName, string $setName )
>>
>>   This method is used to retrieve a related object set from the identity
>>   map. It looks up the set defined by the parameters in the structure
>>   created by findRelatedObjectSet() and returns it.

> I don't quite see why you need this set stuff... it seems all so 
> complicated.

The current design allows yout to manipulate the pre-fetch query. For
example, you want to fetch User objects and the Book objects they
bought. But you are not interessted in all books, but only the 10 most
recent ones. If you call getRelatedObjects( $user, 'Book' ) you expect
*all* books of the user to be returned. Since the pre-fetch only loaded
the 10 most recent ones, this would not satisfy your assumption anymore.

I think the set stuff is quite sensible and solves the issue.

Regards,
Toby
-- 
Mit freundlichen Grüßen / Med vennlig hilsen / With kind regards

Tobias Schlitt (GPG: 0xC462BC14) eZ Components Developer

[EMAIL PROTECTED] | eZ Systems AS | ez.no
-- 
Components mailing list
[email protected]
http://lists.ez.no/mailman/listinfo/components

Reply via email to