[IndexedCatalog] IC support for object subclasses

Johan Dahlin jdahlin at async.com.br
Wed Mar 19 16:37:38 BRST 2003


IndexedCatalog up to now has not included a good framework for using and
querying subclasses of IndexedObjects. In other words, if you had an
object hierarchy with Foo, Bar(Foo) and Baz(Foo), it was impossible to
query for all the Foo objects. Furthermore, the semantics for
inheritance of _ic_options were a bit misty.

Since one of our internal applications needs this in a number of places,
we've been working on a good solution for this over the last weeks.
Finding a good solution, however, is non-trivial, and it's been a lot of
work. Under the last week I've been hacking in better support for
subclassing of classes. This has resulted in a number of cleanups and
changes in IndexedCatalog. A few of them are not backwards compatible
and some change the semantics a lot.

These changes are checked in at the moment on the subclassed-catalogs
branch. It would be really nice to get feedback on the changes since we
have not rolled it out internally. There could be problems with the
semantics we defined, and things might not work as expected, so your
contributions are appreciated.

User-visible Changes

The most important policy change is that there is always *one* Catalog
tied to one class. So if you're doing this:

class Test(IndexedObject):
    _ic_options = [attr('cell_phone', Phone),
                   attr('work_phone', Phone)]

There will only be one Catalog tied to the Phone class. Regardless of
the objects in the Phone Catalog, the query for cell_phone and
work_phone will always return the same results. If you need separate
catalogs for this purpose, you'd need to define CellPhone and WorkPhone
classes (perhaps sharing a common BasePhone class).

Though this does require changing some code, it provides for a lot more
flexibility in composing your object hierarchy.

_ic_weak is also now gone, use weak=1 in _ic_options, e.g.
_ic_options = [attr('foo', FooObject, weak=1)]

One side-effect of this change is that we now require a global registry
inside IndexedCatalog, and this registry needs to be saved. This will be
solved shortly with Database and Shelf classes (not quite there yet).
For now, you should use something like we're using in the test suite:

from IndexedCatalog import Registry

def setup_registry(root):
    """root is the ZODB root object, returned by db.open()"""
    if not root.has_key('_ic_registry'):
        root['_ic_registry'] = Registry.registry
    else:
        Registry.registry = root['_ic_registry']

And call this before you're using any objects in the root of your
storage. This could be changed to a factory method so that you asked the
Registry (a singleton) to create your catalogs, and opinions on this are
also appreciated.

Please test, critique and follow-up :-)

-- 
Johan Dahlin <jdahlin@async.com.br>
Christian Reis <kiko@async.com.br>
Async Open Source



More information about the IndexedCatalog mailing list