Author: jelmer Date: 2007-11-21 12:31:38 +0000 (Wed, 21 Nov 2007) New Revision: 26077
WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=26077 Log: Import updated TDB bindings. Added: branches/SAMBA_4_0/source/lib/tdb/python/ branches/SAMBA_4_0/source/lib/tdb/python/tests/ branches/SAMBA_4_0/source/lib/tdb/python/tests/simple.py branches/SAMBA_4_0/source/lib/tdb/tdb.i Removed: branches/SAMBA_4_0/source/lib/tdb/swig/ Modified: branches/SAMBA_4_0/ branches/SAMBA_4_0/source/lib/tdb/config.mk branches/SAMBA_4_0/source/samba4-skip branches/SAMBA_4_0/source/selftest/samba4_tests.sh Changeset: Property changes on: branches/SAMBA_4_0 ___________________________________________________________________ Name: bzr:revision-info ...skipped... Name: bzr:file-ids ...skipped... Name: bzr:revision-id:v3-trunk0 ...skipped... Modified: branches/SAMBA_4_0/source/lib/tdb/config.mk =================================================================== --- branches/SAMBA_4_0/source/lib/tdb/config.mk 2007-11-21 12:31:35 UTC (rev 26076) +++ branches/SAMBA_4_0/source/lib/tdb/config.mk 2007-11-21 12:31:38 UTC (rev 26077) @@ -60,9 +60,8 @@ ####################### # Start LIBRARY swig_tdb -[LIBRARY::swig_tdb] -LIBRARY_REALNAME = swig/_tdb.$(SHLIBEXT) -OBJ_FILES = swig/tdb_wrap.o +[PYTHON::swig_tdb] +SWIG_FILE = tdb.i PUBLIC_DEPENDENCIES = LIBTDB DYNCONFIG # End LIBRARY swig_tdb ####################### Added: branches/SAMBA_4_0/source/lib/tdb/python/tests/simple.py =================================================================== --- branches/SAMBA_4_0/source/lib/tdb/python/tests/simple.py 2007-11-21 12:31:35 UTC (rev 26076) +++ branches/SAMBA_4_0/source/lib/tdb/python/tests/simple.py 2007-11-21 12:31:38 UTC (rev 26077) @@ -0,0 +1,97 @@ +#!/usr/bin/python +# Some simple tests for the Python bindings for TDB +# Note that this tests the interface of the Python bindings +# It does not test tdb itself. +# +# Copyright (C) 2007 Jelmer Vernooij <[EMAIL PROTECTED]> +# Published under the GNU LGPL + +import tdb +from unittest import TestCase +import os + +class SimpleTdbTests(TestCase): + def setUp(self): + super(SimpleTdbTests, self).setUp() + self.tdb = tdb.Tdb(os.tmpnam(), 0, tdb.DEFAULT, os.O_CREAT|os.O_RDWR) + self.assertNotEqual(None, self.tdb) + + def tearDown(self): + del self.tdb + + def test_lockall(self): + self.tdb.lock_all() + + def test_max_dead(self): + self.tdb.max_dead = 20 + + def test_unlockall(self): + self.tdb.lock_all() + self.tdb.unlock_all() + + def test_lockall_read(self): + self.tdb.read_lock_all() + self.tdb.read_unlock_all() + + def test_reopen(self): + self.tdb.reopen() + + def test_store(self): + self.tdb.store("bar", "bla") + self.assertEquals("bla", self.tdb.fetch("bar")) + + def test_fetch(self): + self.tdb["bar"] = "foo" + self.tdb.reopen() + self.assertEquals("foo", self.tdb["bar"]) + + def test_delete(self): + self.tdb["bar"] = "foo" + del self.tdb["bar"] + self.assertRaises(KeyError, lambda: self.tdb["bar"]) + + def test_contains(self): + self.tdb["bla"] = "bloe" + self.assertTrue("bla" in self.tdb) + + def test_keyerror(self): + self.assertRaises(KeyError, lambda: self.tdb["bla"]) + + def test_hash_size(self): + self.tdb.hash_size + + def test_map_size(self): + self.tdb.map_size + + def test_name(self): + self.tdb.name + + def test_iterator(self): + self.tdb["bla"] = "1" + self.tdb["brainslug"] = "2" + self.assertEquals(["bla", "brainslug"], list(self.tdb)) + + def test_items(self): + self.tdb["bla"] = "1" + self.tdb["brainslug"] = "2" + self.assertEquals([("bla", "1"), ("brainslug", "2")], self.tdb.items()) + + def test_transaction_cancel(self): + self.tdb["bloe"] = "2" + self.tdb.transaction_start() + self.tdb["bloe"] = "1" + self.tdb.transaction_cancel() + self.assertEquals("2", self.tdb["bloe"]) + + def test_transaction_commit(self): + self.tdb["bloe"] = "2" + self.tdb.transaction_start() + self.tdb["bloe"] = "1" + self.tdb.transaction_commit() + self.assertEquals("1", self.tdb["bloe"]) + + def test_iterator(self): + self.tdb["bloe"] = "2" + self.tdb["bla"] = "hoi" + i = iter(self.tdb) + self.assertEquals(set(["bloe", "bla"]), set([i.next(), i.next()])) Copied: branches/SAMBA_4_0/source/lib/tdb/tdb.i (from rev 26076, branches/SAMBA_4_0/source/lib/tdb/swig/tdb.i) =================================================================== --- branches/SAMBA_4_0/source/lib/tdb/swig/tdb.i 2007-11-21 12:31:35 UTC (rev 26076) +++ branches/SAMBA_4_0/source/lib/tdb/tdb.i 2007-11-21 12:31:38 UTC (rev 26077) @@ -0,0 +1,252 @@ +/* + Unix SMB/CIFS implementation. + + Swig interface to tdb. + + Copyright (C) 2004-2006 Tim Potter <[EMAIL PROTECTED]> + Copyright (C) 2007 Jelmer Vernooij <[EMAIL PROTECTED]> + + ** NOTE! The following LGPL license applies to the tdb + ** library. This does NOT imply that all of Samba is released + ** under the LGPL + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 3 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, see <http://www.gnu.org/licenses/>. +*/ + +%module tdb + +%{ + +/* This symbol is used in both includes.h and Python.h which causes an + annoying compiler warning. */ + +#ifdef HAVE_FSTAT +#undef HAVE_FSTAT +#endif + +/* Include tdb headers */ +#include <tdb.h> +#include <fcntl.h> + +typedef TDB_CONTEXT tdb; +%} + +/* The tdb functions will crash if a NULL tdb context is passed */ + +%include exception.i + +%typemap(check) TDB_CONTEXT* { + if ($1 == NULL) + SWIG_exception(SWIG_ValueError, + "tdb context must be non-NULL"); +} + +/* In and out typemaps for the TDB_DATA structure. This is converted to + and from the Python string type which can contain arbitrary binary + data.. */ + +%typemap(in) TDB_DATA { + if (!PyString_Check($input)) { + PyErr_SetString(PyExc_TypeError, "string arg expected"); + return NULL; + } + $1.dsize = PyString_Size($input); + $1.dptr = (uint8_t *)PyString_AsString($input); +} + +%typemap(out) TDB_DATA { + if ($1.dptr == NULL && $1.dsize == 0) { + $result = Py_None; + } else { + $result = PyString_FromStringAndSize((const char *)$1.dptr, $1.dsize); + free($1.dptr); + } +} + +/* Treat a mode_t as an unsigned integer */ +typedef int mode_t; + +/* flags to tdb_store() */ +%constant int REPLACE = TDB_REPLACE; +%constant int INSERT = TDB_INSERT; +%constant int MODIFY = TDB_MODIFY; + +/* flags for tdb_open() */ +%constant int DEFAULT = TDB_DEFAULT; +%constant int CLEAR_IF_FIRST = TDB_CLEAR_IF_FIRST; +%constant int INTERNAL = TDB_INTERNAL; +%constant int NOLOCK = TDB_NOLOCK; +%constant int NOMMAP = TDB_NOMMAP; +%constant int CONVERT = TDB_CONVERT; +%constant int BIGENDIAN = TDB_BIGENDIAN; + +enum TDB_ERROR { + TDB_SUCCESS=0, + TDB_ERR_CORRUPT, + TDB_ERR_IO, + TDB_ERR_LOCK, + TDB_ERR_OOM, + TDB_ERR_EXISTS, + TDB_ERR_NOLOCK, + TDB_ERR_LOCK_TIMEOUT, + TDB_ERR_NOEXIST, + TDB_ERR_EINVAL, + TDB_ERR_RDONLY +}; + +%rename(Tdb) tdb; +%rename(lock_all) tdb_context::lockall; +%rename(unlock_all) tdb_context::unlockall; + +%rename(read_lock_all) tdb_context::lockall_read; +%rename(read_unlock_all) tdb_context::unlockall_read; + +%typemap(default) int tdb_flags { + $1 = TDB_DEFAULT; +} + +%typemap(default) int open_flags { + $1 = O_RDWR; +} + +%typemap(default) int hash_size { + $1 = 0; +} + +%typemap(default) mode_t mode { + $1 = 0600; +} + +%typemap(default) int flag { + $1 = TDB_REPLACE; +} + +typedef struct tdb_context { + %extend { + tdb(const char *name, int hash_size, + int tdb_flags, + int open_flags, mode_t mode) + { + tdb *ret = tdb_open(name, hash_size, tdb_flags, open_flags, mode); + + /* Throw an IOError exception from errno if tdb_open() returns + NULL */ + if (ret == NULL) { + PyErr_SetFromErrno(PyExc_IOError); + SWIG_fail; + } + +fail: + return ret; + } + enum TDB_ERROR error(); + ~tdb() { tdb_close($self); } + int close(); + int append(TDB_DATA key, TDB_DATA new_dbuf); + const char *errorstr(); + TDB_DATA fetch(TDB_DATA key); + int delete(TDB_DATA key); + int store(TDB_DATA key, TDB_DATA dbuf, int flag); + int exists(TDB_DATA key); + TDB_DATA firstkey(); + TDB_DATA nextkey(TDB_DATA key); + int lockall(); + int unlockall(); + int lockall_read(); + int unlockall_read(); + int reopen(); + int transaction_start(); + int transaction_commit(); + int transaction_cancel(); + int transaction_recover(); + int hash_size(); + size_t map_size(); + int get_flags(); + void set_max_dead(int max_dead); + const char *name(); + } + + %pythoncode { + def __str__(self): + return self.name() + + # Random access to keys, values + def __getitem__(self, key): + result = self.fetch(key) + if result is None: + raise KeyError, '%s: %s' % (key, self.errorstr()) + return result + + def __setitem__(self, key, item): + if self.store(key, item) == -1: + raise IOError, self.errorstr() + + def __delitem__(self, key): + if not self.exists(key): + raise KeyError, '%s: %s' % (key, self.errorstr()) + self.delete(key) + + def __contains__(self, key): + return self.exists(key) != 0 + + def has_key(self, key): + return self.exists(key) != 0 + + # Tdb iterator + class TdbIterator: + def __init__(self, tdb): + self.tdb = tdb + self.key = None + + def __iter__(self): + return self + + def next(self): + if self.key is None: + self.key = self.tdb.firstkey() + if self.key is None: + raise StopIteration + return self.key + else: + self.key = self.tdb.nextkey(self.key) + if self.key is None: + raise StopIteration + return self.key + + def __iter__(self): + return self.TdbIterator(self) + + # Implement other dict functions using TdbIterator + + def keys(self): + return [k for k in iter(self)] + + def values(self): + return [self[k] for k in iter(self)] + + def items(self): + return [(k, self[k]) for k in iter(self)] + + def __len__(self): + return len(self.keys()) + + def clear(self): + for k in iter(self): + del(self[k]) + + # TODO: iterkeys, itervalues, iteritems + + # TODO: any other missing methods for container types + } +} tdb; Modified: branches/SAMBA_4_0/source/samba4-skip =================================================================== --- branches/SAMBA_4_0/source/samba4-skip 2007-11-21 12:31:35 UTC (rev 26076) +++ branches/SAMBA_4_0/source/samba4-skip 2007-11-21 12:31:38 UTC (rev 26077) @@ -52,3 +52,4 @@ samba4.ldb.python # Fails to link properly samba4.credentials.python # Fails to link properly samba4.registry.python # Fails to link properly +samba4.tdb.python # Fails to link properly Modified: branches/SAMBA_4_0/source/selftest/samba4_tests.sh =================================================================== --- branches/SAMBA_4_0/source/selftest/samba4_tests.sh 2007-11-21 12:31:35 UTC (rev 26076) +++ branches/SAMBA_4_0/source/selftest/samba4_tests.sh 2007-11-21 12:31:38 UTC (rev 26077) @@ -297,4 +297,5 @@ plantest "ldb.python" none PYTHONPATH=bin/python trial lib/ldb/tests/python/api.py plantest "credentials.python" none PYTHONPATH=bin/python trial auth/credentials/tests/bindings.py plantest "registry.python" none PYTHONPATH=bin/python trial lib/registry/tests/bindings.py + plantest "tdb.python" none PYTHONPATH=bin/python trial lib/tdb/python/tests/simple.py fi