source: branches/samba-3.3.x/source/lib/tdb/tdb.i

Last change on this file was 206, checked in by Herwig Bauernfeind, 16 years ago

Import Samba 3.3 branch at 3.0.0 level (psmedley's port)

File size: 9.9 KB
Line 
1/*
2 Unix SMB/CIFS implementation.
3
4 Swig interface to tdb.
5
6 Copyright (C) 2004-2006 Tim Potter <tpot@samba.org>
7 Copyright (C) 2007 Jelmer Vernooij <jelmer@samba.org>
8
9 ** NOTE! The following LGPL license applies to the tdb
10 ** library. This does NOT imply that all of Samba is released
11 ** under the LGPL
12
13 This library is free software; you can redistribute it and/or
14 modify it under the terms of the GNU Lesser General Public
15 License as published by the Free Software Foundation; either
16 version 3 of the License, or (at your option) any later version.
17
18 This library is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 Lesser General Public License for more details.
22
23 You should have received a copy of the GNU Lesser General Public
24 License along with this library; if not, see <http://www.gnu.org/licenses/>.
25*/
26
27%define DOCSTRING
28"TDB is a simple key-value database similar to GDBM that supports multiple writers."
29%enddef
30
31%module(docstring=DOCSTRING) tdb
32
33%{
34
35/* This symbol is used in both includes.h and Python.h which causes an
36 annoying compiler warning. */
37
38#ifdef HAVE_FSTAT
39#undef HAVE_FSTAT
40#endif
41
42/* Include tdb headers */
43#include <stdint.h>
44#include <signal.h>
45#include <tdb.h>
46#include <fcntl.h>
47
48typedef TDB_CONTEXT tdb;
49%}
50
51/* The tdb functions will crash if a NULL tdb context is passed */
52
53%import exception.i
54%import stdint.i
55
56%typemap(check,noblock=1) TDB_CONTEXT* {
57 if ($1 == NULL)
58 SWIG_exception(SWIG_ValueError,
59 "tdb context must be non-NULL");
60}
61
62/* In and out typemaps for the TDB_DATA structure. This is converted to
63 and from the Python string type which can contain arbitrary binary
64 data.. */
65
66%typemap(in,noblock=1) TDB_DATA {
67 if ($input == Py_None) {
68 $1.dsize = 0;
69 $1.dptr = NULL;
70 } else if (!PyString_Check($input)) {
71 PyErr_SetString(PyExc_TypeError, "string arg expected");
72 return NULL;
73 } else {
74 $1.dsize = PyString_Size($input);
75 $1.dptr = (uint8_t *)PyString_AsString($input);
76 }
77}
78
79%typemap(out,noblock=1) TDB_DATA {
80 if ($1.dptr == NULL && $1.dsize == 0) {
81 $result = Py_None;
82 } else {
83 $result = PyString_FromStringAndSize((const char *)$1.dptr, $1.dsize);
84 free($1.dptr);
85 }
86}
87
88/* Treat a mode_t as an unsigned integer */
89typedef int mode_t;
90
91/* flags to tdb_store() */
92%constant int REPLACE = TDB_REPLACE;
93%constant int INSERT = TDB_INSERT;
94%constant int MODIFY = TDB_MODIFY;
95
96/* flags for tdb_open() */
97%constant int DEFAULT = TDB_DEFAULT;
98%constant int CLEAR_IF_FIRST = TDB_CLEAR_IF_FIRST;
99%constant int INTERNAL = TDB_INTERNAL;
100%constant int NOLOCK = TDB_NOLOCK;
101%constant int NOMMAP = TDB_NOMMAP;
102%constant int CONVERT = TDB_CONVERT;
103%constant int BIGENDIAN = TDB_BIGENDIAN;
104
105enum TDB_ERROR {
106 TDB_SUCCESS=0,
107 TDB_ERR_CORRUPT,
108 TDB_ERR_IO,
109 TDB_ERR_LOCK,
110 TDB_ERR_OOM,
111 TDB_ERR_EXISTS,
112 TDB_ERR_NOLOCK,
113 TDB_ERR_LOCK_TIMEOUT,
114 TDB_ERR_NOEXIST,
115 TDB_ERR_EINVAL,
116 TDB_ERR_RDONLY
117};
118
119%rename(lock_all) tdb_context::lockall;
120%rename(unlock_all) tdb_context::unlockall;
121
122%rename(read_lock_all) tdb_context::lockall_read;
123%rename(read_unlock_all) tdb_context::unlockall_read;
124
125%typemap(default,noblock=1) int tdb_flags {
126 $1 = TDB_DEFAULT;
127}
128
129%typemap(default,noblock=1) int flags {
130 $1 = O_RDWR;
131}
132
133%typemap(default,noblock=1) int hash_size {
134 $1 = 0;
135}
136
137%typemap(default,noblock=1) mode_t mode {
138 $1 = 0600;
139}
140
141%typemap(default,noblock=1) int flag {
142 $1 = TDB_REPLACE;
143}
144
145%rename(Tdb) tdb_context;
146%feature("docstring") tdb_context "A TDB file.";
147%typemap(out,noblock=1) tdb * {
148 /* Throw an IOError exception from errno if tdb_open() returns NULL */
149 if ($1 == NULL) {
150 PyErr_SetFromErrno(PyExc_IOError);
151 SWIG_fail;
152 }
153 $result = SWIG_NewPointerObj($1, $1_descriptor, 0);
154}
155
156typedef struct tdb_context {
157 %extend {
158 %feature("docstring") tdb "S.__init__(name,hash_size=0,tdb_flags=TDB_DEFAULT,flags=O_RDWR,mode=0600)\n"
159 "Open a TDB file.";
160 tdb(const char *name, int hash_size, int tdb_flags, int flags, mode_t mode) {
161 return tdb_open(name, hash_size, tdb_flags, flags, mode);
162 }
163 %feature("docstring") error "S.error() -> int\n"
164 "Find last error number returned by operation on this TDB.";
165 enum TDB_ERROR error();
166 ~tdb() { tdb_close($self); }
167 %feature("docstring") close "S.close() -> None\n"
168 "Close the TDB file.";
169 int close();
170 int append(TDB_DATA key, TDB_DATA new_dbuf);
171 %feature("docstring") errorstr "S.errorstr() -> errorstring\n"
172 "Obtain last error message.";
173 const char *errorstr();
174 %rename(get) fetch;
175 %feature("docstring") fetch "S.fetch(key) -> value\n"
176 "Fetch a value.";
177 TDB_DATA fetch(TDB_DATA key);
178 %feature("docstring") delete "S.delete(key) -> None\n"
179 "Delete an entry.";
180 int delete(TDB_DATA key);
181 %feature("docstring") store "S.store(key, value, flag=TDB_REPLACE) -> None\n"
182 "Store an entry.";
183 int store(TDB_DATA key, TDB_DATA dbuf, int flag);
184 %feature("docstring") exists "S.exists(key) -> bool\n"
185 "Check whether key exists in this database.";
186 int exists(TDB_DATA key);
187 %feature("docstring") firstkey "S.firstkey() -> data\n"
188 "Return the first key in this database.";
189 TDB_DATA firstkey();
190 %feature("docstring") nextkey "S.nextkey(prev) -> data\n"
191 "Return the next key in this database.";
192 TDB_DATA nextkey(TDB_DATA key);
193 %feature("docstring") lockall "S.lockall() -> bool";
194 int lockall();
195 %feature("docstring") unlockall "S.unlockall() -> bool";
196 int unlockall();
197 %feature("docstring") unlockall "S.lockall_read() -> bool";
198 int lockall_read();
199 %feature("docstring") unlockall "S.unlockall_read() -> bool";
200 int unlockall_read();
201 %feature("docstring") reopen "S.reopen() -> bool\n"
202 "Reopen this file.";
203 int reopen();
204 %feature("docstring") transaction_start "S.transaction_start() -> None\n"
205 "Start a new transaction.";
206 int transaction_start();
207 %feature("docstring") transaction_commit "S.transaction_commit() -> None\n"
208 "Commit the currently active transaction.";
209 int transaction_commit();
210 %feature("docstring") transaction_cancel "S.transaction_cancel() -> None\n"
211 "Cancel the currently active transaction.";
212 int transaction_cancel();
213 int transaction_recover();
214 %feature("docstring") hash_size "S.hash_size() -> int";
215 int hash_size();
216 %feature("docstring") map_size "S.map_size() -> int";
217 size_t map_size();
218 %feature("docstring") get_flags "S.get_flags() -> int";
219 int get_flags();
220 %feature("docstring") set_max_dead "S.set_max_dead(int) -> None";
221 void set_max_dead(int max_dead);
222 %feature("docstring") name "S.name() -> path\n" \
223 "Return filename of this TDB file.";
224 const char *name();
225 }
226
227 %pythoncode {
228 def __repr__(self):
229 return "Tdb('%s')" % self.name()
230
231 # Random access to keys, values
232 def __getitem__(self, key):
233 result = self.get(key)
234 if result is None:
235 raise KeyError, '%s: %s' % (key, self.errorstr())
236 return result
237
238 def __setitem__(self, key, item):
239 if self.store(key, item) == -1:
240 raise IOError, self.errorstr()
241
242 def __delitem__(self, key):
243 if not self.exists(key):
244 raise KeyError, '%s: %s' % (key, self.errorstr())
245 self.delete(key)
246
247 def __contains__(self, key):
248 return self.exists(key) != 0
249
250 def has_key(self, key):
251 return self.exists(key) != 0
252
253 def fetch_uint32(self, key):
254 data = self.get(key)
255 if data is None:
256 return None
257 import struct
258 return struct.unpack("<L", data)[0]
259
260 def fetch_int32(self, key):
261 data = self.get(key)
262 if data is None:
263 return None
264 import struct
265 return struct.unpack("<l", data)[0]
266
267 # Tdb iterator
268 class TdbIterator:
269 def __init__(self, tdb):
270 self.tdb = tdb
271 self.key = None
272
273 def __iter__(self):
274 return self
275
276 def next(self):
277 if self.key is None:
278 self.key = self.tdb.firstkey()
279 if self.key is None:
280 raise StopIteration
281 return self.key
282 else:
283 self.key = self.tdb.nextkey(self.key)
284 if self.key is None:
285 raise StopIteration
286 return self.key
287
288 def __iter__(self):
289 return self.TdbIterator(self)
290
291 # Implement other dict functions using TdbIterator
292
293 def keys(self):
294 return [k for k in iter(self)]
295
296 def values(self):
297 return [self[k] for k in iter(self)]
298
299 def items(self):
300 return [(k, self[k]) for k in iter(self)]
301
302 def __len__(self):
303 return len(self.keys())
304
305 def clear(self):
306 for k in iter(self):
307 del(self[k])
308
309 def iterkeys(self):
310 for k in iter(self):
311 yield k
312
313 def itervalues(self):
314 for k in iter(self):
315 yield self[k]
316
317 def iteritems(self):
318 for k in iter(self):
319 yield (k, self[k])
320
321 # TODO: any other missing methods for container types
322 }
323} tdb;
Note: See TracBrowser for help on using the repository browser.