Source code for waeup.kofa.maintenance

"""Helpers for maintainers of kofa sites.

XXX: This stuff might go into a separate package, but right
     now it is too less for a complete package.
"""
import sys
from ZODB.FileStorage import FileStorage
from ZODB.scripts.analyze import report, analyze, shorten
from zope.component.hooks import setSite
from zope.component import getUtility
from zope.catalog.interfaces import ICatalog
from zope.intid.interfaces import IIntIds


[docs]def db_analyze(args=None): """Run the analyze tool from ZODB package. """ if args is None: args = sys.argv[1:] path = None if len(args) > 0: path = args[0] else: print print "Analyze a ZODB file and print statistics" print "about contained objects, sizes, etc." print print "Usage: %s <path-to-Data.fs>" % sys.argv[0] print sys.exit(0) report(analyze(path))
[docs]def update_catalog(site, cat_name, objects=[], func=None): """Update a catalog. Put `objects` or objects delivered by `func()` into the catalog registered under `cat_name` in `site`. Objects to be catalogued must be 'located', i.e. they must have a __name__ and __parent__ (because they are adapted to IKeyReference). You can pass in objects as some iterable or as a function that is called to deliver the set of objects to be catalogued. A function takes precedence over object lists. """ setSite(site) cat = getUtility(ICatalog, name=cat_name) intids = getUtility(IIntIds, context=cat) if func is not None: objects = func() for ob in objects: doc_id = intids.queryId(ob, None) if doc_id is None: doc_id = intids.register(ob) cat.index_doc(doc_id, ob) return cat
[docs]def db_diff(args=None): """Run the analyze tool from ZODB package to find diffs between two ZODBs. """ if args is None: args = sys.argv[1:] zodb_path1, zodb_path2 = (None, None) if len(args) > 1: zodb_path1, zodb_path2 = args[0:2] else: print print "Analyze two ZODB files and print statistics" print "about contained objects, sizes, etc." print "Shows only differences." print print "Usage: %s <path-to-Data1.fs> <path-to-Data2.fs>" % sys.argv[0] print sys.exit(0) a1 = analyze(zodb_path1) a2 = analyze(zodb_path2) diff_report(a1, a2)
[docs]def diff_report(rep1, rep2): print "Processed %d (%d, %d) records in %d (%d, %d) transactions" % ( rep1.OIDS + rep2.OIDS, rep1.OIDS, rep2.OIDS, rep1.TIDS + rep2.TIDS, rep2.TIDS, rep2.TIDS) print "Types used:" fmt = " %-44s %7s %9s %6s %7s" fmtp = "%-44s %+7d %9d %5.1f%% %7.2f" # per-class format fmtpplus = "+ %-44s %+7d %+9d %+5.1f%% %7.2f" # per-class format fmtpminus = "- %-44s %+7d %+9d %+5.1f%% %7.2f" # per-class format fmts = " %44s %+7d %+8dk %+5.1f%% %+7.2f" # summary format typemap1, typemap2 = rep1.TYPEMAP.keys(), rep2.TYPEMAP.keys() typemap1.sort() typemap2.sort() typemap = list(set(typemap1 + typemap2)) typemap.sort() print fmt % ("Class Name", "Count", "TBytes", "Pct", "AvgSize") print fmt % ('-'*44, '-'*7, '-'*9, '-'*5, '-'*7) for t in typemap: if t in typemap1 and t in typemap2 and ( rep1.TYPESIZE[t] == rep2.TYPESIZE[t]) and ( rep1.TYPEMAP[t] == rep2.TYPEMAP[t]): continue if t not in typemap1: cnt = rep2.TYPEMAP[t] pct = rep2.TYPESIZE[t] * 100.0 / rep2.DBYTES print fmtpplus % (shorten(t, 44), cnt, rep2.TYPESIZE[t], pct, rep2.TYPESIZE[t] * 1.0 / rep2.TYPEMAP[t]) elif t not in typemap2: cnt = -rep1.TYPEMAP[t] pct = rep1.TYPESIZE[t] * 100.0 / rep1.DBYTES print fmtpminus % (shorten(t, 44), cnt, -rep1.TYPESIZE[t], pct, rep1.TYPESIZE[t] * 1.0 / rep1.TYPEMAP[t]) else: cnt = rep2.TYPEMAP[t] - rep1.TYPEMAP[t] pct1 = rep1.TYPESIZE[t] * 100.0 / rep1.DBYTES pct2 = rep2.TYPESIZE[t] * 100.0 / rep2.DBYTES pct = pct2 - pct1 size = rep2.TYPESIZE[t] - rep1.TYPESIZE[t] if cnt > 0: print fmtpplus % ( shorten(t, 44), cnt, size, pct, rep2.TYPESIZE[t] * 1.0 / rep2.TYPEMAP[t]) else: print fmtpminus % ( shorten(t, 44), cnt, size, pct, rep1.TYPESIZE[t] * 1.0 / rep1.TYPEMAP[t]) print fmt % ('='*44, '='*7, '='*9, '='*5, '='*7) print fmts % ('Current Objects', rep2.COIDS - rep1.COIDS, (rep2.CBYTES / 1024.0) - (rep1.CBYTES / 1024.0), (rep2.CBYTES * 100.0 / rep2.DBYTES) - ( rep1.CBYTES * 100.0 / rep1.DBYTES), (rep2.CBYTES * 1.0 / rep2.COIDS) - ( rep1.CBYTES * 1.0 / rep1.COIDS)) #if rep1.FOIDS and rep2.FOIDS: fbytes = (rep2.FBYTES / 1024.0) - (rep1.FBYTES / 1024.0) rep1_fpct = (rep1.DBYTES and (rep1.FBYTES * 100.0 / (rep1.DBYTES)) or 0.0) rep2_fpct = (rep2.DBYTES and (rep2.FBYTES * 100.0 / (rep2.DBYTES)) or 0.0) print fmts % ('Old Objects', rep2.FOIDS - rep1.FOIDS, fbytes, rep2_fpct - rep1_fpct, (rep2.FBYTES * 1.0 / (rep2.FOIDS or 1.0)) - ( rep1.FBYTES * 1.0 / (rep1.FOIDS or 1.0))) return