blob: 8f709a233a0c08bfc6718cda9d9621d82393b89c [file] [log] [blame]
Guido van Rossumcc6764c1995-02-09 17:18:10 +00001"""Manage shelves of pickled objects.
2
3A "shelf" is a persistent, dictionary-like object. The difference
4with dbm databases is that the values (not the keys!) in a shelf can
5be essentially arbitrary Python objects -- anything that the "pickle"
6module can handle. This includes most class instances, recursive data
7types, and objects containing lots of shared sub-objects. The keys
8are ordinary strings.
9
10To summarize the interface (key is a string, data is an arbitrary
11object):
12
13 import shelve
Guido van Rossum256cbd71995-02-16 16:30:50 +000014 d = shelve.open(filename) # open, with (g)dbm filename -- no suffix
Guido van Rossumcc6764c1995-02-09 17:18:10 +000015
16 d[key] = data # store data at key (overwrites old data if
17 # using an existing key)
18 data = d[key] # retrieve data at key (raise KeyError if no
19 # such key)
20 del d[key] # delete data stored at key (raises KeyError
21 # if no such key)
22 flag = d.has_key(key) # true if the key exists
23 list = d.keys() # a list of all existing keys (slow!)
24
25 d.close() # close it
26
27Dependent on the implementation, closing a persistent dictionary may
28or may not be necessary to flush changes to disk.
29"""
Guido van Rossuma48061a1995-01-10 00:31:14 +000030
31import pickle
32import StringIO
33
Guido van Rossumcc6764c1995-02-09 17:18:10 +000034
Guido van Rossuma48061a1995-01-10 00:31:14 +000035class Shelf:
Guido van Rossumcc6764c1995-02-09 17:18:10 +000036 """Base class for shelf implementations.
37
38 This is initialized with a dictionary-like object.
39 See the module's __doc__ string for an overview of the interface.
40 """
Guido van Rossuma48061a1995-01-10 00:31:14 +000041
42 def __init__(self, dict):
43 self.dict = dict
44
45 def keys(self):
46 return self.dict.keys()
47
48 def __len__(self):
Guido van Rossum5f8ea101996-09-10 17:39:56 +000049 return len(self.dict)
Guido van Rossuma48061a1995-01-10 00:31:14 +000050
51 def has_key(self, key):
52 return self.dict.has_key(key)
53
54 def __getitem__(self, key):
Guido van Rossumcc6764c1995-02-09 17:18:10 +000055 f = StringIO.StringIO(self.dict[key])
56 return pickle.Unpickler(f).load()
Guido van Rossuma48061a1995-01-10 00:31:14 +000057
58 def __setitem__(self, key, value):
59 f = StringIO.StringIO()
60 p = pickle.Pickler(f)
61 p.dump(value)
62 self.dict[key] = f.getvalue()
63
64 def __delitem__(self, key):
65 del self.dict[key]
66
67 def close(self):
Guido van Rossumcebfa701995-02-27 13:15:29 +000068 if hasattr(self.dict, 'close'):
69 self.dict.close()
70 self.dict = None
Guido van Rossuma48061a1995-01-10 00:31:14 +000071
Guido van Rossumcc6764c1995-02-09 17:18:10 +000072 def __del__(self):
73 self.close()
Guido van Rossuma48061a1995-01-10 00:31:14 +000074
Roger E. Masse4fc70671997-03-25 16:06:03 +000075 def sync(self):
76 if hasattr(self.dict, 'sync'):
77 self.dict.sync()
78
Guido van Rossumcc6764c1995-02-09 17:18:10 +000079
Guido van Rossumabad1cc1995-08-11 14:19:16 +000080class BsdDbShelf(Shelf):
81 """Shelf implementation using the "BSD" db interface.
82
83 The actual database is opened using one of thethe "bsddb" modules
84 "open" routines (i.e. bsddb.hashopen, bsddb.btopen or bsddb.rnopen.)
85
86 This class is initialized with the the database object
87 returned from one of the bsddb open functions.
88
89 See the module's __doc__ string for an overview of the interface.
90 """
91
92 def __init__(self, dict):
93 Shelf.__init__(self, dict)
94
95 def set_location(self, key):
96 (key, value) = self.dict.set_location(key)
97 f = StringIO.StringIO(value)
98 return (key, pickle.Unpickler(f).load())
99
100 def next(self):
101 (key, value) = self.dict.next()
102 f = StringIO.StringIO(value)
103 return (key, pickle.Unpickler(f).load())
104
105 def previous(self):
106 (key, value) = self.dict.previous()
107 f = StringIO.StringIO(value)
108 return (key, pickle.Unpickler(f).load())
109
110 def first(self):
111 (key, value) = self.dict.first()
112 f = StringIO.StringIO(value)
113 return (key, pickle.Unpickler(f).load())
114
115 def last(self):
116 (key, value) = self.dict.last()
117 f = StringIO.StringIO(value)
118 return (key, pickle.Unpickler(f).load())
119
120
121class DbfilenameShelf(Shelf):
Guido van Rossumcc6764c1995-02-09 17:18:10 +0000122 """Shelf implementation using the "anydbm" generic dbm interface.
123
124 This is initialized with the filename for the dbm database.
125 See the module's __doc__ string for an overview of the interface.
126 """
127
Guido van Rossumabad1cc1995-08-11 14:19:16 +0000128 def __init__(self, filename, flag='c'):
Guido van Rossumcc6764c1995-02-09 17:18:10 +0000129 import anydbm
Guido van Rossumabad1cc1995-08-11 14:19:16 +0000130 Shelf.__init__(self, anydbm.open(filename, flag))
Guido van Rossumcc6764c1995-02-09 17:18:10 +0000131
132
Guido van Rossumabad1cc1995-08-11 14:19:16 +0000133def open(filename, flag='c'):
Guido van Rossumcc6764c1995-02-09 17:18:10 +0000134 """Open a persistent dictionary for reading and writing.
135
136 Argument is the filename for the dbm database.
137 See the module's __doc__ string for an overview of the interface.
138 """
139
Guido van Rossumabad1cc1995-08-11 14:19:16 +0000140 return DbfilenameShelf(filename, flag)