def main(argv): try: optv, argv = getopt.getopt(argv[1:], "h", ["help"]) except getopt.GetoptError as e: print(e, file=sys.stderr) usage(sys.stderr) sys.exit(2) for opt, _ in optv: if opt in ("-h", "--help"): usage(sys.stdout) sys.exit(0) if len(argv) != 2: usage(sys.stderr) sys.exit(2) storurl = argv[0] at = fromhex(argv[1]) stor = storageFromURL(storurl) defer(stor.close) # artificial transaction header with tid=0 to request regular commit zin = b'txn 0000000000000000 " "\n' zin += sys.stdin.read() zin = BytesIO(zin) zr = zodbdump.DumpReader(zin) zr.lineno -= 1 # we prepended txn header txn = zr.readtxn() tail = zin.read() if tail: print('E: +%d: garbage after transaction' % zr.lineno, file=sys.stderr) sys.exit(1) tid = zodbcommit(stor, at, txn) print(ashex(tid))
def zodbdump(stor, tidmin, tidmax, hashonly=False, pretty='raw', out=asbinstream(sys.stdout)): def badpretty(): raise ValueError("invalid pretty format %s" % pretty) for txn in stor.iterator(tidmin, tidmax): # XXX .status not covered by IStorageTransactionInformation # XXX but covered by BaseStorage.TransactionRecord out.write(b"txn %s %s\nuser %s\ndescription %s\n" % (ashex( txn.tid), qq(txn.status), qq(txn.user), qq(txn.description))) # extension is saved by ZODB as either empty or as pickle dump of an object rawext = txn_raw_extension(stor, txn) if pretty == 'raw': out.write(b"extension %s\n" % qq(rawext)) elif pretty == 'zpickledis': if len(rawext) == 0: out.write(b'extension ""\n') else: out.write(b"extension\n") extf = BytesIO(rawext) disf = BytesIO() pickletools.dis(extf, disf) out.write(indent(disf.getvalue(), " ")) extra = extf.read() if len(extra) > 0: out.write(b" + extra data %s\n" % qq(extra)) else: badpretty() objv = txnobjv(txn) for obj in objv: entry = b"obj %s " % ashex(obj.oid) write_data = False if obj.data is None: entry += b"delete" # was undo and data taken from obj.data_txn elif obj.data_txn is not None: entry += b"from %s" % ashex(obj.data_txn) else: # XXX sha1 is hardcoded for now. Dump format allows other hashes. entry += b"%i sha1:%s" % (len(obj.data), ashex(sha1(obj.data))) write_data = True out.write(b(entry)) if write_data: if hashonly: out.write(b" -") else: out.write(b"\n") if pretty == 'raw': out.write(obj.data) elif pretty == 'zpickledis': # https://github.com/zopefoundation/ZODB/blob/5.6.0-55-g1226c9d35/src/ZODB/serialize.py#L24-L29 dataf = BytesIO(obj.data) disf = BytesIO() pickletools.dis(dataf, disf) # class pickletools.dis(dataf, disf) # state out.write(indent(disf.getvalue(), " ")) extra = dataf.read() if len(extra) > 0: out.write(b" + extra data %s\n" % qq(extra)) else: badpretty() out.write(b"\n") out.write(b"\n")