[Zodb-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