[TransWarp] peak.naming .. first contact

Phillip J. Eby pje at telecommunity.com
Fri Feb 14 15:35:19 EST 2003


At 07:22 PM 2/14/03 +0100, Ulrich Eck wrote:
>for now i want to be able to lookup and create Folders mainly. one issue 
>is, that i need to modify them e.g. by
>setting the folder-acls. so when using the name-context approach, how do i 
>access/modify attributes of the
>context .. is there any preferred way to setup something like this ?? (i 
>remember barely that jndi has
>methods for accessing attributes on contexts)

This is the weak point in the current interfaces and base classes.  I'll 
consider patches for this.  :)

If you look at the peak.naming.interfaces, IReadContext and IWriteContext 
have comments like this:

     # XXX search, getAttributes

and

     # XXX modifyAttributes

These methods should probably be defined in the interfaces, and some 
support for this added to the context base classes.  I haven't yet 
encountered a situation where I actually need these, so I've left them 
unspecified.  If you can describe your use cases, maybe I can see how they 
should be fleshed out.


>i've gone ahead with the data-manager approach and it looks good. (still 
>need to figure out what's the best
>setup for them, and how to build QueryDMs that are used by elements for 
>e.g. <ImapFolder>.childObjects(model.Collection))
>i've seen the QueryLink Class in Datamangers. how could it be used to 
>setup an ElementClass with
>a feature that exposes the results of that query when called ??
>
>class ImapFolder(model.Element):
>
>    class folderpath(model.Field):
>        """The Folders Path."""
>
>    class folders(model.Collection):
>        """Collection of ChildFolders."""
>
>    class messages(model.Collection):
>        """Collection of Messages contained in this Folder."""
>
>would i just pass a state that has e.g.
>return dict(Items(folders=QueryLink(MyFolderQuery[(<folderpath>,)]), 
>..same-for-messages..))
>that is a not yet executed PersistentQuery and supplies a list-like interface
>for the collection class ??

That's basically correct.  I assume that MyFolderQuery is a QueryDM that 
takes a tuple containing a folder path  as an object ID.  You would 
implement that QueryDM by having its '_load()' method return a sequence of 
folders, and keeping the default QueryDM defaultClass of 
'PersistentQuery'.  So you don't have to implement a "list-like interface" 
if you don't want to.  PersistentQuery and QueryLink will take care of this 
for you.

However, that all assumes that the 'folders' collection isn't the end of 
the relationship that you manipulate in your underlying storage.  If you 
want to have your '_save()' routine look at this list to decide what to 
add, then this is not the way to do it (the QueryLink should be on the 
"parent" pointer side of the relationship).  If your '_save()' routine 
instead looks at what the parent folder of this folder is in order to 
figure out what to add it to, then you should use the approach you've 
described here.

Of course, if folders aren't moveable, and can only ever exist in one 
place, the approach you describe will also work.  Note, by the way, that 
this is an issue only at the level of implementing the data manager; the 
object model is unaffected regardless of which of the three ways the 
relationship is implemented.

A quick explanation of QueryLink, for those who haven't studied the code as 
much as Ulrich: QueryLinks are a proxy for use in an object's loaded state 
to reference a persistent query whose contents represent the value of a 
collection or sequence property.  They keep changes to the object from 
affecting the underlying query, and they also prevent execution of the 
query if the object is modified without actually looking at the results of 
the query.  In this way, if you have a collection with 10,000 things in it 
("virtually"), it isn't necessary to load the list of 10,000 things to add 
an item to it.  What happens is that if the query hasn't already executed, 
the QueryLink ignores the modification attempts (under the assumption that 
if you look at the collection later, the query will execute and be 
up-to-date).  If the query has executed, the QueryLink makes a copy of the 
query results, and modifies the copy.

Last, but not least, whenever any operation (whether read or write) is 
performed on a QueryLink, it checks whether the data in the underlying 
query has been refreshed since the QueryLink made a copy of it, and if so, 
discards its local copy.

QueryLinks are designed primarily for use with relational databases and 
other systems that implement one-to-many relationships via a pointer on the 
"one" side, and a query on the "many" side.  The QueryLink is used on the 
"many" side, while the "one" side is implemented via a straightforward 
load/save on the "pointer" (foreign key).





More information about the PEAK mailing list