[Zope-CVS] CVS: Products/AdaptableStorage/zodb - utils.py:1.1

Shane Hathaway shane@zope.com
Fri, 10 Jan 2003 13:31:18 -0500


Update of /cvs-repository/Products/AdaptableStorage/zodb
In directory cvs.zope.org:/tmp/cvs-serv2666/zodb

Added Files:
	utils.py 
Log Message:
Made move/rename work with objects from the filesystem.  It took some tricks,
but the tricks have unit tests, so it's not so bad. :-)

- Improved reporting of errors in failed attempts to move objects.

- Added a _setOb() patch that copies objects instead of moving or renaming
them, if that's the only thing that can be done.

- Refactored ZODB branch copying into a simple function, copyOf().

- Made FolderItems set a marker that indicates to _setOb() that it has to
copy rather than move.

Since SQL gateways use FolderItemsByKeychain instead of FolderItems, it has
always been possible to move/rename in a SQL database.  None of these
changes affect SQL operations.


=== Added File Products/AdaptableStorage/zodb/utils.py ===
##############################################################################
#
# Copyright (c) 2002 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""Utilities for handling ZODB objects.

$Id: utils.py,v 1.1 2003/01/10 18:31:16 shane Exp $
"""

from cStringIO import StringIO
from cPickle import Pickler, Unpickler


def copyOf(object):
    """Copies a ZODB object, loading subobjects as needed.

    Re-ghostifies objects along the way to save memory.
    """
    former_ghosts = []
    def persistent_id(ob, former_ghosts=former_ghosts):
        if getattr(ob, '_p_changed', 0) is None:
            # Load temporarily
            if former_ghosts:
                for g in former_ghosts:
                    g._p_changed = None
                del former_ghosts[:]
            former_ghosts.append(ob)
            ob._p_changed = 0
        return None
    stream = StringIO()
    p = Pickler(stream, 1)
    p.persistent_id = persistent_id
    p.dump(object)
    if former_ghosts:
        for g in former_ghosts:
            g._p_changed = None
        del former_ghosts[:]
    stream.seek(0)
    u = Unpickler(stream)
    return u.load()