mirror of
https://github.com/samba-team/samba.git
synced 2025-02-04 17:47:26 +03:00
329 lines
9.9 KiB
OpenEdge ABL
329 lines
9.9 KiB
OpenEdge ABL
/*
|
|
Unix SMB/CIFS implementation.
|
|
|
|
Swig interface to tdb.
|
|
|
|
Copyright (C) 2004-2006 Tim Potter <tpot@samba.org>
|
|
Copyright (C) 2007 Jelmer Vernooij <jelmer@samba.org>
|
|
|
|
** 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/>.
|
|
*/
|
|
|
|
%define DOCSTRING
|
|
"TDB is a simple key-value database similar to GDBM that supports multiple writers."
|
|
%enddef
|
|
|
|
%module(docstring=DOCSTRING) 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 <stdint.h>
|
|
#include <signal.h>
|
|
#include <tdb.h>
|
|
#include <fcntl.h>
|
|
|
|
typedef TDB_CONTEXT tdb;
|
|
%}
|
|
|
|
/* The tdb functions will crash if a NULL tdb context is passed */
|
|
|
|
%import exception.i
|
|
%import stdint.i
|
|
|
|
%typemap(check,noblock=1) 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,noblock=1) TDB_DATA {
|
|
if ($input == Py_None) {
|
|
$1.dsize = 0;
|
|
$1.dptr = NULL;
|
|
} else if (!PyString_Check($input)) {
|
|
PyErr_SetString(PyExc_TypeError, "string arg expected");
|
|
return NULL;
|
|
} else {
|
|
$1.dsize = PyString_Size($input);
|
|
$1.dptr = (uint8_t *)PyString_AsString($input);
|
|
}
|
|
}
|
|
|
|
%typemap(out,noblock=1) 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(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,noblock=1) int tdb_flags {
|
|
$1 = TDB_DEFAULT;
|
|
}
|
|
|
|
%typemap(default,noblock=1) int flags {
|
|
$1 = O_RDWR;
|
|
}
|
|
|
|
%typemap(default,noblock=1) int hash_size {
|
|
$1 = 0;
|
|
}
|
|
|
|
%typemap(default,noblock=1) mode_t mode {
|
|
$1 = 0600;
|
|
}
|
|
|
|
%typemap(default,noblock=1) int flag {
|
|
$1 = TDB_REPLACE;
|
|
}
|
|
|
|
%rename(Tdb) tdb_context;
|
|
%feature("docstring") tdb_context "A TDB file.";
|
|
%typemap(out,noblock=1) tdb * {
|
|
/* Throw an IOError exception from errno if tdb_open() returns NULL */
|
|
if ($1 == NULL) {
|
|
PyErr_SetFromErrno(PyExc_IOError);
|
|
SWIG_fail;
|
|
}
|
|
$result = SWIG_NewPointerObj($1, $1_descriptor, 0);
|
|
}
|
|
|
|
typedef struct tdb_context {
|
|
%extend {
|
|
%feature("docstring") tdb "S.__init__(name,hash_size=0,tdb_flags=TDB_DEFAULT,flags=O_RDWR,mode=0600)\n"
|
|
"Open a TDB file.";
|
|
tdb(const char *name, int hash_size, int tdb_flags, int flags, mode_t mode) {
|
|
return tdb_open(name, hash_size, tdb_flags, flags, mode);
|
|
}
|
|
%feature("docstring") error "S.error() -> int\n"
|
|
"Find last error number returned by operation on this TDB.";
|
|
enum TDB_ERROR error();
|
|
~tdb() { tdb_close($self); }
|
|
%feature("docstring") close "S.close() -> None\n"
|
|
"Close the TDB file.";
|
|
int close();
|
|
int append(TDB_DATA key, TDB_DATA new_dbuf);
|
|
%feature("docstring") errorstr "S.errorstr() -> errorstring\n"
|
|
"Obtain last error message.";
|
|
const char *errorstr();
|
|
%rename(get) fetch;
|
|
%feature("docstring") fetch "S.fetch(key) -> value\n"
|
|
"Fetch a value.";
|
|
TDB_DATA fetch(TDB_DATA key);
|
|
%feature("docstring") delete "S.delete(key) -> None\n"
|
|
"Delete an entry.";
|
|
int delete(TDB_DATA key);
|
|
%feature("docstring") store "S.store(key, value, flag=TDB_REPLACE) -> None\n"
|
|
"Store an entry.";
|
|
int store(TDB_DATA key, TDB_DATA dbuf, int flag);
|
|
%feature("docstring") exists "S.exists(key) -> bool\n"
|
|
"Check whether key exists in this database.";
|
|
int exists(TDB_DATA key);
|
|
%feature("docstring") firstkey "S.firstkey() -> data\n"
|
|
"Return the first key in this database.";
|
|
TDB_DATA firstkey();
|
|
%feature("docstring") nextkey "S.nextkey(prev) -> data\n"
|
|
"Return the next key in this database.";
|
|
TDB_DATA nextkey(TDB_DATA key);
|
|
%feature("docstring") lockall "S.lockall() -> bool";
|
|
int lockall();
|
|
%feature("docstring") unlockall "S.unlockall() -> bool";
|
|
int unlockall();
|
|
%feature("docstring") unlockall "S.lockall_read() -> bool";
|
|
int lockall_read();
|
|
%feature("docstring") unlockall "S.unlockall_read() -> bool";
|
|
int unlockall_read();
|
|
%feature("docstring") reopen "S.reopen() -> bool\n"
|
|
"Reopen this file.";
|
|
int reopen();
|
|
%feature("docstring") transaction_start "S.transaction_start() -> None\n"
|
|
"Start a new transaction.";
|
|
int transaction_start();
|
|
%feature("docstring") transaction_commit "S.transaction_commit() -> None\n"
|
|
"Commit the currently active transaction.";
|
|
int transaction_commit();
|
|
%feature("docstring") transaction_cancel "S.transaction_cancel() -> None\n"
|
|
"Cancel the currently active transaction.";
|
|
int transaction_cancel();
|
|
int transaction_recover();
|
|
%feature("docstring") hash_size "S.hash_size() -> int";
|
|
int hash_size();
|
|
%feature("docstring") map_size "S.map_size() -> int";
|
|
size_t map_size();
|
|
%feature("docstring") get_flags "S.get_flags() -> int";
|
|
int get_flags();
|
|
%feature("docstring") set_max_dead "S.set_max_dead(int) -> None";
|
|
void set_max_dead(int max_dead);
|
|
%feature("docstring") name "S.name() -> path\n" \
|
|
"Return filename of this TDB file.";
|
|
const char *name();
|
|
}
|
|
|
|
%pythoncode {
|
|
def __repr__(self):
|
|
return "Tdb('%s')" % self.name()
|
|
|
|
# Random access to keys, values
|
|
def __getitem__(self, key):
|
|
result = self.get(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
|
|
|
|
def fetch_uint32(self, key):
|
|
data = self.get(key)
|
|
if data is None:
|
|
return None
|
|
import struct
|
|
return struct.unpack("<L", data)[0]
|
|
|
|
def fetch_int32(self, key):
|
|
data = self.get(key)
|
|
if data is None:
|
|
return None
|
|
import struct
|
|
return struct.unpack("<l", data)[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])
|
|
|
|
def iterkeys(self):
|
|
for k in iter(self):
|
|
yield k
|
|
|
|
def itervalues(self):
|
|
for k in iter(self):
|
|
yield self[k]
|
|
|
|
def iteritems(self):
|
|
for k in iter(self):
|
|
yield (k, self[k])
|
|
|
|
# TODO: any other missing methods for container types
|
|
}
|
|
} tdb;
|
|
|
|
%pythoncode {
|
|
__docformat__ = 'restructuredText'
|
|
open = Tdb
|
|
}
|