[Zope3-checkins] CVS: ZODB4/ZODB - dbdump.py:1.1 Serialize.py:1.9 fsdump.py:1.7

Jeremy Hylton jeremy@zope.com
Tue, 3 Dec 2002 18:07:05 -0500


Update of /cvs-repository/ZODB4/ZODB
In directory cvs.zope.org:/tmp/cvs-serv21967

Modified Files:
	Serialize.py fsdump.py 
Added Files:
	dbdump.py 
Log Message:
Add dbdump with generic database dumping code,
and a filestorage-specific method to invoke it.
Move serialization logic to Serialize.


=== Added File ZODB4/ZODB/dbdump.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.
# 
##############################################################################
"""Provide a text dump of a storage based on a storage iterator."""

from ZODB.FileStorage import FileIterator
from ZODB.TimeStamp import TimeStamp
from ZODB.utils import u64
from ZODB.tests.StorageTestBase import zodb_unpickle
from ZODB.Serialize import SimpleObjectReader

import md5
import time

def dbdump(iter, outp=None, with_offset=True):
    i = 0
    for trans in iter:
        t = TimeStamp(trans.tid).timeTime()
        # special case just for FileStorage
        if with_offset and hasattr(trans, "_pos"):
            print >> outp, "Trans #%05d tid=%016x time=%s offset=%d" % \
                  (i, u64(trans.tid), time.ctime(t), trans._pos)
        else:
            print >> outp, "Trans #%05d tid=%016x time=%s" % \
                  (i, u64(trans.tid), time.ctime(t))
        print >> outp, "\tstatus=%s user=%s description=%s" % \
              (`trans.status`, trans.user, trans.description)
        j = 0
        for rec in trans:
            if rec.data is None:
                fullclass = "undo or abort of object creation"
            else:
                # Any object reader will do
                reader = SimpleObjectReader()
                fullclass = reader.getClassName(rec.data)
                dig = md5.new(rec.data).hexdigest()
            # special case for testing purposes
            if fullclass == "ZODB.tests.MinPO.MinPO":
                obj = zodb_unpickle(rec.data)
                fullclass = "%s %s" % (fullclass, obj.value)
            if rec.version:
                version = "version=%s " % rec.version
            else:
                version = ''
            print >> outp, "  data #%05d oid=%016x %sclass=%s" % \
                  (j, u64(rec.oid), version, fullclass)
            j += 1
        print >> outp
        i += 1
    iter.close()

def fsdump(path, outp=None, with_offset=True):
    iter = FileIterator(path)
    dbdump(iter, outp, with_offset)


=== ZODB4/ZODB/Serialize.py 1.8 => 1.9 ===
--- ZODB4/ZODB/Serialize.py:1.8	Mon Dec  2 16:22:33 2002
+++ ZODB4/ZODB/Serialize.py	Tue Dec  3 18:07:05 2002
@@ -183,6 +183,11 @@
                 
         return object
 
+    def getClassName(self, pickle):
+        unpickler = self._get_unpickler(pickle)
+        module, classname, newargs = unpickler.load()
+        return "%s.%s" % (module, classname)
+
     def getGhost(self, pickle):
         unpickler = self._get_unpickler(pickle)
         module, classname, newargs = unpickler.load()
@@ -205,6 +210,12 @@
         state = unpickler.load()
         object.__setstate__(state)
         return object
+
+class SimpleObjectReader(BaseObjectReader):
+    """Minimal reader for a single data record."""
+
+    def _persistent_load(self, oid):
+        return None
 
 class ConnectionObjectReader(BaseObjectReader):
 


=== ZODB4/ZODB/fsdump.py 1.6 => 1.7 ===
--- ZODB4/ZODB/fsdump.py:1.6	Tue Dec  3 13:46:30 2002
+++ ZODB4/ZODB/fsdump.py	Tue Dec  3 18:07:05 2002
@@ -11,78 +11,6 @@
 # FOR A PARTICULAR PURPOSE.
 # 
 ##############################################################################
-from ZODB.FileStorage import FileIterator
-from ZODB.TimeStamp import TimeStamp
-from ZODB.utils import u64
-from ZODB.tests.StorageTestBase import zodb_unpickle
-
-from cPickle import Unpickler
-from cStringIO import StringIO
-import md5
-import types
-
-def get_pickle_metadata(data):
-    # ZODB's data records contain two pickles.  The first is the class
-    # of the object, the second is the object.
-    if data.startswith('(c'):
-        # Don't actually unpickle a class, because it will attempt to
-        # load the class.  Just break open the pickle and get the
-        # module and class from it.
-        modname, classname, rest = data.split('\n', 2)
-        modname = modname[2:]
-        return modname, classname
-    f = StringIO(data)
-    u = Unpickler(f)
-    try:
-        class_info = u.load()
-    except Exception, err:
-        print "Error", err
-        return '', ''
-    if isinstance(class_info, types.TupleType):
-        if isinstance(class_info[0], types.TupleType):
-            modname, classname = class_info[0]
-        else:
-            modname, classname = class_info
-    else:
-        # XXX not sure what to do here
-        modname = repr(class_info)
-        classname = ''
-    return modname, classname
-
-def fsdump(path, file=None, with_offset=1):
-    i = 0
-    iter = FileIterator(path)
-    for trans in iter:
-        if with_offset:
-            print >> file, "Trans #%05d tid=%016x time=%s offset=%d" % \
-                  (i, u64(trans.tid), str(TimeStamp(trans.tid)), trans._pos)
-        else:
-            print >> file, "Trans #%05d tid=%016x time=%s" % \
-                  (i, u64(trans.tid), str(TimeStamp(trans.tid)))
-        print >> file, "\tstatus=%s user=%s description=%s" % \
-              (`trans.status`, trans.user, trans.description)
-        j = 0
-        for rec in trans:
-            if rec.data is None:
-                fullclass = "undo or abort of object creation"
-            else:
-                modname, classname = get_pickle_metadata(rec.data)
-                dig = md5.new(rec.data).hexdigest()
-                fullclass = "%s.%s" % (modname, classname)
-            # special case for testing purposes
-            if fullclass == "ZODB.tests.MinPO.MinPO":
-                obj = zodb_unpickle(rec.data)
-                fullclass = "%s %s" % (fullclass, obj.value)
-            if rec.version:
-                version = "version=%s " % rec.version
-            else:
-                version = ''
-            print >> file, "  data #%05d oid=%016x %sclass=%s" % \
-                  (j, u64(rec.oid), version, fullclass)
-            j += 1
-        print >> file
-        i += 1
-    iter.close()
 
 import struct
 from ZODB.FileStorage import TRANS_HDR, TRANS_HDR_LEN