2008-12-18 21:57:21 +03:00
/*
Unix SMB / CIFS implementation .
2009-10-21 21:18:54 +04:00
Python interface to tdb .
2008-12-18 21:57:21 +03:00
Copyright ( C ) 2004 - 2006 Tim Potter < tpot @ samba . org >
Copyright ( C ) 2007 - 2008 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
2010-12-21 20:48:49 +03:00
2008-12-18 21:57:21 +03:00
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/>.
*/
2010-10-03 01:40:19 +04:00
# include <Python.h>
2009-01-30 21:38:59 +03:00
# include "replace.h"
# include "system/filesys.h"
2008-12-18 21:57:21 +03:00
/* Include tdb headers */
# include <tdb.h>
2015-05-22 18:10:34 +03:00
# if PY_MAJOR_VERSION >= 3
# define PyInt_FromLong PyLong_FromLong
# define PyInt_AsLong PyLong_AsLong
# define Py_TPFLAGS_HAVE_ITER 0
# endif
2019-05-02 21:48:43 +03:00
/* discard signature of 'func' in favour of 'target_sig' */
# define PY_DISCARD_FUNC_SIG(target_sig, func) (target_sig)(void(*)(void))func
2008-12-18 21:57:21 +03:00
typedef struct {
PyObject_HEAD
TDB_CONTEXT * ctx ;
2008-12-18 23:42:50 +03:00
bool closed ;
2008-12-18 21:57:21 +03:00
} PyTdbObject ;
2015-05-22 18:10:34 +03:00
static PyTypeObject PyTdb ;
2008-12-18 21:57:21 +03:00
static void PyErr_SetTDBError ( TDB_CONTEXT * tdb )
{
PyErr_SetObject ( PyExc_RuntimeError ,
Py_BuildValue ( " (i,s) " , tdb_error ( tdb ) , tdb_errorstr ( tdb ) ) ) ;
}
2015-05-22 18:10:34 +03:00
static TDB_DATA PyBytes_AsTDB_DATA ( PyObject * data )
2008-12-18 21:57:21 +03:00
{
TDB_DATA ret ;
2015-05-22 18:10:34 +03:00
ret . dptr = ( unsigned char * ) PyBytes_AsString ( data ) ;
ret . dsize = PyBytes_Size ( data ) ;
2008-12-18 21:57:21 +03:00
return ret ;
}
2015-05-22 18:10:34 +03:00
static PyObject * PyBytes_FromTDB_DATA ( TDB_DATA data )
2008-12-18 21:57:21 +03:00
{
if ( data . dptr = = NULL & & data . dsize = = 0 ) {
2009-01-06 06:13:57 +03:00
Py_RETURN_NONE ;
2008-12-18 21:57:21 +03:00
} else {
2015-05-22 18:10:34 +03:00
PyObject * ret = PyBytes_FromStringAndSize ( ( const char * ) data . dptr ,
data . dsize ) ;
2008-12-18 21:57:21 +03:00
free ( data . dptr ) ;
return ret ;
}
}
# define PyErr_TDB_ERROR_IS_ERR_RAISE(ret, tdb) \
if ( ret ! = 0 ) { \
PyErr_SetTDBError ( tdb ) ; \
return NULL ; \
}
2012-07-16 13:43:15 +04:00
# define PyErr_TDB_RAISE_IF_CLOSED(self) \
if ( self - > closed ) { \
PyErr_SetObject ( PyExc_RuntimeError , \
Py_BuildValue ( " (i,s) " , TDB_ERR_IO , " Database is already closed " ) ) ; \
return NULL ; \
}
# define PyErr_TDB_RAISE_RETURN_MINUS_1_IF_CLOSED(self) \
if ( self - > closed ) { \
PyErr_SetObject ( PyExc_RuntimeError , \
Py_BuildValue ( " (i,s) " , TDB_ERR_IO , " Database is already closed " ) ) ; \
return - 1 ; \
}
2008-12-18 21:57:21 +03:00
static PyObject * py_tdb_open ( PyTypeObject * type , PyObject * args , PyObject * kwargs )
{
2010-09-19 21:42:29 +04:00
char * name = NULL ;
2008-12-18 21:57:21 +03:00
int hash_size = 0 , tdb_flags = TDB_DEFAULT , flags = O_RDWR , mode = 0600 ;
TDB_CONTEXT * ctx ;
PyTdbObject * ret ;
2014-02-03 14:29:38 +04:00
const char * _kwnames [ ] = { " name " , " hash_size " , " tdb_flags " , " flags " , " mode " , NULL } ;
char * * kwnames = discard_const_p ( char * , _kwnames ) ;
2008-12-18 21:57:21 +03:00
2014-02-03 14:29:38 +04:00
if ( ! PyArg_ParseTupleAndKeywords ( args , kwargs , " |siiii " , kwnames , & name , & hash_size , & tdb_flags , & flags , & mode ) )
2008-12-18 21:57:21 +03:00
return NULL ;
2010-09-19 21:42:29 +04:00
if ( name = = NULL ) {
tdb_flags | = TDB_INTERNAL ;
}
2008-12-18 21:57:21 +03:00
ctx = tdb_open ( name , hash_size , tdb_flags , flags , mode ) ;
if ( ctx = = NULL ) {
PyErr_SetFromErrno ( PyExc_IOError ) ;
return NULL ;
}
ret = PyObject_New ( PyTdbObject , & PyTdb ) ;
2010-10-02 17:43:50 +04:00
if ( ! ret ) {
tdb_close ( ctx ) ;
return NULL ;
}
2008-12-18 21:57:21 +03:00
ret - > ctx = ctx ;
2008-12-18 23:42:50 +03:00
ret - > closed = false ;
2008-12-18 21:57:21 +03:00
return ( PyObject * ) ret ;
}
2019-05-02 21:48:43 +03:00
static PyObject * obj_transaction_cancel ( PyTdbObject * self ,
PyObject * Py_UNUSED ( ignored ) )
2008-12-18 21:57:21 +03:00
{
2012-07-16 13:43:15 +04:00
int ret ;
PyErr_TDB_RAISE_IF_CLOSED ( self ) ;
ret = tdb_transaction_cancel ( self - > ctx ) ;
2008-12-18 21:57:21 +03:00
PyErr_TDB_ERROR_IS_ERR_RAISE ( ret , self - > ctx ) ;
2009-01-06 06:13:57 +03:00
Py_RETURN_NONE ;
2008-12-18 21:57:21 +03:00
}
2019-05-02 21:48:43 +03:00
static PyObject * obj_transaction_commit ( PyTdbObject * self ,
PyObject * Py_UNUSED ( ignored ) )
2008-12-18 21:57:21 +03:00
{
2012-07-16 13:43:15 +04:00
int ret ;
PyErr_TDB_RAISE_IF_CLOSED ( self ) ;
ret = tdb_transaction_commit ( self - > ctx ) ;
2008-12-18 21:57:21 +03:00
PyErr_TDB_ERROR_IS_ERR_RAISE ( ret , self - > ctx ) ;
2009-01-06 06:13:57 +03:00
Py_RETURN_NONE ;
2008-12-18 21:57:21 +03:00
}
2019-05-02 21:48:43 +03:00
static PyObject * obj_transaction_prepare_commit ( PyTdbObject * self ,
PyObject * Py_UNUSED ( ignored ) )
2010-09-19 13:53:32 +04:00
{
2012-07-16 13:43:15 +04:00
int ret ;
PyErr_TDB_RAISE_IF_CLOSED ( self ) ;
ret = tdb_transaction_prepare_commit ( self - > ctx ) ;
2010-09-19 13:53:32 +04:00
PyErr_TDB_ERROR_IS_ERR_RAISE ( ret , self - > ctx ) ;
Py_RETURN_NONE ;
}
2019-05-02 21:48:43 +03:00
static PyObject * obj_transaction_start ( PyTdbObject * self ,
PyObject * Py_UNUSED ( ignored ) )
2008-12-18 21:57:21 +03:00
{
2012-07-16 13:43:15 +04:00
int ret ;
PyErr_TDB_RAISE_IF_CLOSED ( self ) ;
ret = tdb_transaction_start ( self - > ctx ) ;
2008-12-18 21:57:21 +03:00
PyErr_TDB_ERROR_IS_ERR_RAISE ( ret , self - > ctx ) ;
2009-01-06 06:13:57 +03:00
Py_RETURN_NONE ;
2008-12-18 21:57:21 +03:00
}
2019-05-02 21:48:43 +03:00
static PyObject * obj_reopen ( PyTdbObject * self ,
PyObject * Py_UNUSED ( ignored ) )
2008-12-18 21:57:21 +03:00
{
2012-07-16 13:43:15 +04:00
int ret ;
PyErr_TDB_RAISE_IF_CLOSED ( self ) ;
ret = tdb_reopen ( self - > ctx ) ;
2012-12-11 19:51:01 +04:00
if ( ret ! = 0 ) {
self - > closed = true ;
PyErr_SetObject ( PyExc_RuntimeError ,
Py_BuildValue ( " (i,s) " ,
TDB_ERR_IO ,
" Failed to reopen database " ) ) ;
return NULL ;
}
2009-01-06 06:13:57 +03:00
Py_RETURN_NONE ;
2008-12-18 21:57:21 +03:00
}
2019-05-02 21:48:43 +03:00
static PyObject * obj_lockall ( PyTdbObject * self ,
PyObject * Py_UNUSED ( ignored ) )
2008-12-18 21:57:21 +03:00
{
2012-07-16 13:43:15 +04:00
int ret ;
PyErr_TDB_RAISE_IF_CLOSED ( self ) ;
ret = tdb_lockall ( self - > ctx ) ;
2008-12-18 21:57:21 +03:00
PyErr_TDB_ERROR_IS_ERR_RAISE ( ret , self - > ctx ) ;
2009-01-06 06:13:57 +03:00
Py_RETURN_NONE ;
2008-12-18 21:57:21 +03:00
}
2019-05-02 21:48:43 +03:00
static PyObject * obj_unlockall ( PyTdbObject * self ,
PyObject * Py_UNUSED ( ignored ) )
2008-12-18 21:57:21 +03:00
{
2012-07-16 13:43:15 +04:00
int ret ;
PyErr_TDB_RAISE_IF_CLOSED ( self ) ;
ret = tdb_unlockall ( self - > ctx ) ;
2008-12-18 21:57:21 +03:00
PyErr_TDB_ERROR_IS_ERR_RAISE ( ret , self - > ctx ) ;
2009-01-06 06:13:57 +03:00
Py_RETURN_NONE ;
2008-12-18 21:57:21 +03:00
}
2019-05-02 21:48:43 +03:00
static PyObject * obj_lockall_read ( PyTdbObject * self ,
PyObject * Py_UNUSED ( ignored ) )
2008-12-18 21:57:21 +03:00
{
2012-07-16 13:43:15 +04:00
int ret ;
PyErr_TDB_RAISE_IF_CLOSED ( self ) ;
ret = tdb_lockall_read ( self - > ctx ) ;
2008-12-18 21:57:21 +03:00
PyErr_TDB_ERROR_IS_ERR_RAISE ( ret , self - > ctx ) ;
2009-01-06 06:13:57 +03:00
Py_RETURN_NONE ;
2008-12-18 21:57:21 +03:00
}
2019-05-02 21:48:43 +03:00
static PyObject * obj_unlockall_read ( PyTdbObject * self ,
PyObject * Py_UNUSED ( ignored ) )
2008-12-18 21:57:21 +03:00
{
int ret = tdb_unlockall_read ( self - > ctx ) ;
PyErr_TDB_ERROR_IS_ERR_RAISE ( ret , self - > ctx ) ;
2009-01-06 06:13:57 +03:00
Py_RETURN_NONE ;
2008-12-18 21:57:21 +03:00
}
2019-05-02 21:48:43 +03:00
static PyObject * obj_close ( PyTdbObject * self , PyObject * Py_UNUSED ( ignored ) )
2008-12-18 21:57:21 +03:00
{
2008-12-18 23:42:50 +03:00
int ret ;
if ( self - > closed )
2009-01-06 06:13:57 +03:00
Py_RETURN_NONE ;
2008-12-18 23:42:50 +03:00
ret = tdb_close ( self - > ctx ) ;
self - > closed = true ;
2012-12-11 19:51:01 +04:00
if ( ret ! = 0 ) {
PyErr_SetObject ( PyExc_RuntimeError ,
Py_BuildValue ( " (i,s) " ,
TDB_ERR_IO ,
" Failed to close database " ) ) ;
return NULL ;
}
2009-01-06 06:13:57 +03:00
Py_RETURN_NONE ;
2008-12-18 21:57:21 +03:00
}
static PyObject * obj_get ( PyTdbObject * self , PyObject * args )
{
TDB_DATA key ;
PyObject * py_key ;
2012-07-16 13:43:15 +04:00
PyErr_TDB_RAISE_IF_CLOSED ( self ) ;
2008-12-18 21:57:21 +03:00
if ( ! PyArg_ParseTuple ( args , " O " , & py_key ) )
return NULL ;
2015-05-22 18:10:34 +03:00
key = PyBytes_AsTDB_DATA ( py_key ) ;
2012-07-16 13:03:40 +04:00
if ( ! key . dptr )
return NULL ;
2008-12-18 21:57:21 +03:00
2015-05-22 18:10:34 +03:00
return PyBytes_FromTDB_DATA ( tdb_fetch ( self - > ctx , key ) ) ;
2008-12-18 21:57:21 +03:00
}
static PyObject * obj_append ( PyTdbObject * self , PyObject * args )
{
TDB_DATA key , data ;
PyObject * py_key , * py_data ;
int ret ;
2012-07-16 13:43:15 +04:00
PyErr_TDB_RAISE_IF_CLOSED ( self ) ;
2008-12-18 21:57:21 +03:00
if ( ! PyArg_ParseTuple ( args , " OO " , & py_key , & py_data ) )
return NULL ;
2015-05-22 18:10:34 +03:00
key = PyBytes_AsTDB_DATA ( py_key ) ;
2012-07-16 13:03:40 +04:00
if ( ! key . dptr )
return NULL ;
2015-05-22 18:10:34 +03:00
data = PyBytes_AsTDB_DATA ( py_data ) ;
2012-07-16 13:03:40 +04:00
if ( ! data . dptr )
return NULL ;
2008-12-18 21:57:21 +03:00
ret = tdb_append ( self - > ctx , key , data ) ;
PyErr_TDB_ERROR_IS_ERR_RAISE ( ret , self - > ctx ) ;
2009-01-06 06:13:57 +03:00
Py_RETURN_NONE ;
2008-12-18 21:57:21 +03:00
}
2019-05-02 21:48:43 +03:00
static PyObject * obj_firstkey ( PyTdbObject * self , PyObject * Py_UNUSED ( ignored ) )
2008-12-18 21:57:21 +03:00
{
2012-07-16 13:43:15 +04:00
PyErr_TDB_RAISE_IF_CLOSED ( self ) ;
2015-05-22 18:10:34 +03:00
return PyBytes_FromTDB_DATA ( tdb_firstkey ( self - > ctx ) ) ;
2008-12-18 21:57:21 +03:00
}
static PyObject * obj_nextkey ( PyTdbObject * self , PyObject * args )
{
TDB_DATA key ;
PyObject * py_key ;
2012-07-16 13:43:15 +04:00
PyErr_TDB_RAISE_IF_CLOSED ( self ) ;
2008-12-18 21:57:21 +03:00
if ( ! PyArg_ParseTuple ( args , " O " , & py_key ) )
return NULL ;
2015-05-22 18:10:34 +03:00
key = PyBytes_AsTDB_DATA ( py_key ) ;
2012-07-16 13:03:40 +04:00
if ( ! key . dptr )
return NULL ;
2008-12-18 21:57:21 +03:00
2015-05-22 18:10:34 +03:00
return PyBytes_FromTDB_DATA ( tdb_nextkey ( self - > ctx , key ) ) ;
2008-12-18 21:57:21 +03:00
}
static PyObject * obj_delete ( PyTdbObject * self , PyObject * args )
{
TDB_DATA key ;
PyObject * py_key ;
int ret ;
2012-07-16 13:43:15 +04:00
PyErr_TDB_RAISE_IF_CLOSED ( self ) ;
2008-12-18 21:57:21 +03:00
if ( ! PyArg_ParseTuple ( args , " O " , & py_key ) )
return NULL ;
2015-05-22 18:10:34 +03:00
key = PyBytes_AsTDB_DATA ( py_key ) ;
2012-07-16 13:03:40 +04:00
if ( ! key . dptr )
return NULL ;
2008-12-18 21:57:21 +03:00
ret = tdb_delete ( self - > ctx , key ) ;
PyErr_TDB_ERROR_IS_ERR_RAISE ( ret , self - > ctx ) ;
2009-01-06 06:13:57 +03:00
Py_RETURN_NONE ;
2008-12-18 21:57:21 +03:00
}
2015-05-22 18:57:07 +03:00
static int obj_contains ( PyTdbObject * self , PyObject * py_key )
2008-12-18 21:57:21 +03:00
{
TDB_DATA key ;
2015-05-22 18:57:07 +03:00
int ret ;
PyErr_TDB_RAISE_RETURN_MINUS_1_IF_CLOSED ( self ) ;
key = PyBytes_AsTDB_DATA ( py_key ) ;
if ( ! key . dptr ) {
PyErr_BadArgument ( ) ;
return - 1 ;
}
ret = tdb_exists ( self - > ctx , key ) ;
if ( ret )
return 1 ;
return 0 ;
}
# if PY_MAJOR_VERSION < 3
static PyObject * obj_has_key ( PyTdbObject * self , PyObject * args )
{
2008-12-18 21:57:21 +03:00
int ret ;
PyObject * py_key ;
2012-07-16 13:43:15 +04:00
PyErr_TDB_RAISE_IF_CLOSED ( self ) ;
2008-12-18 21:57:21 +03:00
if ( ! PyArg_ParseTuple ( args , " O " , & py_key ) )
return NULL ;
2015-05-22 18:57:07 +03:00
ret = obj_contains ( self , py_key ) ;
if ( ret = = - 1 )
2012-07-16 13:03:40 +04:00
return NULL ;
2015-05-22 18:57:07 +03:00
if ( ret )
Py_RETURN_TRUE ;
Py_RETURN_FALSE ;
2008-12-18 21:57:21 +03:00
}
2015-05-22 18:57:07 +03:00
# endif
2008-12-18 21:57:21 +03:00
static PyObject * obj_store ( PyTdbObject * self , PyObject * args )
{
TDB_DATA key , value ;
int ret ;
int flag = TDB_REPLACE ;
PyObject * py_key , * py_value ;
2012-07-16 13:43:15 +04:00
PyErr_TDB_RAISE_IF_CLOSED ( self ) ;
2008-12-18 21:57:21 +03:00
if ( ! PyArg_ParseTuple ( args , " OO|i " , & py_key , & py_value , & flag ) )
return NULL ;
2015-05-22 18:10:34 +03:00
key = PyBytes_AsTDB_DATA ( py_key ) ;
2012-07-16 13:03:40 +04:00
if ( ! key . dptr )
return NULL ;
2015-05-22 18:10:34 +03:00
value = PyBytes_AsTDB_DATA ( py_value ) ;
2012-07-16 13:03:40 +04:00
if ( ! value . dptr )
return NULL ;
2008-12-18 21:57:21 +03:00
ret = tdb_store ( self - > ctx , key , value , flag ) ;
PyErr_TDB_ERROR_IS_ERR_RAISE ( ret , self - > ctx ) ;
2009-01-06 06:13:57 +03:00
Py_RETURN_NONE ;
2008-12-18 21:57:21 +03:00
}
2010-09-19 13:53:20 +04:00
static PyObject * obj_add_flags ( PyTdbObject * self , PyObject * args )
{
unsigned flags ;
2012-07-16 13:43:15 +04:00
PyErr_TDB_RAISE_IF_CLOSED ( self ) ;
2010-09-19 13:53:20 +04:00
if ( ! PyArg_ParseTuple ( args , " I " , & flags ) )
return NULL ;
tdb_add_flags ( self - > ctx , flags ) ;
Py_RETURN_NONE ;
}
static PyObject * obj_remove_flags ( PyTdbObject * self , PyObject * args )
{
unsigned flags ;
2012-07-16 13:43:15 +04:00
PyErr_TDB_RAISE_IF_CLOSED ( self ) ;
2010-09-19 13:53:20 +04:00
if ( ! PyArg_ParseTuple ( args , " I " , & flags ) )
return NULL ;
tdb_remove_flags ( self - > ctx , flags ) ;
Py_RETURN_NONE ;
}
2008-12-18 22:41:02 +03:00
typedef struct {
PyObject_HEAD
TDB_DATA current ;
PyTdbObject * iteratee ;
} PyTdbIteratorObject ;
static PyObject * tdb_iter_next ( PyTdbIteratorObject * self )
{
TDB_DATA current ;
PyObject * ret ;
if ( self - > current . dptr = = NULL & & self - > current . dsize = = 0 )
return NULL ;
current = self - > current ;
self - > current = tdb_nextkey ( self - > iteratee - > ctx , self - > current ) ;
2015-05-22 18:10:34 +03:00
ret = PyBytes_FromTDB_DATA ( current ) ;
2008-12-18 22:41:02 +03:00
return ret ;
}
static void tdb_iter_dealloc ( PyTdbIteratorObject * self )
{
Py_DECREF ( self - > iteratee ) ;
PyObject_Del ( self ) ;
}
PyTypeObject PyTdbIterator = {
. tp_name = " Iterator " ,
. tp_basicsize = sizeof ( PyTdbIteratorObject ) ,
. tp_iternext = ( iternextfunc ) tdb_iter_next ,
. tp_dealloc = ( destructor ) tdb_iter_dealloc ,
. tp_flags = Py_TPFLAGS_DEFAULT ,
. tp_iter = PyObject_SelfIter ,
} ;
2019-05-02 21:48:43 +03:00
static PyObject * tdb_object_iter ( PyTdbObject * self ,
PyObject * Py_UNUSED ( ignored ) )
2008-12-18 22:41:02 +03:00
{
PyTdbIteratorObject * ret ;
2012-07-16 13:43:15 +04:00
PyErr_TDB_RAISE_IF_CLOSED ( self ) ;
2008-12-18 22:41:02 +03:00
ret = PyObject_New ( PyTdbIteratorObject , & PyTdbIterator ) ;
2010-10-02 17:43:50 +04:00
if ( ! ret )
return NULL ;
2008-12-18 22:41:02 +03:00
ret - > current = tdb_firstkey ( self - > ctx ) ;
ret - > iteratee = self ;
Py_INCREF ( self ) ;
return ( PyObject * ) ret ;
}
2019-05-02 21:48:43 +03:00
static PyObject * obj_clear ( PyTdbObject * self , PyObject * Py_UNUSED ( ignored ) )
2008-12-18 22:41:02 +03:00
{
2012-07-16 13:43:15 +04:00
int ret ;
PyErr_TDB_RAISE_IF_CLOSED ( self ) ;
ret = tdb_wipe_all ( self - > ctx ) ;
2008-12-18 22:41:02 +03:00
PyErr_TDB_ERROR_IS_ERR_RAISE ( ret , self - > ctx ) ;
2009-01-06 06:13:57 +03:00
Py_RETURN_NONE ;
2008-12-18 22:41:02 +03:00
}
2019-05-02 21:48:43 +03:00
static PyObject * obj_repack ( PyTdbObject * self , PyObject * Py_UNUSED ( ignored ) )
2010-10-02 17:43:46 +04:00
{
2012-07-16 13:43:15 +04:00
int ret ;
PyErr_TDB_RAISE_IF_CLOSED ( self ) ;
ret = tdb_repack ( self - > ctx ) ;
2010-10-02 17:43:46 +04:00
PyErr_TDB_ERROR_IS_ERR_RAISE ( ret , self - > ctx ) ;
Py_RETURN_NONE ;
}
2019-05-02 21:48:43 +03:00
static PyObject * obj_enable_seqnum ( PyTdbObject * self ,
PyObject * Py_UNUSED ( ignored ) )
2010-09-19 20:34:33 +04:00
{
2012-07-16 13:43:15 +04:00
PyErr_TDB_RAISE_IF_CLOSED ( self ) ;
2010-09-19 20:34:33 +04:00
tdb_enable_seqnum ( self - > ctx ) ;
Py_RETURN_NONE ;
}
2019-05-02 21:48:43 +03:00
static PyObject * obj_increment_seqnum_nonblock ( PyTdbObject * self ,
PyObject * Py_UNUSED ( ignored ) )
2010-09-19 20:34:33 +04:00
{
2012-07-16 13:43:15 +04:00
PyErr_TDB_RAISE_IF_CLOSED ( self ) ;
2010-09-19 20:34:33 +04:00
tdb_increment_seqnum_nonblock ( self - > ctx ) ;
Py_RETURN_NONE ;
}
2008-12-18 21:57:21 +03:00
static PyMethodDef tdb_object_methods [ ] = {
{ " transaction_cancel " , ( PyCFunction ) obj_transaction_cancel , METH_NOARGS ,
" S.transaction_cancel() -> None \n "
" Cancel the currently active transaction. " } ,
{ " transaction_commit " , ( PyCFunction ) obj_transaction_commit , METH_NOARGS ,
" S.transaction_commit() -> None \n "
" Commit the currently active transaction. " } ,
2010-09-19 13:53:32 +04:00
{ " transaction_prepare_commit " , ( PyCFunction ) obj_transaction_prepare_commit , METH_NOARGS ,
" S.transaction_prepare_commit() -> None \n "
" Prepare to commit the currently active transaction " } ,
2008-12-18 21:57:21 +03:00
{ " transaction_start " , ( PyCFunction ) obj_transaction_start , METH_NOARGS ,
" S.transaction_start() -> None \n "
" Start a new transaction. " } ,
{ " reopen " , ( PyCFunction ) obj_reopen , METH_NOARGS , " Reopen this file. " } ,
{ " lock_all " , ( PyCFunction ) obj_lockall , METH_NOARGS , NULL } ,
{ " unlock_all " , ( PyCFunction ) obj_unlockall , METH_NOARGS , NULL } ,
{ " read_lock_all " , ( PyCFunction ) obj_lockall_read , METH_NOARGS , NULL } ,
{ " read_unlock_all " , ( PyCFunction ) obj_unlockall_read , METH_NOARGS , NULL } ,
{ " close " , ( PyCFunction ) obj_close , METH_NOARGS , NULL } ,
2009-10-21 21:18:55 +04:00
{ " get " , ( PyCFunction ) obj_get , METH_VARARGS , " S.get(key) -> value \n "
2008-12-18 21:57:21 +03:00
" Fetch a value. " } ,
{ " append " , ( PyCFunction ) obj_append , METH_VARARGS , " S.append(key, value) -> None \n "
" Append data to an existing key. " } ,
{ " firstkey " , ( PyCFunction ) obj_firstkey , METH_NOARGS , " S.firstkey() -> data \n "
" Return the first key in this database. " } ,
2015-06-18 13:35:49 +03:00
{ " nextkey " , ( PyCFunction ) obj_nextkey , METH_VARARGS , " S.nextkey(key) -> data \n "
2008-12-18 21:57:21 +03:00
" Return the next key in this database. " } ,
{ " delete " , ( PyCFunction ) obj_delete , METH_VARARGS , " S.delete(key) -> None \n "
" Delete an entry. " } ,
2015-05-22 18:57:07 +03:00
# if PY_MAJOR_VERSION < 3
2008-12-18 21:57:21 +03:00
{ " has_key " , ( PyCFunction ) obj_has_key , METH_VARARGS , " S.has_key(key) -> None \n "
" Check whether key exists in this database. " } ,
2015-05-22 18:57:07 +03:00
# endif
2008-12-18 21:57:21 +03:00
{ " store " , ( PyCFunction ) obj_store , METH_VARARGS , " S.store(key, data, flag=REPLACE) -> None "
" Store data. " } ,
2010-09-19 13:53:20 +04:00
{ " add_flags " , ( PyCFunction ) obj_add_flags , METH_VARARGS , " S.add_flags(flags) -> None " } ,
{ " remove_flags " , ( PyCFunction ) obj_remove_flags , METH_VARARGS , " S.remove_flags(flags) -> None " } ,
2015-05-22 18:57:07 +03:00
# if PY_MAJOR_VERSION >= 3
{ " keys " , ( PyCFunction ) tdb_object_iter , METH_NOARGS , " S.iterkeys() -> iterator " } ,
# else
2008-12-18 22:41:02 +03:00
{ " iterkeys " , ( PyCFunction ) tdb_object_iter , METH_NOARGS , " S.iterkeys() -> iterator " } ,
2015-05-22 18:57:07 +03:00
# endif
2008-12-18 22:41:02 +03:00
{ " clear " , ( PyCFunction ) obj_clear , METH_NOARGS , " S.clear() -> None \n "
" Wipe the entire database. " } ,
2010-10-02 17:43:46 +04:00
{ " repack " , ( PyCFunction ) obj_repack , METH_NOARGS , " S.repack() -> None \n "
" Repack the entire database. " } ,
2010-09-19 20:34:33 +04:00
{ " enable_seqnum " , ( PyCFunction ) obj_enable_seqnum , METH_NOARGS ,
" S.enable_seqnum() -> None " } ,
{ " increment_seqnum_nonblock " , ( PyCFunction ) obj_increment_seqnum_nonblock , METH_NOARGS ,
" S.increment_seqnum_nonblock() -> None " } ,
2008-12-18 21:57:21 +03:00
{ NULL }
} ;
static PyObject * obj_get_hash_size ( PyTdbObject * self , void * closure )
{
2012-07-16 13:43:15 +04:00
PyErr_TDB_RAISE_IF_CLOSED ( self ) ;
2008-12-18 21:57:21 +03:00
return PyInt_FromLong ( tdb_hash_size ( self - > ctx ) ) ;
}
static int obj_set_max_dead ( PyTdbObject * self , PyObject * max_dead , void * closure )
{
2012-07-16 13:43:15 +04:00
PyErr_TDB_RAISE_RETURN_MINUS_1_IF_CLOSED ( self ) ;
2020-03-15 00:04:52 +03:00
if ( ! PyLong_Check ( max_dead ) )
2008-12-18 21:57:21 +03:00
return - 1 ;
tdb_set_max_dead ( self - > ctx , PyInt_AsLong ( max_dead ) ) ;
return 0 ;
}
static PyObject * obj_get_map_size ( PyTdbObject * self , void * closure )
{
2012-07-16 13:43:15 +04:00
PyErr_TDB_RAISE_IF_CLOSED ( self ) ;
2008-12-18 21:57:21 +03:00
return PyInt_FromLong ( tdb_map_size ( self - > ctx ) ) ;
}
2010-09-19 13:53:29 +04:00
static PyObject * obj_get_freelist_size ( PyTdbObject * self , void * closure )
{
2012-07-16 13:43:15 +04:00
PyErr_TDB_RAISE_IF_CLOSED ( self ) ;
2010-09-19 13:53:29 +04:00
return PyInt_FromLong ( tdb_freelist_size ( self - > ctx ) ) ;
}
2008-12-18 21:57:21 +03:00
static PyObject * obj_get_flags ( PyTdbObject * self , void * closure )
{
2012-07-16 13:43:15 +04:00
PyErr_TDB_RAISE_IF_CLOSED ( self ) ;
2008-12-18 21:57:21 +03:00
return PyInt_FromLong ( tdb_get_flags ( self - > ctx ) ) ;
}
static PyObject * obj_get_filename ( PyTdbObject * self , void * closure )
{
2012-07-16 13:43:15 +04:00
PyErr_TDB_RAISE_IF_CLOSED ( self ) ;
2015-05-22 18:10:34 +03:00
return PyBytes_FromString ( tdb_name ( self - > ctx ) ) ;
2008-12-18 21:57:21 +03:00
}
2010-09-19 20:34:33 +04:00
static PyObject * obj_get_seqnum ( PyTdbObject * self , void * closure )
{
2012-07-16 13:43:15 +04:00
PyErr_TDB_RAISE_IF_CLOSED ( self ) ;
2010-09-19 20:34:33 +04:00
return PyInt_FromLong ( tdb_get_seqnum ( self - > ctx ) ) ;
}
2015-06-18 14:43:27 +03:00
static PyObject * obj_get_text ( PyTdbObject * self , void * closure )
{
PyObject * mod , * cls , * inst ;
mod = PyImport_ImportModule ( " _tdb_text " ) ;
if ( mod = = NULL )
return NULL ;
cls = PyObject_GetAttrString ( mod , " TdbTextWrapper " ) ;
if ( cls = = NULL ) {
Py_DECREF ( mod ) ;
return NULL ;
}
inst = PyObject_CallFunction ( cls , discard_const_p ( char , " O " ) , self ) ;
Py_DECREF ( mod ) ;
Py_DECREF ( cls ) ;
return inst ;
}
2010-09-19 20:34:33 +04:00
2008-12-18 21:57:21 +03:00
static PyGetSetDef tdb_object_getsetters [ ] = {
2018-12-13 13:29:09 +03:00
{
. name = discard_const_p ( char , " hash_size " ) ,
. get = ( getter ) obj_get_hash_size ,
} ,
{
. name = discard_const_p ( char , " map_size " ) ,
. get = ( getter ) obj_get_map_size ,
} ,
{
. name = discard_const_p ( char , " freelist_size " ) ,
. get = ( getter ) obj_get_freelist_size ,
} ,
{
. name = discard_const_p ( char , " flags " ) ,
. get = ( getter ) obj_get_flags ,
} ,
{
. name = discard_const_p ( char , " max_dead " ) ,
. set = ( setter ) obj_set_max_dead ,
} ,
{
. name = discard_const_p ( char , " filename " ) ,
. get = ( getter ) obj_get_filename ,
. doc = discard_const_p ( char , " The filename of this TDB file. " ) ,
} ,
{
. name = discard_const_p ( char , " seqnum " ) ,
. get = ( getter ) obj_get_seqnum ,
} ,
{
. name = discard_const_p ( char , " text " ) ,
. get = ( getter ) obj_get_text ,
} ,
{ . name = NULL }
2008-12-18 21:57:21 +03:00
} ;
static PyObject * tdb_object_repr ( PyTdbObject * self )
{
2012-07-16 13:43:15 +04:00
PyErr_TDB_RAISE_IF_CLOSED ( self ) ;
2010-09-19 21:42:29 +04:00
if ( tdb_get_flags ( self - > ctx ) & TDB_INTERNAL ) {
2019-06-07 11:45:52 +03:00
return PyUnicode_FromString ( " Tdb(<internal>) " ) ;
2010-09-19 21:42:29 +04:00
} else {
2019-06-07 12:08:55 +03:00
return PyUnicode_FromFormat ( " Tdb('%s') " , tdb_name(self->ctx)) ;
2010-09-19 21:42:29 +04:00
}
2008-12-18 21:57:21 +03:00
}
static void tdb_object_dealloc ( PyTdbObject * self )
{
2008-12-18 23:42:50 +03:00
if ( ! self - > closed )
tdb_close ( self - > ctx ) ;
2015-05-22 18:10:34 +03:00
Py_TYPE ( self ) - > tp_free ( self ) ;
2008-12-18 21:57:21 +03:00
}
static PyObject * obj_getitem ( PyTdbObject * self , PyObject * key )
{
TDB_DATA tkey , val ;
2012-07-16 13:43:15 +04:00
PyErr_TDB_RAISE_IF_CLOSED ( self ) ;
2015-05-22 18:10:34 +03:00
if ( ! PyBytes_Check ( key ) ) {
PyErr_SetString ( PyExc_TypeError , " Expected bytestring as key " ) ;
2008-12-18 21:57:21 +03:00
return NULL ;
}
2015-05-22 18:10:34 +03:00
tkey . dptr = ( unsigned char * ) PyBytes_AsString ( key ) ;
tkey . dsize = PyBytes_Size ( key ) ;
2008-12-18 21:57:21 +03:00
val = tdb_fetch ( self - > ctx , tkey ) ;
if ( val . dptr = = NULL ) {
2015-07-16 17:55:28 +03:00
/*
* if the key doesn ' t exist raise KeyError ( key ) to be
* consistent with python dict
*/
PyErr_SetObject ( PyExc_KeyError , key ) ;
2008-12-18 21:57:21 +03:00
return NULL ;
} else {
2015-05-22 18:10:34 +03:00
return PyBytes_FromTDB_DATA ( val ) ;
2008-12-18 21:57:21 +03:00
}
}
static int obj_setitem ( PyTdbObject * self , PyObject * key , PyObject * value )
{
TDB_DATA tkey , tval ;
int ret ;
2012-07-16 13:43:15 +04:00
PyErr_TDB_RAISE_RETURN_MINUS_1_IF_CLOSED ( self ) ;
2015-05-22 18:10:34 +03:00
if ( ! PyBytes_Check ( key ) ) {
PyErr_SetString ( PyExc_TypeError , " Expected bytestring as key " ) ;
2008-12-18 21:57:21 +03:00
return - 1 ;
}
2015-05-22 18:10:34 +03:00
tkey = PyBytes_AsTDB_DATA ( key ) ;
2008-12-18 21:57:21 +03:00
if ( value = = NULL ) {
ret = tdb_delete ( self - > ctx , tkey ) ;
} else {
2015-05-22 18:10:34 +03:00
if ( ! PyBytes_Check ( value ) ) {
2008-12-18 21:57:21 +03:00
PyErr_SetString ( PyExc_TypeError , " Expected string as value " ) ;
return - 1 ;
}
2015-05-22 18:10:34 +03:00
tval = PyBytes_AsTDB_DATA ( value ) ;
2008-12-18 21:57:21 +03:00
ret = tdb_store ( self - > ctx , tkey , tval , TDB_REPLACE ) ;
}
if ( ret ! = 0 ) {
PyErr_SetTDBError ( self - > ctx ) ;
return - 1 ;
}
return ret ;
}
static PyMappingMethods tdb_object_mapping = {
. mp_subscript = ( binaryfunc ) obj_getitem ,
. mp_ass_subscript = ( objobjargproc ) obj_setitem ,
} ;
2015-05-22 18:57:07 +03:00
static PySequenceMethods tdb_object_seq = {
. sq_contains = ( objobjproc ) obj_contains ,
} ;
2010-12-21 20:48:49 +03:00
static PyTypeObject PyTdb = {
2011-12-11 09:09:32 +04:00
. tp_name = " tdb.Tdb " ,
2008-12-18 21:57:21 +03:00
. tp_basicsize = sizeof ( PyTdbObject ) ,
. tp_methods = tdb_object_methods ,
. tp_getset = tdb_object_getsetters ,
. tp_new = py_tdb_open ,
. tp_doc = " A TDB file " ,
. tp_repr = ( reprfunc ) tdb_object_repr ,
. tp_dealloc = ( destructor ) tdb_object_dealloc ,
. tp_as_mapping = & tdb_object_mapping ,
2015-05-22 18:57:07 +03:00
. tp_as_sequence = & tdb_object_seq ,
2008-12-18 22:41:02 +03:00
. tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_ITER ,
2019-05-02 21:48:43 +03:00
. tp_iter = PY_DISCARD_FUNC_SIG ( getiterfunc , tdb_object_iter ) ,
2008-12-18 21:57:21 +03:00
} ;
static PyMethodDef tdb_methods [ ] = {
2019-05-02 21:48:43 +03:00
{
. ml_name = " open " ,
. ml_meth = PY_DISCARD_FUNC_SIG ( PyCFunction , py_tdb_open ) ,
. ml_flags = METH_VARARGS | METH_KEYWORDS ,
. ml_doc = " open(name, hash_size=0, tdb_flags=TDB_DEFAULT, "
" flags=O_RDWR, mode=0600) \n Open a TDB file. "
} ,
{ . ml_name = NULL }
2008-12-18 21:57:21 +03:00
} ;
2015-05-22 18:10:34 +03:00
# define MODULE_DOC "simple key-value database that supports multiple writers."
# if PY_MAJOR_VERSION >= 3
static struct PyModuleDef moduledef = {
PyModuleDef_HEAD_INIT ,
. m_name = " tdb " ,
. m_doc = MODULE_DOC ,
. m_size = - 1 ,
. m_methods = tdb_methods ,
} ;
# endif
PyObject * module_init ( void ) ;
PyObject * module_init ( void )
2008-12-18 21:57:21 +03:00
{
PyObject * m ;
if ( PyType_Ready ( & PyTdb ) < 0 )
2015-05-22 18:10:34 +03:00
return NULL ;
2008-12-18 21:57:21 +03:00
2008-12-18 22:41:02 +03:00
if ( PyType_Ready ( & PyTdbIterator ) < 0 )
2015-05-22 18:10:34 +03:00
return NULL ;
2008-12-18 22:41:02 +03:00
2015-05-22 18:10:34 +03:00
# if PY_MAJOR_VERSION >= 3
m = PyModule_Create ( & moduledef ) ;
# else
m = Py_InitModule3 ( " tdb " , tdb_methods , MODULE_DOC ) ;
# endif
2008-12-18 21:57:21 +03:00
if ( m = = NULL )
2015-05-22 18:10:34 +03:00
return NULL ;
PyModule_AddIntConstant ( m , " REPLACE " , TDB_REPLACE ) ;
PyModule_AddIntConstant ( m , " INSERT " , TDB_INSERT ) ;
PyModule_AddIntConstant ( m , " MODIFY " , TDB_MODIFY ) ;
PyModule_AddIntConstant ( m , " DEFAULT " , TDB_DEFAULT ) ;
PyModule_AddIntConstant ( m , " CLEAR_IF_FIRST " , TDB_CLEAR_IF_FIRST ) ;
PyModule_AddIntConstant ( m , " INTERNAL " , TDB_INTERNAL ) ;
PyModule_AddIntConstant ( m , " NOLOCK " , TDB_NOLOCK ) ;
PyModule_AddIntConstant ( m , " NOMMAP " , TDB_NOMMAP ) ;
PyModule_AddIntConstant ( m , " CONVERT " , TDB_CONVERT ) ;
PyModule_AddIntConstant ( m , " BIGENDIAN " , TDB_BIGENDIAN ) ;
PyModule_AddIntConstant ( m , " NOSYNC " , TDB_NOSYNC ) ;
PyModule_AddIntConstant ( m , " SEQNUM " , TDB_SEQNUM ) ;
PyModule_AddIntConstant ( m , " VOLATILE " , TDB_VOLATILE ) ;
PyModule_AddIntConstant ( m , " ALLOW_NESTING " , TDB_ALLOW_NESTING ) ;
PyModule_AddIntConstant ( m , " DISALLOW_NESTING " , TDB_DISALLOW_NESTING ) ;
PyModule_AddIntConstant ( m , " INCOMPATIBLE_HASH " , TDB_INCOMPATIBLE_HASH ) ;
PyModule_AddStringConstant ( m , " __docformat__ " , " restructuredText " ) ;
PyModule_AddStringConstant ( m , " __version__ " , PACKAGE_VERSION ) ;
2010-10-04 15:17:25 +04:00
2008-12-18 21:57:21 +03:00
Py_INCREF ( & PyTdb ) ;
PyModule_AddObject ( m , " Tdb " , ( PyObject * ) & PyTdb ) ;
2008-12-18 22:41:02 +03:00
Py_INCREF ( & PyTdbIterator ) ;
2015-05-22 18:10:34 +03:00
return m ;
}
# if PY_MAJOR_VERSION >= 3
PyMODINIT_FUNC PyInit_tdb ( void ) ;
PyMODINIT_FUNC PyInit_tdb ( void )
{
return module_init ( ) ;
}
# else
void inittdb ( void ) ;
void inittdb ( void )
{
module_init ( ) ;
2008-12-18 21:57:21 +03:00
}
2015-05-22 18:10:34 +03:00
# endif