[Zope-CVS] CVS: ZODB4/Doc - changes.txt:1.1

Jeremy Hylton jeremy@zope.com
Mon, 29 Jul 2002 15:09:39 -0400

Update of /cvs-repository/ZODB4/Doc
In directory cvs.zope.org:/tmp/cvs-serv16423/Doc

Added Files:
Log Message:
Add summary of changes since ZODB3.

XXX in progress

=== Added File ZODB4/Doc/changes.txt ===
A brief summary of the changes between ZODB3 and ZODB4.

The ZODB3 package provides three kinds of functionality that have been
split into three separate packages in ZODB4: Persistence, Transaction,
and ZODB.  Persistence provides the machinery for tracking the state
of persistent objects via the Persistent base class.  Transaction
provides transaction control for ZODB and other transaction-aware
software.  ZODB provides the backend database for storing persistent
objects using pickles.

The first changes you will run into are changes in the layout of
packages, modules, and classes.  You will probably need to update a
lot of import statements to get things from their current locations.
One reason for these changes is to avoid complicated __init__ modules
in packages, which hid the real locations of objects.  Here's a brief
summary of the changes, organized by object name.


    In ZODB4, use "from Transaction import get_transaction."  The
    default transaction manager is created in Transaction/__init__.py.
    In ZODB3, this name was placed in __builtins__ as a side-effect
    of importing ZODB.


    The DB class is defined in the module ZODB.DB, which means one way
    to get it is "from ZODB.DB import DB."  Some of the storages now
    provide a DB() convenience function that opens a storage and
    returns a DB that uses it: "from ZODB.FileStorage import DB."
    This is currently supported for FileStorage and MappingStorage.
    The DB functions take all the arguments of the storage, followed
    by all the arguments of the DB (except the storage argument).

    PersistentList, PersistentMapping

    These are now modules within the Persistence package.  The classes
    are thus available as "from Persistence.PersistentList import
    PersistentList."   XXX There is a good change that PersistentMapping
    will be renamed PersistentDict.


    The BTrees package is currently a sub-package of Persistence.
    Thus, "from Persistence.BTrees.IOBTree import IOBTree".  XXX We
    might change this back to the old version with BTrees as a
    top-level package.

Note that Persistent is still advertised as Peristence.Persistent,
because it's name would otherwise be Persistence.cPersistence.Persistent, 
which seems to ugly.

Although the changes doesn't have much user-visible effect, one of the
biggest changes is that the Persistent base class is now a Python
extension type implemented as a C subclass of type.  This version of
ZODB does not rely on ExtensionClass, which makes it possible to work
with new-style classes and other Python 2.2 features.

The Persistence API has changed somewhat, which will affect the way
user code interacts with the persistence infrastructure.  The methods
_p_activate() and _p_deactivate() can be used to make a ghost and real
object and vice versa; these methods are preferred over the special
forms of _p_change.  As a result, the preferred use of _p_changed is
just to set it to True when an object is changed.

The hooks for writing __getattr__() and __setattr__() methods on
Persistent classes have also changed.  The API is currently in a bit
of flux.  Expect changes.  At the moment, an __setattr__() method
should first called _p_setattr().  If that method returns True, the
assignment was handled by the persistence machinery and the user code
shouldn't do anything.  If it returns False, the user code should
handle the attribute.  It is necessary to call this method first to
guarantee that the object is not a ghost.  The _p_delattr() method
works the same way for __delattr__() functions.  There's nothing to do
for __getattr__().  I haven't tried __getattribute__(), but I expect
it won't work.

The Transaction implementation has been completely overhauled.  There
are four significant changes that users may need to cope with.  The
first is that a transaction that fails because of an uncaught
exception is not aborted.  The user code should explicitly call
get_transaction().abort().  The second is that commit() does not take
an optional argument to flag subtransaction commits.  Instead, call
the savepoint() method.  ZODB will return a rollback object from
savepoint().  If the rollback object's rollback() method is called, it
will abort the savepoint() -- rolling back changes to the previous
savepoint or the start of the transaction.

The other changes to the Transaction implementation affect
implementors of resource / data managers.  The ZODB Connection object
is an example of a data manager.  When the persistence machinery
detects that an object has been modified, the register() method is
called on its data manager.  It's up to the data manager to register
with the transaction.  The manager is registered with the transaction,
not the individual objects.  The interface the data manager implements
(IDataManager) has changed.  It should implement four methods:
prepare(), abort(), commit(), and savepoint().  Here is how they
correspond to the odl API: prepare() is roughly equivalent to
tpc_begin() through tpc_vote().  abort() and commit() are roughly
equivalent to tpc_abort() and tpc_finish().  savepoint() is used for