1#!/usr/bin/env python3
2
3"""
4Synopsis: %(prog)s [-h|-g|-b|-r|-a] dbfile [ picklefile ]
5
6Convert the database file given on the command line to a pickle
7representation.  The optional flags indicate the type of the database:
8
9    -a - open using dbm (any supported format)
10    -b - open as bsddb btree file
11    -d - open as dbm file
12    -g - open as gdbm file
13    -h - open as bsddb hash file
14    -r - open as bsddb recno file
15
16The default is hash.  If a pickle file is named it is opened for write
17access (deleting any existing data).  If no pickle file is named, the pickle
18output is written to standard output.
19
20"""
21
22import getopt
23try:
24    import bsddb
25except ImportError:
26    bsddb = None
27try:
28    import dbm.ndbm as dbm
29except ImportError:
30    dbm = None
31try:
32    import dbm.gnu as gdbm
33except ImportError:
34    gdbm = None
35try:
36    import dbm.ndbm as anydbm
37except ImportError:
38    anydbm = None
39import sys
40try:
41    import pickle as pickle
42except ImportError:
43    import pickle
44
45prog = sys.argv[0]
46
47def usage():
48    sys.stderr.write(__doc__ % globals())
49
50def main(args):
51    try:
52        opts, args = getopt.getopt(args, "hbrdag",
53                                   ["hash", "btree", "recno", "dbm",
54                                    "gdbm", "anydbm"])
55    except getopt.error:
56        usage()
57        return 1
58
59    if len(args) == 0 or len(args) > 2:
60        usage()
61        return 1
62    elif len(args) == 1:
63        dbfile = args[0]
64        pfile = sys.stdout
65    else:
66        dbfile = args[0]
67        try:
68            pfile = open(args[1], 'wb')
69        except IOError:
70            sys.stderr.write("Unable to open %s\n" % args[1])
71            return 1
72
73    dbopen = None
74    for opt, arg in opts:
75        if opt in ("-h", "--hash"):
76            try:
77                dbopen = bsddb.hashopen
78            except AttributeError:
79                sys.stderr.write("bsddb module unavailable.\n")
80                return 1
81        elif opt in ("-b", "--btree"):
82            try:
83                dbopen = bsddb.btopen
84            except AttributeError:
85                sys.stderr.write("bsddb module unavailable.\n")
86                return 1
87        elif opt in ("-r", "--recno"):
88            try:
89                dbopen = bsddb.rnopen
90            except AttributeError:
91                sys.stderr.write("bsddb module unavailable.\n")
92                return 1
93        elif opt in ("-a", "--anydbm"):
94            try:
95                dbopen = anydbm.open
96            except AttributeError:
97                sys.stderr.write("dbm module unavailable.\n")
98                return 1
99        elif opt in ("-g", "--gdbm"):
100            try:
101                dbopen = gdbm.open
102            except AttributeError:
103                sys.stderr.write("dbm.gnu module unavailable.\n")
104                return 1
105        elif opt in ("-d", "--dbm"):
106            try:
107                dbopen = dbm.open
108            except AttributeError:
109                sys.stderr.write("dbm.ndbm module unavailable.\n")
110                return 1
111    if dbopen is None:
112        if bsddb is None:
113            sys.stderr.write("bsddb module unavailable - ")
114            sys.stderr.write("must specify dbtype.\n")
115            return 1
116        else:
117            dbopen = bsddb.hashopen
118
119    try:
120        db = dbopen(dbfile, 'r')
121    except bsddb.error:
122        sys.stderr.write("Unable to open %s.  " % dbfile)
123        sys.stderr.write("Check for format or version mismatch.\n")
124        return 1
125
126    for k in db.keys():
127        pickle.dump((k, db[k]), pfile, 1==1)
128
129    db.close()
130    pfile.close()
131
132    return 0
133
134if __name__ == "__main__":
135    sys.exit(main(sys.argv[1:]))
136