blob: b05c627379a71761a6ba6d78df5a86db3650cff6 [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
Guido van Rossumcc6764c1995-02-09 17:18:10 +000075
Guido van Rossumabad1cc1995-08-11 14:19:16 +000076class BsdDbShelf(Shelf):
77 """Shelf implementation using the "BSD" db interface.
78
79 The actual database is opened using one of thethe "bsddb" modules
80 "open" routines (i.e. bsddb.hashopen, bsddb.btopen or bsddb.rnopen.)
81
82 This class is initialized with the the database object
83 returned from one of the bsddb open functions.
84
85 See the module's __doc__ string for an overview of the interface.
86 """
87
88 def __init__(self, dict):
89 Shelf.__init__(self, dict)
90
91 def set_location(self, key):
92 (key, value) = self.dict.set_location(key)
93 f = StringIO.StringIO(value)
94 return (key, pickle.Unpickler(f).load())
95
96 def next(self):
97 (key, value) = self.dict.next()
98 f = StringIO.StringIO(value)
99 return (key, pickle.Unpickler(f).load())
100
101 def previous(self):
102 (key, value) = self.dict.previous()
103 f = StringIO.StringIO(value)
104 return (key, pickle.Unpickler(f).load())
105
106 def first(self):
107 (key, value) = self.dict.first()
108 f = StringIO.StringIO(value)
109 return (key, pickle.Unpickler(f).load())
110
111 def last(self):
112 (key, value) = self.dict.last()
113 f = StringIO.StringIO(value)
114 return (key, pickle.Unpickler(f).load())
115
116
117class DbfilenameShelf(Shelf):
Guido van Rossumcc6764c1995-02-09 17:18:10 +0000118 """Shelf implementation using the "anydbm" generic dbm interface.
119
120 This is initialized with the filename for the dbm database.
121 See the module's __doc__ string for an overview of the interface.
122 """
123
Guido van Rossumabad1cc1995-08-11 14:19:16 +0000124 def __init__(self, filename, flag='c'):
Guido van Rossumcc6764c1995-02-09 17:18:10 +0000125 import anydbm
Guido van Rossumabad1cc1995-08-11 14:19:16 +0000126 Shelf.__init__(self, anydbm.open(filename, flag))
Guido van Rossumcc6764c1995-02-09 17:18:10 +0000127
128
Guido van Rossumabad1cc1995-08-11 14:19:16 +0000129def open(filename, flag='c'):
Guido van Rossumcc6764c1995-02-09 17:18:10 +0000130 """Open a persistent dictionary for reading and writing.
131
132 Argument is the filename for the dbm database.
133 See the module's __doc__ string for an overview of the interface.
134 """
135
Guido van Rossumabad1cc1995-08-11 14:19:16 +0000136 return DbfilenameShelf(filename, flag)