[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