blob: 9b65a0911fa6bd376aca9a613af62008a78b9e5a [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
Guido van Rossum914c9381997-06-06 21:12:45 +000031# Try using cPickle and cStringIO if available.
32
33try:
34 from cPickle import Pickler, Unpickler
35except ImportError:
36 from pickle import Pickler, Unpickler
37
38try:
39 from cStringIO import StringIO
40except ImportError:
41 from StringIO import StringIO
Guido van Rossuma48061a1995-01-10 00:31:14 +000042
Guido van Rossumcc6764c1995-02-09 17:18:10 +000043
Guido van Rossuma48061a1995-01-10 00:31:14 +000044class Shelf:
Guido van Rossumcc6764c1995-02-09 17:18:10 +000045 """Base class for shelf implementations.
46
47 This is initialized with a dictionary-like object.
48 See the module's __doc__ string for an overview of the interface.
49 """
Guido van Rossuma48061a1995-01-10 00:31:14 +000050
51 def __init__(self, dict):
52 self.dict = dict
53
54 def keys(self):
55 return self.dict.keys()
56
57 def __len__(self):
Guido van Rossum5f8ea101996-09-10 17:39:56 +000058 return len(self.dict)
Guido van Rossuma48061a1995-01-10 00:31:14 +000059
60 def has_key(self, key):
61 return self.dict.has_key(key)
62
63 def __getitem__(self, key):
Guido van Rossum914c9381997-06-06 21:12:45 +000064 f = StringIO(self.dict[key])
65 return Unpickler(f).load()
Guido van Rossuma48061a1995-01-10 00:31:14 +000066
67 def __setitem__(self, key, value):
Guido van Rossum914c9381997-06-06 21:12:45 +000068 f = StringIO()
69 p = Pickler(f)
Guido van Rossuma48061a1995-01-10 00:31:14 +000070 p.dump(value)
71 self.dict[key] = f.getvalue()
72
73 def __delitem__(self, key):
74 del self.dict[key]
75
76 def close(self):
Guido van Rossum6599fb01997-12-09 14:18:33 +000077 try:
78 if self.dict:
79 self.dict.close()
80 except:
81 pass
82 self.dict = 0
Guido van Rossuma48061a1995-01-10 00:31:14 +000083
Guido van Rossumcc6764c1995-02-09 17:18:10 +000084 def __del__(self):
85 self.close()
Guido van Rossuma48061a1995-01-10 00:31:14 +000086
Roger E. Masse4fc70671997-03-25 16:06:03 +000087 def sync(self):
88 if hasattr(self.dict, 'sync'):
89 self.dict.sync()
90
Guido van Rossumcc6764c1995-02-09 17:18:10 +000091
Guido van Rossumabad1cc1995-08-11 14:19:16 +000092class BsdDbShelf(Shelf):
93 """Shelf implementation using the "BSD" db interface.
94
Guido van Rossum914c9381997-06-06 21:12:45 +000095 This adds methods first(), next(), previous(), last() and
96 set_location() that have no counterpart in [g]dbm databases.
Guido van Rossumabad1cc1995-08-11 14:19:16 +000097
Guido van Rossum914c9381997-06-06 21:12:45 +000098 The actual database must be opened using one of the "bsddb"
99 modules "open" routines (i.e. bsddb.hashopen, bsddb.btopen or
100 bsddb.rnopen) and passed to the constructor.
Guido van Rossumabad1cc1995-08-11 14:19:16 +0000101
102 See the module's __doc__ string for an overview of the interface.
103 """
104
105 def __init__(self, dict):
106 Shelf.__init__(self, dict)
107
108 def set_location(self, key):
109 (key, value) = self.dict.set_location(key)
Guido van Rossum914c9381997-06-06 21:12:45 +0000110 f = StringIO(value)
111 return (key, Unpickler(f).load())
Guido van Rossumabad1cc1995-08-11 14:19:16 +0000112
113 def next(self):
114 (key, value) = self.dict.next()
Guido van Rossum914c9381997-06-06 21:12:45 +0000115 f = StringIO(value)
116 return (key, Unpickler(f).load())
Guido van Rossumabad1cc1995-08-11 14:19:16 +0000117
118 def previous(self):
119 (key, value) = self.dict.previous()
Guido van Rossum914c9381997-06-06 21:12:45 +0000120 f = StringIO(value)
121 return (key, Unpickler(f).load())
Guido van Rossumabad1cc1995-08-11 14:19:16 +0000122
123 def first(self):
124 (key, value) = self.dict.first()
Guido van Rossum914c9381997-06-06 21:12:45 +0000125 f = StringIO(value)
126 return (key, Unpickler(f).load())
Guido van Rossumabad1cc1995-08-11 14:19:16 +0000127
128 def last(self):
129 (key, value) = self.dict.last()
Guido van Rossum914c9381997-06-06 21:12:45 +0000130 f = StringIO(value)
131 return (key, Unpickler(f).load())
Guido van Rossumabad1cc1995-08-11 14:19:16 +0000132
133
134class DbfilenameShelf(Shelf):
Guido van Rossumcc6764c1995-02-09 17:18:10 +0000135 """Shelf implementation using the "anydbm" generic dbm interface.
136
137 This is initialized with the filename for the dbm database.
138 See the module's __doc__ string for an overview of the interface.
139 """
140
Guido van Rossumabad1cc1995-08-11 14:19:16 +0000141 def __init__(self, filename, flag='c'):
Guido van Rossumcc6764c1995-02-09 17:18:10 +0000142 import anydbm
Guido van Rossumabad1cc1995-08-11 14:19:16 +0000143 Shelf.__init__(self, anydbm.open(filename, flag))
Guido van Rossumcc6764c1995-02-09 17:18:10 +0000144
145
Guido van Rossumabad1cc1995-08-11 14:19:16 +0000146def open(filename, flag='c'):
Guido van Rossumcc6764c1995-02-09 17:18:10 +0000147 """Open a persistent dictionary for reading and writing.
148
149 Argument is the filename for the dbm database.
150 See the module's __doc__ string for an overview of the interface.
151 """
152
Guido van Rossumabad1cc1995-08-11 14:19:16 +0000153 return DbfilenameShelf(filename, flag)