Mercurial > p > roundup > code
comparison scripts/dump_dbm_sessions_db.py @ 6799:1188bb423f92
Script dumps dbm files without marshalled data like _ids
Allow the _ids database to be dumped. The _ids db (when using the
anydbm backend) records the number last used for each object
type. E.G. if there were 8 statuses defined, it would have the entry:
status: 8
Allow other dbm databases (like the node or journal dbs) to be dumped.
Used argparse for command line options and added support for:
dump all keys in sorted order
dump specific key(s)
pretty print output
| author | John Rouillard <rouilj@ieee.org> |
|---|---|
| date | Sun, 24 Jul 2022 01:31:45 -0400 |
| parents | 61481d7bbb07 |
| children | 9ba04f37896f |
comparison
equal
deleted
inserted
replaced
| 6798:863c63b73315 | 6799:1188bb423f92 |
|---|---|
| 7 Dump format: | 7 Dump format: |
| 8 | 8 |
| 9 key: <timestamp> data | 9 key: <timestamp> data |
| 10 | 10 |
| 11 where <timestamp> is the human readable __timestamp decoded from the | 11 where <timestamp> is the human readable __timestamp decoded from the |
| 12 data object. | 12 data object. Data object is dumped in json format. With pretty print |
| 13 | 13 |
| 14 key: | |
| 15 <timestamp> | |
| 16 { | |
| 17 key: val, | |
| 18 ... | |
| 19 } | |
| 20 | |
| 21 if data is not a python object, print will be key: data or | |
| 22 key: | |
| 23 data | |
| 24 | |
| 25 if pretty printed. | |
| 14 """ | 26 """ |
| 15 | 27 |
| 16 import dbm, marshal, sys | 28 import argparse, dbm, json, marshal, os, sys |
| 17 from datetime import datetime | 29 from datetime import datetime |
| 18 | 30 |
| 19 try: | 31 def indent(text, amount, ch=" "): |
| 20 file = sys.argv[1] | 32 """ Found at: https://stackoverflow.com/a/8348914 |
| 21 except IndexError: | 33 """ |
| 34 padding = amount * ch | |
| 35 return ''.join(padding+line for line in text.splitlines(True)) | |
| 36 | |
| 37 def print_marshal(k): | |
| 38 d = marshal.loads(db[k]) | |
| 39 try: | |
| 40 t = datetime.fromtimestamp(d['__timestamp']) | |
| 41 except (KeyError, TypeError): | |
| 42 # TypeError raised if marshalled data is not a dict (list, tuple etc) | |
| 43 t = "no_timestamp" | |
| 44 if args.pretty: | |
| 45 print("%s:\n %s\n%s"%(k, t, indent(json.dumps( | |
| 46 d, sort_keys=True, indent=4), 4))) | |
| 47 else: | |
| 48 print("%s: %s %s"%(k, t, d)) | |
| 49 | |
| 50 def print_raw(k): | |
| 51 if args.pretty: | |
| 52 print("%s:\n %s"%(k, db[k])) | |
| 53 else: | |
| 54 print("%s: %s"%(k, db[k])) | |
| 55 | |
| 56 parser = argparse.ArgumentParser( | |
| 57 description='Dump DBM files used by Roundup in storage order.') | |
| 58 parser.add_argument('-k', '--key', action="append", | |
| 59 help='dump the entry for a key, can be used multiple times.') | |
| 60 parser.add_argument('-K', '--keysonly', action='store_true', | |
| 61 help='print the database keys, sorted in byte order.') | |
| 62 parser.add_argument('-p', '--pretty', action='store_true', | |
| 63 help='pretty print the output rather than printing on one line.') | |
| 64 parser.add_argument('file', nargs='?', | |
| 65 help='file to be dumped ("sessions" if not provided)') | |
| 66 args = parser.parse_args() | |
| 67 | |
| 68 if args.file: | |
| 69 file = args.file | |
| 70 else: | |
| 22 file="sessions" | 71 file="sessions" |
| 23 | 72 |
| 24 try: | 73 try: |
| 25 db = dbm.open(file) | 74 db = dbm.open(file) |
| 26 except Exception: | 75 except Exception as e: |
| 27 print("Unable to open database: %s"%file) | 76 print("Unable to open database for %s: %s"%(file, e)) |
| 28 exit(1) | 77 try: |
| 78 os.stat(file) | |
| 79 print(" perhaps file is invalid or was created with a different version of Python?") | |
| 80 except OSError: | |
| 81 # the file does exist on disk. | |
| 82 pass | |
| 83 exit(1) | |
| 84 | |
| 85 if args.keysonly: | |
| 86 for k in sorted(db.keys()): | |
| 87 print("%s"%k) | |
| 88 exit(0) | |
| 89 | |
| 90 if args.key: | |
| 91 for k in args.key: | |
| 92 try: | |
| 93 print_marshal(k) | |
| 94 except (ValueError): | |
| 95 print_raw(k) | |
| 96 exit(0) | |
| 29 | 97 |
| 30 k = db.firstkey() | 98 k = db.firstkey() |
| 31 while k is not None: | 99 while k is not None: |
| 32 d = marshal.loads(db[k]) | 100 try: |
| 33 t = datetime.fromtimestamp(d['__timestamp']) | 101 print_marshal(k) |
| 34 print("%s: %s %s"%(k, t, d)) | 102 except (ValueError): # ValueError marshal.loads failed |
| 35 k = db.nextkey(k) | 103 print_raw(k) |
| 104 | |
| 105 k = db.nextkey(k) |
