Merge commit 'release-4-0-0alpha1' into v4-0-test
[kai/samba.git] / source / lib / tdb / swig / Tdb.py
1 """Provide a more Pythonic and object-oriented interface to tdb."""
2
3 #
4 # Swig interface to Samba
5 #
6 # Copyright (C) Tim Potter 2006
7 #
8 # This program is free software; you can redistribute it and/or modify
9 # it under the terms of the GNU General Public License as published by
10 # the Free Software Foundation; either version 3 of the License, or
11 # (at your option) any later version.
12 #   
13 # This program is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 # GNU General Public License for more details.
17 #   
18 # You should have received a copy of the GNU General Public License
19 # along with this program; if not, see <http://www.gnu.org/licenses/>.
20 #
21
22 import os
23 from tdb import *
24
25 # Open flags
26
27 DEFAULT        = TDB_DEFAULT
28 CLEAR_IF_FIRST = TDB_CLEAR_IF_FIRST
29 INTERNAL       = TDB_INTERNAL
30 NOLOCK         = TDB_NOLOCK
31 NOMMAP         = TDB_NOMMAP
32
33 # Class representing a TDB file
34
35 class Tdb:
36
37     # Create and destroy Tdb objects
38
39     def __init__(self, name, hash_size = 0, flags = TDB_DEFAULT,
40                  open_flags = os.O_RDWR | os.O_CREAT, mode = 0600):
41         self.tdb = tdb_open(name, hash_size, flags, open_flags, mode)
42         if self.tdb is None:
43             raise IOError, tdb_errorstr(self.tdb)
44         
45     def __del__(self):
46         self.close()
47
48     def close(self):
49         if hasattr(self, 'tdb') and self.tdb is not None:
50             if tdb_close(self.tdb) == -1:
51                 raise IOError, tdb_errorstr(self.tdb)
52             self.tdb = None
53
54     # Random access to keys, values
55
56     def __getitem__(self, key):
57         result = tdb_fetch(self.tdb, key)
58         if result is None:
59             raise KeyError, '%s: %s' % (key, tdb_errorstr(self.tdb))
60         return result
61
62     def __setitem__(self, key, item):
63         if tdb_store(self.tdb, key, item) == -1:
64             raise IOError, tdb_errorstr(self.tdb)
65
66     def __delitem__(self, key):
67         if not tdb_exists(self.tdb, key):
68             raise KeyError, '%s: %s' % (key, tdb_errorstr(self.tdb))
69         tdb_delete(self.tdb, key)
70
71     def has_key(self, key):
72         return tdb_exists(self.tdb, key) != 0
73
74     # Tdb iterator
75
76     class TdbIterator:
77         def __init__(self, tdb):
78             self.tdb = tdb
79             self.key = None
80
81         def __iter__(self):
82             return self
83             
84         def next(self):
85             if self.key is None:
86                 self.key = tdb_firstkey(self.tdb)
87                 if self.key is None:
88                     raise StopIteration
89                 return self.key
90             else:
91                 self.key = tdb_nextkey(self.tdb, self.key)
92                 if self.key is None:
93                     raise StopIteration
94                 return self.key
95
96     def __iter__(self):
97         return Tdb.TdbIterator(self.tdb)
98
99     # Implement other dict functions using TdbIterator
100
101     def keys(self):
102         return [k for k in iter(self)]
103
104     def values(self):
105         return [self[k] for k in iter(self)]
106
107     def items(self):
108         return [(k, self[k]) for k in iter(self)]
109
110     def __len__(self):
111         return len(self.keys())
112
113     def clear(self):
114         for k in iter(self):
115             del(self[k])
116
117     # TODO: iterkeys, itervalues, iteritems
118
119     # TODO: any other missing methods for container types