Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cpython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
cpython
Commits
ef9764f1
Commit
ef9764f1
authored
May 13, 2008
by
Jesus Cea
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
bsddb module updated to version 4.6.4
parent
bbb09375
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
1521 additions
and
377 deletions
+1521
-377
Misc/NEWS
Misc/NEWS
+2
-0
Modules/_bsddb.c
Modules/_bsddb.c
+1474
-368
Modules/bsddb.h
Modules/bsddb.h
+45
-9
No files found.
Misc/NEWS
View file @
ef9764f1
...
...
@@ -25,6 +25,8 @@ Extension Modules
- Support for Windows9x has been removed from the winsound module.
- bsddb module updated to version 4.6.4.
Library
-------
...
...
Modules/_bsddb.c
View file @
ef9764f1
...
...
@@ -36,7 +36,7 @@
/*
* Handwritten code to wrap version 3.x of the Berkeley DB library,
* written to replace a SWIG-generated file. It has since been updated
* to compile with BerkeleyDB versions 3.2 through 4.2.
* to compile with Berkeley
DB versions 3.2 through 4.2.
*
* This module was started by Andrew Kuchling to remove the dependency
* on SWIG in a package by Gregory P. Smith who based his work on a
...
...
@@ -48,7 +48,10 @@
* the DB 3.x API and to build a solid unit test suite. Robin has
* since gone onto other projects (wxPython).
*
* Gregory P. Smith <greg@krypto.org> is once again the maintainer.
* Gregory P. Smith <greg@krypto.org> was once again the maintainer.
*
* Since January 2008, new maintainer is Jesus Cea <jcea@argo.es>.
* Jesus Cea licenses this code to PSF under a Contributor Agreement.
*
* Use the pybsddb-users@lists.sf.net mailing list for all questions.
* Things can change faster than the header of this file is updated. This
...
...
@@ -183,6 +186,10 @@ static PyObject* DBFileExistsError; /* EEXIST */
static
PyObject
*
DBNoSuchFileError
;
/* ENOENT */
static
PyObject
*
DBPermissionsError
;
/* EPERM */
#if (DBVER >= 42)
static
PyObject
*
DBRepHandleDeadError
;
/* DB_REP_HANDLE_DEAD */
#endif
#if (DBVER < 43)
#define DB_BUFFER_SMALL ENOMEM
#endif
...
...
@@ -202,6 +209,9 @@ static PyObject* DBPermissionsError; /* EPERM */
staticforward
PyTypeObject
DB_Type
,
DBCursor_Type
,
DBEnv_Type
,
DBTxn_Type
,
DBLock_Type
;
#if (DBVER >= 43)
staticforward
PyTypeObject
DBSequence_Type
;
#endif
#ifndef Py_TYPE
/* for compatibility with Python 2.5 and earlier */
...
...
@@ -217,10 +227,77 @@ staticforward PyTypeObject DB_Type, DBCursor_Type, DBEnv_Type, DBTxn_Type, DBLoc
#define DBSequenceObject_Check(v) (Py_TYPE(v) == &DBSequence_Type)
#endif
#if (DBVER < 46)
#define _DBC_close(dbc) dbc->c_close(dbc)
#define _DBC_count(dbc,a,b) dbc->c_count(dbc,a,b)
#define _DBC_del(dbc,a) dbc->c_del(dbc,a)
#define _DBC_dup(dbc,a,b) dbc->c_dup(dbc,a,b)
#define _DBC_get(dbc,a,b,c) dbc->c_get(dbc,a,b,c)
#define _DBC_pget(dbc,a,b,c,d) dbc->c_pget(dbc,a,b,c,d)
#define _DBC_put(dbc,a,b,c) dbc->c_put(dbc,a,b,c)
#else
#define _DBC_close(dbc) dbc->close(dbc)
#define _DBC_count(dbc,a,b) dbc->count(dbc,a,b)
#define _DBC_del(dbc,a) dbc->del(dbc,a)
#define _DBC_dup(dbc,a,b) dbc->dup(dbc,a,b)
#define _DBC_get(dbc,a,b,c) dbc->get(dbc,a,b,c)
#define _DBC_pget(dbc,a,b,c,d) dbc->pget(dbc,a,b,c,d)
#define _DBC_put(dbc,a,b,c) dbc->put(dbc,a,b,c)
#endif
/* --------------------------------------------------------------------- */
/* Utility macros and functions */
#define INSERT_IN_DOUBLE_LINKED_LIST(backlink,object) \
{ \
object->sibling_next=backlink; \
object->sibling_prev_p=&(backlink); \
backlink=object; \
if (object->sibling_next) { \
object->sibling_next->sibling_prev_p=&(object->sibling_next); \
} \
}
#define EXTRACT_FROM_DOUBLE_LINKED_LIST(object) \
{ \
if (object->sibling_next) { \
object->sibling_next->sibling_prev_p=object->sibling_prev_p; \
} \
*(object->sibling_prev_p)=object->sibling_next; \
}
#define EXTRACT_FROM_DOUBLE_LINKED_LIST_MAYBE_NULL(object) \
{ \
if (object->sibling_next) { \
object->sibling_next->sibling_prev_p=object->sibling_prev_p; \
} \
if (object->sibling_prev_p) { \
*(object->sibling_prev_p)=object->sibling_next; \
} \
}
#define INSERT_IN_DOUBLE_LINKED_LIST_TXN(backlink,object) \
{ \
object->sibling_next_txn=backlink; \
object->sibling_prev_p_txn=&(backlink); \
backlink=object; \
if (object->sibling_next_txn) { \
object->sibling_next_txn->sibling_prev_p_txn= \
&(object->sibling_next_txn); \
} \
}
#define EXTRACT_FROM_DOUBLE_LINKED_LIST_TXN(object) \
{ \
if (object->sibling_next_txn) { \
object->sibling_next_txn->sibling_prev_p_txn= \
object->sibling_prev_p_txn; \
} \
*(object->sibling_prev_p_txn)=object->sibling_next_txn; \
}
#define RETURN_IF_ERR() \
if (makeDBError(err)) { \
return NULL; \
...
...
@@ -443,6 +520,66 @@ static void _db_errorCallback(const DB_ENV *db_env,
}
/*
** We need these functions because some results
** are undefined if pointer is NULL. Some other
** give None instead of "".
**
** This functions are static and will be
** -I hope- inlined.
*/
static
const
char
*
DummyString
=
"This string is a simple placeholder"
;
static
PyObject
*
Build_PyString
(
const
char
*
p
,
int
s
)
{
if
(
!
p
)
{
p
=
DummyString
;
assert
(
s
==
0
);
}
return
PyString_FromStringAndSize
(
p
,
s
);
}
static
PyObject
*
BuildValue_S
(
const
void
*
p
,
int
s
)
{
if
(
!
p
)
{
p
=
DummyString
;
assert
(
s
==
0
);
}
return
Py_BuildValue
(
"s#"
,
p
,
s
);
}
static
PyObject
*
BuildValue_SS
(
const
void
*
p1
,
int
s1
,
const
void
*
p2
,
int
s2
)
{
if
(
!
p1
)
{
p1
=
DummyString
;
assert
(
s1
==
0
);
}
if
(
!
p2
)
{
p2
=
DummyString
;
assert
(
s2
==
0
);
}
return
Py_BuildValue
(
"s#s#"
,
p1
,
s1
,
p2
,
s2
);
}
static
PyObject
*
BuildValue_IS
(
int
i
,
const
void
*
p
,
int
s
)
{
if
(
!
p
)
{
p
=
DummyString
;
assert
(
s
==
0
);
}
return
Py_BuildValue
(
"is#"
,
i
,
p
,
s
);
}
static
PyObject
*
BuildValue_LS
(
long
i
,
const
void
*
p
,
int
s
)
{
if
(
!
p
)
{
p
=
DummyString
;
assert
(
s
==
0
);
}
return
Py_BuildValue
(
"ls#"
,
i
,
p
,
s
);
}
/* make a nice exception object to raise for errors. */
static
int
makeDBError
(
int
err
)
{
...
...
@@ -505,6 +642,10 @@ static int makeDBError(int err)
case
ENOENT
:
errObj
=
DBNoSuchFileError
;
break
;
case
EPERM
:
errObj
=
DBPermissionsError
;
break
;
#if (DBVER >= 42)
case
DB_REP_HANDLE_DEAD
:
errObj
=
DBRepHandleDeadError
;
break
;
#endif
default:
errObj
=
DBError
;
break
;
}
...
...
@@ -608,16 +749,11 @@ static PyObject* _DBCursor_get(DBCursorObject* self, int extra_flags,
flags
|=
extra_flags
;
CLEAR_DBT
(
key
);
CLEAR_DBT
(
data
);
if
(
CHECK_DBFLAG
(
self
->
mydb
,
DB_THREAD
))
{
/* Tell BerkeleyDB to malloc the return value (thread safe) */
data
.
flags
=
DB_DBT_MALLOC
;
key
.
flags
=
DB_DBT_MALLOC
;
}
if
(
!
add_partial_dbt
(
&
data
,
dlen
,
doff
))
return
NULL
;
MYDB_BEGIN_ALLOW_THREADS
;
err
=
self
->
dbc
->
c
_get
(
self
->
dbc
,
&
key
,
&
data
,
flags
);
err
=
_DBC
_get
(
self
->
dbc
,
&
key
,
&
data
,
flags
);
MYDB_END_ALLOW_THREADS
;
if
((
err
==
DB_NOTFOUND
||
err
==
DB_KEYEMPTY
)
...
...
@@ -638,21 +774,15 @@ static PyObject* _DBCursor_get(DBCursorObject* self, int extra_flags,
case
DB_RECNO
:
case
DB_QUEUE
:
retval
=
Py_BuildValue
(
"is#"
,
*
((
db_recno_t
*
)
key
.
data
),
data
.
data
,
data
.
size
);
retval
=
BuildValue_IS
(
*
((
db_recno_t
*
)
key
.
data
),
data
.
data
,
data
.
size
);
break
;
case
DB_HASH
:
case
DB_BTREE
:
default:
retval
=
Py_BuildValue
(
"s#s#"
,
key
.
data
,
key
.
size
,
data
.
data
,
data
.
size
);
retval
=
BuildValue_SS
(
key
.
data
,
key
.
size
,
data
.
data
,
data
.
size
);
break
;
}
}
if
(
!
err
)
{
FREE_DBT
(
key
);
FREE_DBT
(
data
);
}
return
retval
;
}
...
...
@@ -672,7 +802,7 @@ static void _addTimeTToDict(PyObject* dict, char *name, time_t value)
{
PyObject
*
v
;
/* if the value fits in regular int, use that. */
#ifdef
HAVE
_LONG_LONG
#ifdef
PY
_LONG_LONG
if
(
sizeof
(
time_t
)
>
sizeof
(
long
))
v
=
PyLong_FromLongLong
((
PY_LONG_LONG
)
value
);
else
...
...
@@ -696,7 +826,16 @@ static void _addDb_seq_tToDict(PyObject* dict, char *name, db_seq_t value)
}
#endif
#if (DBVER >= 40)
static
void
_addDB_lsnToDict
(
PyObject
*
dict
,
char
*
name
,
DB_LSN
value
)
{
PyObject
*
v
=
Py_BuildValue
(
"(ll)"
,
value
.
file
,
value
.
offset
);
if
(
!
v
||
PyDict_SetItemString
(
dict
,
name
,
v
))
PyErr_Clear
();
Py_XDECREF
(
v
);
}
#endif
/* --------------------------------------------------------------------- */
/* Allocators and deallocators */
...
...
@@ -716,6 +855,10 @@ newDBObject(DBEnvObject* arg, int flags)
self
->
flags
=
0
;
self
->
setflags
=
0
;
self
->
myenvobj
=
NULL
;
self
->
children_cursors
=
NULL
;
#if (DBVER >=43)
self
->
children_sequences
=
NULL
;
#endif
#if (DBVER >= 33)
self
->
associateCallback
=
NULL
;
self
->
btCompareCallback
=
NULL
;
...
...
@@ -728,7 +871,14 @@ newDBObject(DBEnvObject* arg, int flags)
Py_INCREF
(
arg
);
self
->
myenvobj
=
arg
;
db_env
=
arg
->
db_env
;
INSERT_IN_DOUBLE_LINKED_LIST
(
self
->
myenvobj
->
children_dbs
,
self
);
}
else
{
self
->
sibling_prev_p
=
NULL
;
self
->
sibling_next
=
NULL
;
}
self
->
txn
=
NULL
;
self
->
sibling_prev_p_txn
=
NULL
;
self
->
sibling_next_txn
=
NULL
;
if
(
self
->
myenvobj
)
self
->
moduleFlags
=
self
->
myenvobj
->
moduleFlags
;
...
...
@@ -760,23 +910,17 @@ newDBObject(DBEnvObject* arg, int flags)
}
/* Forward declaration */
static
PyObject
*
DB_close_internal
(
DBObject
*
self
,
int
flags
);
static
void
DB_dealloc
(
DBObject
*
self
)
{
PyObject
*
dummy
;
if
(
self
->
db
!=
NULL
)
{
/* avoid closing a DB when its DBEnv has been closed out from under
* it */
if
(
!
self
->
myenvobj
||
(
self
->
myenvobj
&&
self
->
myenvobj
->
db_env
))
{
MYDB_BEGIN_ALLOW_THREADS
;
self
->
db
->
close
(
self
->
db
,
0
);
MYDB_END_ALLOW_THREADS
;
}
else
{
PyErr_Warn
(
PyExc_RuntimeWarning
,
"DB could not be closed in destructor: DBEnv already closed"
);
}
self
->
db
=
NULL
;
dummy
=
DB_close_internal
(
self
,
0
);
Py_XDECREF
(
dummy
);
}
if
(
self
->
in_weakreflist
!=
NULL
)
{
PyObject_ClearWeakRefs
((
PyObject
*
)
self
);
...
...
@@ -798,9 +942,8 @@ DB_dealloc(DBObject* self)
PyObject_Del
(
self
);
}
static
DBCursorObject
*
newDBCursorObject
(
DBC
*
dbc
,
DBObject
*
db
)
newDBCursorObject
(
DBC
*
dbc
,
DB
TxnObject
*
txn
,
DB
Object
*
db
)
{
DBCursorObject
*
self
=
PyObject_New
(
DBCursorObject
,
&
DBCursor_Type
);
if
(
self
==
NULL
)
...
...
@@ -808,40 +951,37 @@ newDBCursorObject(DBC* dbc, DBObject* db)
self
->
dbc
=
dbc
;
self
->
mydb
=
db
;
INSERT_IN_DOUBLE_LINKED_LIST
(
self
->
mydb
->
children_cursors
,
self
);
if
(
txn
&&
((
PyObject
*
)
txn
!=
Py_None
))
{
INSERT_IN_DOUBLE_LINKED_LIST_TXN
(
txn
->
children_cursors
,
self
);
self
->
txn
=
txn
;
}
else
{
self
->
txn
=
NULL
;
}
self
->
in_weakreflist
=
NULL
;
Py_INCREF
(
self
->
mydb
);
return
self
;
}
/* Forward declaration */
static
PyObject
*
DBC_close_internal
(
DBCursorObject
*
self
);
static
void
DBCursor_dealloc
(
DBCursorObject
*
self
)
{
int
err
;
PyObject
*
dummy
;
if
(
self
->
dbc
!=
NULL
)
{
dummy
=
DBC_close_internal
(
self
);
Py_XDECREF
(
dummy
);
}
if
(
self
->
in_weakreflist
!=
NULL
)
{
PyObject_ClearWeakRefs
((
PyObject
*
)
self
);
}
if
(
self
->
dbc
!=
NULL
)
{
/* If the underlying database has been closed, we don't
need to do anything. If the environment has been closed
we need to leak, as BerkeleyDB will crash trying to access
the environment. There was an exception when the
user closed the environment even though there still was
a database open. */
if
(
self
->
mydb
->
db
&&
self
->
mydb
->
myenvobj
&&
!
self
->
mydb
->
myenvobj
->
closed
)
/* test for: open db + no environment or non-closed environment */
if
(
self
->
mydb
->
db
&&
(
!
self
->
mydb
->
myenvobj
||
(
self
->
mydb
->
myenvobj
&&
!
self
->
mydb
->
myenvobj
->
closed
)))
{
MYDB_BEGIN_ALLOW_THREADS
;
err
=
self
->
dbc
->
c_close
(
self
->
dbc
);
MYDB_END_ALLOW_THREADS
;
}
self
->
dbc
=
NULL
;
}
Py_XDECREF
(
self
->
mydb
);
Py_DECREF
(
self
->
mydb
);
PyObject_Del
(
self
);
}
...
...
@@ -858,8 +998,14 @@ newDBEnvObject(int flags)
self
->
flags
=
flags
;
self
->
moduleFlags
.
getReturnsNone
=
DEFAULT_GET_RETURNS_NONE
;
self
->
moduleFlags
.
cursorSetReturnsNone
=
DEFAULT_CURSOR_SET_RETURNS_NONE
;
self
->
children_dbs
=
NULL
;
self
->
children_txns
=
NULL
;
self
->
in_weakreflist
=
NULL
;
#if (DBVER >= 40)
self
->
event_notifyCallback
=
NULL
;
#endif
MYDB_BEGIN_ALLOW_THREADS
;
err
=
db_env_create
(
&
self
->
db_env
,
flags
);
MYDB_END_ALLOW_THREADS
;
...
...
@@ -869,75 +1015,119 @@ newDBEnvObject(int flags)
}
else
{
self
->
db_env
->
set_errcall
(
self
->
db_env
,
_db_errorCallback
);
self
->
db_env
->
app_private
=
self
;
}
return
self
;
}
/* Forward declaration */
static
PyObject
*
DBEnv_close_internal
(
DBEnvObject
*
self
,
int
flags
);
static
void
DBEnv_dealloc
(
DBEnvObject
*
self
)
{
PyObject
*
dummy
;
if
(
self
->
db_env
&&
!
self
->
closed
)
{
dummy
=
DBEnv_close_internal
(
self
,
0
);
Py_XDECREF
(
dummy
);
}
#if (DBVER >= 40)
Py_XDECREF
(
self
->
event_notifyCallback
);
self
->
event_notifyCallback
=
NULL
;
#endif
if
(
self
->
in_weakreflist
!=
NULL
)
{
PyObject_ClearWeakRefs
((
PyObject
*
)
self
);
}
if
(
self
->
db_env
&&
!
self
->
closed
)
{
MYDB_BEGIN_ALLOW_THREADS
;
self
->
db_env
->
close
(
self
->
db_env
,
0
);
MYDB_END_ALLOW_THREADS
;
}
PyObject_Del
(
self
);
}
static
DBTxnObject
*
newDBTxnObject
(
DBEnvObject
*
myenv
,
DB
_TXN
*
parent
,
int
flags
)
newDBTxnObject
(
DBEnvObject
*
myenv
,
DB
TxnObject
*
parent
,
DB_TXN
*
txn
,
int
flags
)
{
int
err
;
DB_TXN
*
parent_txn
=
NULL
;
DBTxnObject
*
self
=
PyObject_New
(
DBTxnObject
,
&
DBTxn_Type
);
if
(
self
==
NULL
)
return
NULL
;
Py_INCREF
(
myenv
);
self
->
env
=
(
PyObject
*
)
myenv
;
self
->
in_weakreflist
=
NULL
;
MYDB_BEGIN_ALLOW_THREADS
;
if
(
parent
&&
((
PyObject
*
)
parent
!=
Py_None
))
{
parent_txn
=
parent
->
txn
;
}
if
(
txn
)
{
self
->
txn
=
txn
;
}
else
{
MYDB_BEGIN_ALLOW_THREADS
;
#if (DBVER >= 40)
err
=
myenv
->
db_env
->
txn_begin
(
myenv
->
db_env
,
parent
,
&
(
self
->
txn
),
flags
);
err
=
myenv
->
db_env
->
txn_begin
(
myenv
->
db_env
,
parent_txn
,
&
(
self
->
txn
),
flags
);
#else
err
=
txn_begin
(
myenv
->
db_env
,
parent
,
&
(
self
->
txn
),
flags
);
err
=
txn_begin
(
myenv
->
db_env
,
parent
->
txn
,
&
(
self_
txn
),
flags
);
#endif
MYDB_END_ALLOW_THREADS
;
if
(
makeDBError
(
err
))
{
Py_DECREF
(
self
->
env
);
PyObject_Del
(
self
);
self
=
NULL
;
MYDB_END_ALLOW_THREADS
;
if
(
makeDBError
(
err
))
{
PyObject_Del
(
self
);
return
NULL
;
}
}
if
(
parent_txn
)
{
/* Can't use 'parent' because could be 'parent==Py_None' */
self
->
parent_txn
=
parent
;
Py_INCREF
(
parent
);
self
->
env
=
NULL
;
INSERT_IN_DOUBLE_LINKED_LIST
(
parent
->
children_txns
,
self
);
}
else
{
self
->
parent_txn
=
NULL
;
Py_INCREF
(
myenv
);
self
->
env
=
myenv
;
INSERT_IN_DOUBLE_LINKED_LIST
(
myenv
->
children_txns
,
self
);
}
self
->
children_txns
=
NULL
;
self
->
children_dbs
=
NULL
;
self
->
children_cursors
=
NULL
;
self
->
children_sequences
=
NULL
;
self
->
flag_prepare
=
0
;
return
self
;
}
/* Forward declaration */
static
PyObject
*
DBTxn_abort_discard_internal
(
DBTxnObject
*
self
,
int
discard
);
static
void
DBTxn_dealloc
(
DBTxnObject
*
self
)
{
PyObject
*
dummy
;
if
(
self
->
txn
)
{
int
flag_prepare
=
self
->
flag_prepare
;
dummy
=
DBTxn_abort_discard_internal
(
self
,
0
);
Py_XDECREF
(
dummy
);
if
(
!
flag_prepare
)
{
PyErr_Warn
(
PyExc_RuntimeWarning
,
"DBTxn aborted in destructor. No prior commit() or abort()."
);
}
}
if
(
self
->
in_weakreflist
!=
NULL
)
{
PyObject_ClearWeakRefs
((
PyObject
*
)
self
);
}
if
(
self
->
txn
)
{
/* it hasn't been finalized, abort it! */
MYDB_BEGIN_ALLOW_THREADS
;
#if (DBVER >= 40)
self
->
txn
->
abort
(
self
->
txn
);
#else
txn_abort
(
self
->
txn
);
#endif
MYDB_END_ALLOW_THREADS
;
PyErr_Warn
(
PyExc_RuntimeWarning
,
"DBTxn aborted in destructor. No prior commit() or abort()."
);
if
(
self
->
env
)
{
Py_DECREF
(
self
->
env
);
}
else
{
Py_DECREF
(
self
->
parent_txn
);
}
Py_DECREF
(
self
->
env
);
PyObject_Del
(
self
);
}
...
...
@@ -991,8 +1181,11 @@ newDBSequenceObject(DBObject* mydb, int flags)
return
NULL
;
Py_INCREF
(
mydb
);
self
->
mydb
=
mydb
;
self
->
in_weakreflist
=
NULL
;
INSERT_IN_DOUBLE_LINKED_LIST
(
self
->
mydb
->
children_sequences
,
self
);
self
->
txn
=
NULL
;
self
->
in_weakreflist
=
NULL
;
MYDB_BEGIN_ALLOW_THREADS
;
err
=
db_sequence_create
(
&
self
->
sequence
,
self
->
mydb
->
db
,
flags
);
...
...
@@ -1006,10 +1199,20 @@ newDBSequenceObject(DBObject* mydb, int flags)
return
self
;
}
/* Forward declaration */
static
PyObject
*
DBSequence_close_internal
(
DBSequenceObject
*
self
,
int
flags
,
int
do_not_close
);
static
void
DBSequence_dealloc
(
DBSequenceObject
*
self
)
{
PyObject
*
dummy
;
if
(
self
->
sequence
!=
NULL
)
{
dummy
=
DBSequence_close_internal
(
self
,
0
,
0
);
Py_XDECREF
(
dummy
);
}
if
(
self
->
in_weakreflist
!=
NULL
)
{
PyObject_ClearWeakRefs
((
PyObject
*
)
self
);
}
...
...
@@ -1072,11 +1275,9 @@ _db_associateCallback(DB* db, const DBT* priKey, const DBT* priData,
MYDB_BEGIN_BLOCK_THREADS
;
if
(
type
==
DB_RECNO
||
type
==
DB_QUEUE
)
args
=
Py_BuildValue
(
"(ls#)"
,
*
((
db_recno_t
*
)
priKey
->
data
),
priData
->
data
,
priData
->
size
);
args
=
BuildValue_LS
(
*
((
db_recno_t
*
)
priKey
->
data
),
priData
->
data
,
priData
->
size
);
else
args
=
Py_BuildValue
(
"(s#s#)"
,
priKey
->
data
,
priKey
->
size
,
priData
->
data
,
priData
->
size
);
args
=
BuildValue_SS
(
priKey
->
data
,
priKey
->
size
,
priData
->
data
,
priData
->
size
);
if
(
args
!=
NULL
)
{
result
=
PyEval_CallObject
(
callback
,
args
);
}
...
...
@@ -1217,21 +1418,49 @@ DB_associate(DBObject* self, PyObject* args, PyObject* kwargs)
static
PyObject
*
DB_close
(
DBObject
*
self
,
PyObject
*
ar
gs
)
DB_close
_internal
(
DBObject
*
self
,
int
fla
gs
)
{
int
err
,
flags
=
0
;
i
f
(
!
PyArg_ParseTuple
(
args
,
"|i:close"
,
&
flags
))
return
NULL
;
PyObject
*
dummy
;
i
nt
err
;
if
(
self
->
db
!=
NULL
)
{
if
(
self
->
myenvobj
)
CHECK_ENV_NOT_CLOSED
(
self
->
myenvobj
);
/* Can be NULL if db is not in an environment */
EXTRACT_FROM_DOUBLE_LINKED_LIST_MAYBE_NULL
(
self
);
if
(
self
->
txn
)
{
EXTRACT_FROM_DOUBLE_LINKED_LIST_TXN
(
self
);
self
->
txn
=
NULL
;
}
while
(
self
->
children_cursors
)
{
dummy
=
DBC_close_internal
(
self
->
children_cursors
);
Py_XDECREF
(
dummy
);
}
#if (DBVER >= 43)
while
(
self
->
children_sequences
)
{
dummy
=
DBSequence_close_internal
(
self
->
children_sequences
,
0
,
0
);
Py_XDECREF
(
dummy
);
}
#endif
MYDB_BEGIN_ALLOW_THREADS
;
err
=
self
->
db
->
close
(
self
->
db
,
flags
);
MYDB_END_ALLOW_THREADS
;
self
->
db
=
NULL
;
RETURN_IF_ERR
();
}
RETURN_NONE
();
}
static
PyObject
*
DB_close
(
DBObject
*
self
,
PyObject
*
args
)
{
int
flags
=
0
;
if
(
!
PyArg_ParseTuple
(
args
,
"|i:close"
,
&
flags
))
return
NULL
;
return
DB_close_internal
(
self
,
flags
);
}
static
PyObject
*
_DB_consume
(
DBObject
*
self
,
PyObject
*
args
,
PyObject
*
kwargs
,
int
consume_flag
)
...
...
@@ -1262,7 +1491,7 @@ _DB_consume(DBObject* self, PyObject* args, PyObject* kwargs, int consume_flag)
CLEAR_DBT
(
key
);
CLEAR_DBT
(
data
);
if
(
CHECK_DBFLAG
(
self
,
DB_THREAD
))
{
/* Tell BerkeleyDB to malloc the return value (thread safe) */
/* Tell Berkeley
DB to malloc the return value (thread safe) */
data
.
flags
=
DB_DBT_MALLOC
;
key
.
flags
=
DB_DBT_MALLOC
;
}
...
...
@@ -1278,8 +1507,7 @@ _DB_consume(DBObject* self, PyObject* args, PyObject* kwargs, int consume_flag)
retval
=
Py_None
;
}
else
if
(
!
err
)
{
retval
=
Py_BuildValue
(
"s#s#"
,
key
.
data
,
key
.
size
,
data
.
data
,
data
.
size
);
retval
=
BuildValue_SS
(
key
.
data
,
key
.
size
,
data
.
data
,
data
.
size
);
FREE_DBT
(
key
);
FREE_DBT
(
data
);
}
...
...
@@ -1322,7 +1550,7 @@ DB_cursor(DBObject* self, PyObject* args, PyObject* kwargs)
err
=
self
->
db
->
cursor
(
self
->
db
,
txn
,
&
dbc
,
flags
);
MYDB_END_ALLOW_THREADS
;
RETURN_IF_ERR
();
return
(
PyObject
*
)
newDBCursorObject
(
dbc
,
self
);
return
(
PyObject
*
)
newDBCursorObject
(
dbc
,
(
DBTxnObject
*
)
txnobj
,
self
);
}
...
...
@@ -1404,7 +1632,7 @@ DB_get(DBObject* self, PyObject* args, PyObject* kwargs)
CLEAR_DBT
(
data
);
if
(
CHECK_DBFLAG
(
self
,
DB_THREAD
))
{
/* Tell BerkeleyDB to malloc the return value (thread safe) */
/* Tell Berkeley
DB to malloc the return value (thread safe) */
data
.
flags
=
DB_DBT_MALLOC
;
}
if
(
!
add_partial_dbt
(
&
data
,
dlen
,
doff
))
{
...
...
@@ -1429,10 +1657,9 @@ DB_get(DBObject* self, PyObject* args, PyObject* kwargs)
}
else
if
(
!
err
)
{
if
(
flags
&
DB_SET_RECNO
)
/* return both key and data */
retval
=
Py_BuildValue
(
"s#s#"
,
key
.
data
,
key
.
size
,
data
.
data
,
data
.
size
);
retval
=
BuildValue_SS
(
key
.
data
,
key
.
size
,
data
.
data
,
data
.
size
);
else
/* return just the data */
retval
=
PyString_FromStringAndSize
((
char
*
)
data
.
data
,
data
.
size
);
retval
=
Build_PyString
(
data
.
data
,
data
.
size
);
FREE_DBT
(
data
);
}
FREE_DBT
(
key
);
...
...
@@ -1472,7 +1699,7 @@ DB_pget(DBObject* self, PyObject* args, PyObject* kwargs)
CLEAR_DBT
(
data
);
if
(
CHECK_DBFLAG
(
self
,
DB_THREAD
))
{
/* Tell BerkeleyDB to malloc the return value (thread safe) */
/* Tell Berkeley
DB to malloc the return value (thread safe) */
data
.
flags
=
DB_DBT_MALLOC
;
}
if
(
!
add_partial_dbt
(
&
data
,
dlen
,
doff
))
{
...
...
@@ -1501,13 +1728,13 @@ DB_pget(DBObject* self, PyObject* args, PyObject* kwargs)
else
if
(
!
err
)
{
PyObject
*
pkeyObj
;
PyObject
*
dataObj
;
dataObj
=
PyString_FromStringAndSize
(
data
.
data
,
data
.
size
);
dataObj
=
Build_PyString
(
data
.
data
,
data
.
size
);
if
(
self
->
primaryDBType
==
DB_RECNO
||
self
->
primaryDBType
==
DB_QUEUE
)
pkeyObj
=
PyInt_FromLong
(
*
(
int
*
)
pkey
.
data
);
else
pkeyObj
=
PyString_FromStringAndSize
(
pkey
.
data
,
pkey
.
size
);
pkeyObj
=
Build_PyString
(
pkey
.
data
,
pkey
.
size
);
if
(
flags
&
DB_SET_RECNO
)
/* return key , pkey and data */
{
...
...
@@ -1516,7 +1743,7 @@ DB_pget(DBObject* self, PyObject* args, PyObject* kwargs)
if
(
type
==
DB_RECNO
||
type
==
DB_QUEUE
)
keyObj
=
PyInt_FromLong
(
*
(
int
*
)
key
.
data
);
else
keyObj
=
PyString_FromStringAndSize
(
key
.
data
,
key
.
size
);
keyObj
=
Build_PyString
(
key
.
data
,
key
.
size
);
#if (PY_VERSION_HEX >= 0x02040000)
retval
=
PyTuple_Pack
(
3
,
keyObj
,
pkeyObj
,
dataObj
);
#else
...
...
@@ -1620,7 +1847,7 @@ DB_get_both(DBObject* self, PyObject* args, PyObject* kwargs)
orig_data
=
data
.
data
;
if
(
CHECK_DBFLAG
(
self
,
DB_THREAD
))
{
/* Tell BerkeleyDB to malloc the return value (thread safe) */
/* Tell Berkeley
DB to malloc the return value (thread safe) */
/* XXX(nnorwitz): At least 4.4.20 and 4.5.20 require this flag. */
data
.
flags
=
DB_DBT_MALLOC
;
}
...
...
@@ -1637,7 +1864,7 @@ DB_get_both(DBObject* self, PyObject* args, PyObject* kwargs)
}
else
if
(
!
err
)
{
/* XXX(nnorwitz): can we do: retval = dataobj; Py_INCREF(retval); */
retval
=
PyString_FromStringAndSize
((
char
*
)
data
.
data
,
data
.
size
);
retval
=
Build_PyString
(
data
.
data
,
data
.
size
);
/* Even though the flags require DB_DBT_MALLOC, data is not always
allocated. 4.4: allocated, 4.5: *not* allocated. :-( */
...
...
@@ -1748,7 +1975,7 @@ DB_join(DBObject* self, PyObject* args)
but does not hold python references to them or prevent
them from being closed prematurely. This can cause
python to crash when things are done in the wrong order. */
return
(
PyObject
*
)
newDBCursorObject
(
dbc
,
self
);
return
(
PyObject
*
)
newDBCursorObject
(
dbc
,
NULL
,
self
);
}
...
...
@@ -1845,6 +2072,17 @@ DB_open(DBObject* self, PyObject* args, PyObject* kwargs)
return
NULL
;
}
#if (DBVER >= 41)
if
(
txn
)
{
/* Can't use 'txnobj' because could be 'txnobj==Py_None' */
INSERT_IN_DOUBLE_LINKED_LIST_TXN
(((
DBTxnObject
*
)
txnobj
)
->
children_dbs
,
self
);
self
->
txn
=
(
DBTxnObject
*
)
txnobj
;
}
else
{
self
->
txn
=
NULL
;
}
#else
self
->
txn
=
NULL
;
#endif
MYDB_BEGIN_ALLOW_THREADS
;
#if (DBVER >= 41)
err
=
self
->
db
->
open
(
self
->
db
,
txn
,
filename
,
dbname
,
type
,
flags
,
mode
);
...
...
@@ -1853,8 +2091,10 @@ DB_open(DBObject* self, PyObject* args, PyObject* kwargs)
#endif
MYDB_END_ALLOW_THREADS
;
if
(
makeDBError
(
err
))
{
self
->
db
->
close
(
self
->
db
,
0
);
self
->
db
=
NULL
;
PyObject
*
dummy
;
dummy
=
DB_close_internal
(
self
,
0
);
Py_XDECREF
(
dummy
);
return
NULL
;
}
...
...
@@ -1863,6 +2103,7 @@ DB_open(DBObject* self, PyObject* args, PyObject* kwargs)
#endif
self
->
flags
=
flags
;
RETURN_NONE
();
}
...
...
@@ -1993,7 +2234,7 @@ _default_cmp(const DBT *leftKey,
}
static
int
_db_compareCallback
(
DB
*
db
,
_db_compareCallback
(
DB
*
db
,
const
DBT
*
leftKey
,
const
DBT
*
rightKey
)
{
...
...
@@ -2015,8 +2256,7 @@ _db_compareCallback(DB* db,
}
else
{
MYDB_BEGIN_BLOCK_THREADS
;
args
=
Py_BuildValue
(
"s#s#"
,
leftKey
->
data
,
leftKey
->
size
,
rightKey
->
data
,
rightKey
->
size
);
args
=
BuildValue_SS
(
leftKey
->
data
,
leftKey
->
size
,
rightKey
->
data
,
rightKey
->
size
);
if
(
args
!=
NULL
)
{
/* XXX(twouters) I highly doubt this INCREF is correct */
Py_INCREF
(
self
);
...
...
@@ -2369,6 +2609,9 @@ DB_stat(DBObject* self, PyObject* args, PyObject* kwargs)
MAKE_HASH_ENTRY
(
version
);
MAKE_HASH_ENTRY
(
nkeys
);
MAKE_HASH_ENTRY
(
ndata
);
#if (DBVER >= 46)
MAKE_HASH_ENTRY
(
pagecnt
);
#endif
MAKE_HASH_ENTRY
(
pagesize
);
#if (DBVER < 41)
MAKE_HASH_ENTRY
(
nelem
);
...
...
@@ -2391,6 +2634,9 @@ DB_stat(DBObject* self, PyObject* args, PyObject* kwargs)
MAKE_BT_ENTRY
(
version
);
MAKE_BT_ENTRY
(
nkeys
);
MAKE_BT_ENTRY
(
ndata
);
#if (DBVER >= 46)
MAKE_BT_ENTRY
(
pagecnt
);
#endif
MAKE_BT_ENTRY
(
pagesize
);
MAKE_BT_ENTRY
(
minkey
);
MAKE_BT_ENTRY
(
re_len
);
...
...
@@ -2400,6 +2646,9 @@ DB_stat(DBObject* self, PyObject* args, PyObject* kwargs)
MAKE_BT_ENTRY
(
leaf_pg
);
MAKE_BT_ENTRY
(
dup_pg
);
MAKE_BT_ENTRY
(
over_pg
);
#if (DBVER >= 43)
MAKE_BT_ENTRY
(
empty_pg
);
#endif
MAKE_BT_ENTRY
(
free
);
MAKE_BT_ENTRY
(
int_pgfree
);
MAKE_BT_ENTRY
(
leaf_pgfree
);
...
...
@@ -2413,6 +2662,9 @@ DB_stat(DBObject* self, PyObject* args, PyObject* kwargs)
MAKE_QUEUE_ENTRY
(
nkeys
);
MAKE_QUEUE_ENTRY
(
ndata
);
MAKE_QUEUE_ENTRY
(
pagesize
);
#if (DBVER > 40)
MAKE_QUEUE_ENTRY
(
extentsize
);
#endif
MAKE_QUEUE_ENTRY
(
pages
);
MAKE_QUEUE_ENTRY
(
re_len
);
MAKE_QUEUE_ENTRY
(
re_pad
);
...
...
@@ -2527,15 +2779,14 @@ DB_verify(DBObject* self, PyObject* args, PyObject* kwargs)
if
(
outFile
)
fclose
(
outFile
);
/* DB.verify acts as a DB handle destructor (like close); this was
* documented in BerkeleyDB 4.2 but had the undocumented effect
* of not being safe in prior versions while still requiring an explicit
* DB.close call afterwards. Lets call close for the user to emulate
* the safe 4.2 behaviour. */
#if (DBVER <= 41)
self
->
db
->
close
(
self
->
db
,
0
);
#endif
self
->
db
=
NULL
;
{
/* DB.verify acts as a DB handle destructor (like close) */
PyObject
*
error
;
error
=
DB_close_internal
(
self
,
0
);
if
(
error
)
{
return
error
;
}
}
RETURN_IF_ERR
();
RETURN_NONE
();
...
...
@@ -2622,7 +2873,7 @@ redo_stat_for_length:
so we can use any of them for the type cast */
size
=
((
DB_BTREE_STAT
*
)
sp
)
->
bt_ndata
;
/* A size of 0 could mean that BerkeleyDB no longer had the stat values cached.
/* A size of 0 could mean that Berkeley
DB no longer had the stat values cached.
* redo a full stat to make sure.
* Fixes SF python bug 1493322, pybsddb bug 1184012
*/
...
...
@@ -2658,7 +2909,7 @@ PyObject* DB_subscript(DBObject* self, PyObject* keyobj)
CLEAR_DBT
(
data
);
if
(
CHECK_DBFLAG
(
self
,
DB_THREAD
))
{
/* Tell BerkeleyDB to malloc the return value (thread safe) */
/* Tell Berkeley
DB to malloc the return value (thread safe) */
data
.
flags
=
DB_DBT_MALLOC
;
}
MYDB_BEGIN_ALLOW_THREADS
;
...
...
@@ -2672,7 +2923,7 @@ PyObject* DB_subscript(DBObject* self, PyObject* keyobj)
retval
=
NULL
;
}
else
{
retval
=
PyString_FromStringAndSize
((
char
*
)
data
.
data
,
data
.
size
);
retval
=
Build_PyString
(
data
.
data
,
data
.
size
);
FREE_DBT
(
data
);
}
...
...
@@ -2802,14 +3053,9 @@ _DB_make_list(DBObject* self, DB_TXN* txn, int type)
return
NULL
;
}
if
(
CHECK_DBFLAG
(
self
,
DB_THREAD
))
{
key
.
flags
=
DB_DBT_REALLOC
;
data
.
flags
=
DB_DBT_REALLOC
;
}
while
(
1
)
{
/* use the cursor to traverse the DB, collecting items */
MYDB_BEGIN_ALLOW_THREADS
;
err
=
cursor
->
c
_get
(
cursor
,
&
key
,
&
data
,
DB_NEXT
);
err
=
_DBC
_get
(
cursor
,
&
key
,
&
data
,
DB_NEXT
);
MYDB_END_ALLOW_THREADS
;
if
(
err
)
{
...
...
@@ -2823,7 +3069,7 @@ _DB_make_list(DBObject* self, DB_TXN* txn, int type)
case
DB_BTREE
:
case
DB_HASH
:
default:
item
=
PyString_FromStringAndSize
((
char
*
)
key
.
data
,
key
.
size
);
item
=
Build_PyString
(
key
.
data
,
key
.
size
);
break
;
case
DB_RECNO
:
case
DB_QUEUE
:
...
...
@@ -2833,7 +3079,7 @@ _DB_make_list(DBObject* self, DB_TXN* txn, int type)
break
;
case
_VALUES_LIST
:
item
=
PyString_FromStringAndSize
((
char
*
)
data
.
data
,
data
.
size
);
item
=
Build_PyString
(
data
.
data
,
data
.
size
);
break
;
case
_ITEMS_LIST
:
...
...
@@ -2841,13 +3087,11 @@ _DB_make_list(DBObject* self, DB_TXN* txn, int type)
case
DB_BTREE
:
case
DB_HASH
:
default:
item
=
Py_BuildValue
(
"s#s#"
,
key
.
data
,
key
.
size
,
data
.
data
,
data
.
size
);
item
=
BuildValue_SS
(
key
.
data
,
key
.
size
,
data
.
data
,
data
.
size
);
break
;
case
DB_RECNO
:
case
DB_QUEUE
:
item
=
Py_BuildValue
(
"is#"
,
*
((
db_recno_t
*
)
key
.
data
),
data
.
data
,
data
.
size
);
item
=
BuildValue_IS
(
*
((
db_recno_t
*
)
key
.
data
),
data
.
data
,
data
.
size
);
break
;
}
break
;
...
...
@@ -2872,10 +3116,8 @@ _DB_make_list(DBObject* self, DB_TXN* txn, int type)
}
done:
FREE_DBT
(
key
);
FREE_DBT
(
data
);
MYDB_BEGIN_ALLOW_THREADS
;
cursor
->
c
_close
(
cursor
);
_DBC
_close
(
cursor
);
MYDB_END_ALLOW_THREADS
;
return
list
;
}
...
...
@@ -2927,23 +3169,35 @@ DB_values(DBObject* self, PyObject* args)
static
PyObject
*
DBC_close
(
DBCursorObject
*
self
,
PyObject
*
args
)
DBC_close
_internal
(
DBCursorObject
*
self
)
{
int
err
=
0
;
if
(
!
PyArg_ParseTuple
(
args
,
":close"
))
return
NULL
;
if
(
self
->
dbc
!=
NULL
)
{
EXTRACT_FROM_DOUBLE_LINKED_LIST
(
self
);
if
(
self
->
txn
)
{
EXTRACT_FROM_DOUBLE_LINKED_LIST_TXN
(
self
);
self
->
txn
=
NULL
;
}
MYDB_BEGIN_ALLOW_THREADS
;
err
=
self
->
dbc
->
c_close
(
self
->
dbc
);
self
->
dbc
=
NULL
;
err
=
_DBC_close
(
self
->
dbc
);
MYDB_END_ALLOW_THREADS
;
self
->
dbc
=
NULL
;
}
RETURN_IF_ERR
();
RETURN_NONE
();
}
static
PyObject
*
DBC_close
(
DBCursorObject
*
self
,
PyObject
*
args
)
{
if
(
!
PyArg_ParseTuple
(
args
,
":close"
))
return
NULL
;
return
DBC_close_internal
(
self
);
}
static
PyObject
*
DBC_count
(
DBCursorObject
*
self
,
PyObject
*
args
)
...
...
@@ -2958,7 +3212,7 @@ DBC_count(DBCursorObject* self, PyObject* args)
CHECK_CURSOR_NOT_CLOSED
(
self
);
MYDB_BEGIN_ALLOW_THREADS
;
err
=
self
->
dbc
->
c
_count
(
self
->
dbc
,
&
count
,
flags
);
err
=
_DBC
_count
(
self
->
dbc
,
&
count
,
flags
);
MYDB_END_ALLOW_THREADS
;
RETURN_IF_ERR
();
...
...
@@ -2984,7 +3238,7 @@ DBC_delete(DBCursorObject* self, PyObject* args)
CHECK_CURSOR_NOT_CLOSED
(
self
);
MYDB_BEGIN_ALLOW_THREADS
;
err
=
self
->
dbc
->
c
_del
(
self
->
dbc
,
flags
);
err
=
_DBC
_del
(
self
->
dbc
,
flags
);
MYDB_END_ALLOW_THREADS
;
RETURN_IF_ERR
();
...
...
@@ -3005,11 +3259,11 @@ DBC_dup(DBCursorObject* self, PyObject* args)
CHECK_CURSOR_NOT_CLOSED
(
self
);
MYDB_BEGIN_ALLOW_THREADS
;
err
=
self
->
dbc
->
c
_dup
(
self
->
dbc
,
&
dbc
,
flags
);
err
=
_DBC
_dup
(
self
->
dbc
,
&
dbc
,
flags
);
MYDB_END_ALLOW_THREADS
;
RETURN_IF_ERR
();
return
(
PyObject
*
)
newDBCursorObject
(
dbc
,
self
->
mydb
);
return
(
PyObject
*
)
newDBCursorObject
(
dbc
,
self
->
txn
,
self
->
mydb
);
}
static
PyObject
*
...
...
@@ -3059,19 +3313,12 @@ DBC_get(DBCursorObject* self, PyObject* args, PyObject *kwargs)
if
(
(
dataobj
&&
!
make_dbt
(
dataobj
,
&
data
))
||
(
!
add_partial_dbt
(
&
data
,
dlen
,
doff
))
)
{
FREE_DBT
(
key
);
FREE_DBT
(
key
);
/* 'make_key_dbt' could do a 'malloc' */
return
NULL
;
}
if
(
CHECK_DBFLAG
(
self
->
mydb
,
DB_THREAD
))
{
data
.
flags
=
DB_DBT_MALLOC
;
if
(
!
(
key
.
flags
&
DB_DBT_REALLOC
))
{
key
.
flags
|=
DB_DBT_MALLOC
;
}
}
MYDB_BEGIN_ALLOW_THREADS
;
err
=
self
->
dbc
->
c
_get
(
self
->
dbc
,
&
key
,
&
data
,
flags
);
err
=
_DBC
_get
(
self
->
dbc
,
&
key
,
&
data
,
flags
);
MYDB_END_ALLOW_THREADS
;
if
((
err
==
DB_NOTFOUND
||
err
==
DB_KEYEMPTY
)
...
...
@@ -3090,18 +3337,15 @@ DBC_get(DBCursorObject* self, PyObject* args, PyObject *kwargs)
case
DB_BTREE
:
case
DB_HASH
:
default:
retval
=
Py_BuildValue
(
"s#s#"
,
key
.
data
,
key
.
size
,
data
.
data
,
data
.
size
);
retval
=
BuildValue_SS
(
key
.
data
,
key
.
size
,
data
.
data
,
data
.
size
);
break
;
case
DB_RECNO
:
case
DB_QUEUE
:
retval
=
Py_BuildValue
(
"is#"
,
*
((
db_recno_t
*
)
key
.
data
),
data
.
data
,
data
.
size
);
retval
=
BuildValue_IS
(
*
((
db_recno_t
*
)
key
.
data
),
data
.
data
,
data
.
size
);
break
;
}
FREE_DBT
(
data
);
}
FREE_DBT
(
key
);
FREE_DBT
(
key
);
/* 'make_key_dbt' could do a 'malloc' */
return
retval
;
}
...
...
@@ -3145,22 +3389,15 @@ DBC_pget(DBCursorObject* self, PyObject* args, PyObject *kwargs)
return
NULL
;
if
(
(
dataobj
&&
!
make_dbt
(
dataobj
,
&
data
))
||
(
!
add_partial_dbt
(
&
data
,
dlen
,
doff
))
)
{
FREE_DBT
(
key
);
FREE_DBT
(
key
);
/* 'make_key_dbt' could do a 'malloc' */
return
NULL
;
}
if
(
CHECK_DBFLAG
(
self
->
mydb
,
DB_THREAD
))
{
data
.
flags
=
DB_DBT_MALLOC
;
if
(
!
(
key
.
flags
&
DB_DBT_REALLOC
))
{
key
.
flags
|=
DB_DBT_MALLOC
;
}
}
CLEAR_DBT
(
pkey
);
pkey
.
flags
=
DB_DBT_MALLOC
;
MYDB_BEGIN_ALLOW_THREADS
;
err
=
self
->
dbc
->
c
_pget
(
self
->
dbc
,
&
key
,
&
pkey
,
&
data
,
flags
);
err
=
_DBC
_pget
(
self
->
dbc
,
&
key
,
&
pkey
,
&
data
,
flags
);
MYDB_END_ALLOW_THREADS
;
if
((
err
==
DB_NOTFOUND
||
err
==
DB_KEYEMPTY
)
...
...
@@ -3174,13 +3411,13 @@ DBC_pget(DBCursorObject* self, PyObject* args, PyObject *kwargs)
else
{
PyObject
*
pkeyObj
;
PyObject
*
dataObj
;
dataObj
=
PyString_FromStringAndSize
(
data
.
data
,
data
.
size
);
dataObj
=
Build_PyString
(
data
.
data
,
data
.
size
);
if
(
self
->
mydb
->
primaryDBType
==
DB_RECNO
||
self
->
mydb
->
primaryDBType
==
DB_QUEUE
)
pkeyObj
=
PyInt_FromLong
(
*
(
int
*
)
pkey
.
data
);
else
pkeyObj
=
PyString_FromStringAndSize
(
pkey
.
data
,
pkey
.
size
);
pkeyObj
=
Build_PyString
(
pkey
.
data
,
pkey
.
size
);
if
(
key
.
data
&&
key
.
size
)
/* return key, pkey and data */
{
...
...
@@ -3189,14 +3426,14 @@ DBC_pget(DBCursorObject* self, PyObject* args, PyObject *kwargs)
if
(
type
==
DB_RECNO
||
type
==
DB_QUEUE
)
keyObj
=
PyInt_FromLong
(
*
(
int
*
)
key
.
data
);
else
keyObj
=
PyString_FromStringAndSize
(
key
.
data
,
key
.
size
);
keyObj
=
Build_PyString
(
key
.
data
,
key
.
size
);
#if (PY_VERSION_HEX >= 0x02040000)
retval
=
PyTuple_Pack
(
3
,
keyObj
,
pkeyObj
,
dataObj
);
#else
retval
=
Py_BuildValue
(
"OOO"
,
keyObj
,
pkeyObj
,
dataObj
);
#endif
Py_DECREF
(
keyObj
);
FREE_DBT
(
key
);
FREE_DBT
(
key
);
/* 'make_key_dbt' could do a 'malloc' */
}
else
/* return just the pkey and data */
{
...
...
@@ -3209,11 +3446,10 @@ DBC_pget(DBCursorObject* self, PyObject* args, PyObject *kwargs)
Py_DECREF
(
dataObj
);
Py_DECREF
(
pkeyObj
);
FREE_DBT
(
pkey
);
FREE_DBT
(
data
);
}
/* the only time REALLOC should be set is if we used an integer
* key that make_key_dbt malloc'd for us. always free these. */
if
(
key
.
flags
&
DB_DBT_REALLOC
)
{
if
(
key
.
flags
&
DB_DBT_REALLOC
)
{
/* 'make_key_dbt' could do a 'malloc' */
FREE_DBT
(
key
);
}
return
retval
;
...
...
@@ -3236,20 +3472,13 @@ DBC_get_recno(DBCursorObject* self, PyObject* args)
CLEAR_DBT
(
key
);
CLEAR_DBT
(
data
);
if
(
CHECK_DBFLAG
(
self
->
mydb
,
DB_THREAD
))
{
/* Tell BerkeleyDB to malloc the return value (thread safe) */
data
.
flags
=
DB_DBT_MALLOC
;
key
.
flags
=
DB_DBT_MALLOC
;
}
MYDB_BEGIN_ALLOW_THREADS
;
err
=
self
->
dbc
->
c
_get
(
self
->
dbc
,
&
key
,
&
data
,
DB_GET_RECNO
);
err
=
_DBC
_get
(
self
->
dbc
,
&
key
,
&
data
,
DB_GET_RECNO
);
MYDB_END_ALLOW_THREADS
;
RETURN_IF_ERR
();
recno
=
*
((
db_recno_t
*
)
data
.
data
);
FREE_DBT
(
key
);
FREE_DBT
(
data
);
return
PyInt_FromLong
(
recno
);
}
...
...
@@ -3297,14 +3526,14 @@ DBC_put(DBCursorObject* self, PyObject* args, PyObject* kwargs)
if
(
!
make_dbt
(
dataobj
,
&
data
)
||
!
add_partial_dbt
(
&
data
,
dlen
,
doff
)
)
{
FREE_DBT
(
key
);
FREE_DBT
(
key
);
/* 'make_key_dbt' could do a 'malloc' */
return
NULL
;
}
MYDB_BEGIN_ALLOW_THREADS
;
err
=
self
->
dbc
->
c
_put
(
self
->
dbc
,
&
key
,
&
data
,
flags
);
err
=
_DBC
_put
(
self
->
dbc
,
&
key
,
&
data
,
flags
);
MYDB_END_ALLOW_THREADS
;
FREE_DBT
(
key
);
FREE_DBT
(
key
);
/* 'make_key_dbt' could do a 'malloc' */
RETURN_IF_ERR
();
self
->
mydb
->
haveStat
=
0
;
RETURN_NONE
();
...
...
@@ -3331,17 +3560,13 @@ DBC_set(DBCursorObject* self, PyObject* args, PyObject *kwargs)
return
NULL
;
CLEAR_DBT
(
data
);
if
(
CHECK_DBFLAG
(
self
->
mydb
,
DB_THREAD
))
{
/* Tell BerkeleyDB to malloc the return value (thread safe) */
data
.
flags
=
DB_DBT_MALLOC
;
}
if
(
!
add_partial_dbt
(
&
data
,
dlen
,
doff
))
{
FREE_DBT
(
key
);
FREE_DBT
(
key
);
/* 'make_key_dbt' could do a 'malloc' */
return
NULL
;
}
MYDB_BEGIN_ALLOW_THREADS
;
err
=
self
->
dbc
->
c
_get
(
self
->
dbc
,
&
key
,
&
data
,
flags
|
DB_SET
);
err
=
_DBC
_get
(
self
->
dbc
,
&
key
,
&
data
,
flags
|
DB_SET
);
MYDB_END_ALLOW_THREADS
;
if
((
err
==
DB_NOTFOUND
||
err
==
DB_KEYEMPTY
)
&&
self
->
mydb
->
moduleFlags
.
cursorSetReturnsNone
)
{
...
...
@@ -3359,22 +3584,19 @@ DBC_set(DBCursorObject* self, PyObject* args, PyObject *kwargs)
case
DB_BTREE
:
case
DB_HASH
:
default:
retval
=
Py_BuildValue
(
"s#s#"
,
key
.
data
,
key
.
size
,
data
.
data
,
data
.
size
);
retval
=
BuildValue_SS
(
key
.
data
,
key
.
size
,
data
.
data
,
data
.
size
);
break
;
case
DB_RECNO
:
case
DB_QUEUE
:
retval
=
Py_BuildValue
(
"is#"
,
*
((
db_recno_t
*
)
key
.
data
),
data
.
data
,
data
.
size
);
retval
=
BuildValue_IS
(
*
((
db_recno_t
*
)
key
.
data
),
data
.
data
,
data
.
size
);
break
;
}
FREE_DBT
(
data
);
FREE_DBT
(
key
);
FREE_DBT
(
key
);
/* 'make_key_dbt' could do a 'malloc' */
}
/* the only time REALLOC should be set is if we used an integer
* key that make_key_dbt malloc'd for us. always free these. */
if
(
key
.
flags
&
DB_DBT_REALLOC
)
{
FREE_DBT
(
key
);
FREE_DBT
(
key
);
/* 'make_key_dbt' could do a 'malloc' */
}
return
retval
;
...
...
@@ -3402,19 +3624,11 @@ DBC_set_range(DBCursorObject* self, PyObject* args, PyObject* kwargs)
CLEAR_DBT
(
data
);
if
(
!
add_partial_dbt
(
&
data
,
dlen
,
doff
))
{
FREE_DBT
(
key
);
FREE_DBT
(
key
);
/* 'make_key_dbt' could do a 'malloc' */
return
NULL
;
}
if
(
CHECK_DBFLAG
(
self
->
mydb
,
DB_THREAD
))
{
/* Tell BerkeleyDB to malloc the return value (thread safe) */
data
.
flags
|=
DB_DBT_MALLOC
;
/* only BTREE databases will return anything in the key */
if
(
!
(
key
.
flags
&
DB_DBT_REALLOC
)
&&
_DB_get_type
(
self
->
mydb
)
==
DB_BTREE
)
{
key
.
flags
|=
DB_DBT_MALLOC
;
}
}
MYDB_BEGIN_ALLOW_THREADS
;
err
=
self
->
dbc
->
c
_get
(
self
->
dbc
,
&
key
,
&
data
,
flags
|
DB_SET_RANGE
);
err
=
_DBC
_get
(
self
->
dbc
,
&
key
,
&
data
,
flags
|
DB_SET_RANGE
);
MYDB_END_ALLOW_THREADS
;
if
((
err
==
DB_NOTFOUND
||
err
==
DB_KEYEMPTY
)
&&
self
->
mydb
->
moduleFlags
.
cursorSetReturnsNone
)
{
...
...
@@ -3432,22 +3646,19 @@ DBC_set_range(DBCursorObject* self, PyObject* args, PyObject* kwargs)
case
DB_BTREE
:
case
DB_HASH
:
default:
retval
=
Py_BuildValue
(
"s#s#"
,
key
.
data
,
key
.
size
,
data
.
data
,
data
.
size
);
retval
=
BuildValue_SS
(
key
.
data
,
key
.
size
,
data
.
data
,
data
.
size
);
break
;
case
DB_RECNO
:
case
DB_QUEUE
:
retval
=
Py_BuildValue
(
"is#"
,
*
((
db_recno_t
*
)
key
.
data
),
data
.
data
,
data
.
size
);
retval
=
BuildValue_IS
(
*
((
db_recno_t
*
)
key
.
data
),
data
.
data
,
data
.
size
);
break
;
}
FREE_DBT
(
key
);
FREE_DBT
(
data
);
FREE_DBT
(
key
);
/* 'make_key_dbt' could do a 'malloc' */
}
/* the only time REALLOC should be set is if we used an integer
* key that make_key_dbt malloc'd for us. always free these. */
if
(
key
.
flags
&
DB_DBT_REALLOC
)
{
FREE_DBT
(
key
);
FREE_DBT
(
key
);
/* 'make_key_dbt' could do a 'malloc' */
}
return
retval
;
...
...
@@ -3465,12 +3676,12 @@ _DBC_get_set_both(DBCursorObject* self, PyObject* keyobj, PyObject* dataobj,
if
(
!
make_key_dbt
(
self
->
mydb
,
keyobj
,
&
key
,
NULL
))
return
NULL
;
if
(
!
make_dbt
(
dataobj
,
&
data
))
{
FREE_DBT
(
key
);
FREE_DBT
(
key
);
/* 'make_key_dbt' could do a 'malloc' */
return
NULL
;
}
MYDB_BEGIN_ALLOW_THREADS
;
err
=
self
->
dbc
->
c
_get
(
self
->
dbc
,
&
key
,
&
data
,
flags
|
DB_GET_BOTH
);
err
=
_DBC
_get
(
self
->
dbc
,
&
key
,
&
data
,
flags
|
DB_GET_BOTH
);
MYDB_END_ALLOW_THREADS
;
if
((
err
==
DB_NOTFOUND
||
err
==
DB_KEYEMPTY
)
&&
returnsNone
)
{
Py_INCREF
(
Py_None
);
...
...
@@ -3487,18 +3698,16 @@ _DBC_get_set_both(DBCursorObject* self, PyObject* keyobj, PyObject* dataobj,
case
DB_BTREE
:
case
DB_HASH
:
default:
retval
=
Py_BuildValue
(
"s#s#"
,
key
.
data
,
key
.
size
,
data
.
data
,
data
.
size
);
retval
=
BuildValue_SS
(
key
.
data
,
key
.
size
,
data
.
data
,
data
.
size
);
break
;
case
DB_RECNO
:
case
DB_QUEUE
:
retval
=
Py_BuildValue
(
"is#"
,
*
((
db_recno_t
*
)
key
.
data
),
data
.
data
,
data
.
size
);
retval
=
BuildValue_IS
(
*
((
db_recno_t
*
)
key
.
data
),
data
.
data
,
data
.
size
);
break
;
}
}
FREE_DBT
(
key
);
FREE_DBT
(
key
);
/* 'make_key_dbt' could do a 'malloc' */
return
retval
;
}
...
...
@@ -3537,7 +3746,7 @@ DBC_get_current_size(DBCursorObject* self, PyObject* args)
data
.
flags
=
DB_DBT_USERMEM
;
data
.
ulen
=
0
;
MYDB_BEGIN_ALLOW_THREADS
;
err
=
self
->
dbc
->
c
_get
(
self
->
dbc
,
&
key
,
&
data
,
flags
);
err
=
_DBC
_get
(
self
->
dbc
,
&
key
,
&
data
,
flags
);
MYDB_END_ALLOW_THREADS
;
if
(
err
==
DB_BUFFER_SMALL
||
!
err
)
{
/* DB_BUFFER_SMALL means positive size, !err means zero length value */
...
...
@@ -3545,8 +3754,6 @@ DBC_get_current_size(DBCursorObject* self, PyObject* args)
err
=
0
;
}
FREE_DBT
(
key
);
FREE_DBT
(
data
);
RETURN_IF_ERR
();
return
retval
;
}
...
...
@@ -3600,17 +3807,13 @@ DBC_set_recno(DBCursorObject* self, PyObject* args, PyObject *kwargs)
key
.
flags
=
DB_DBT_REALLOC
;
CLEAR_DBT
(
data
);
if
(
CHECK_DBFLAG
(
self
->
mydb
,
DB_THREAD
))
{
/* Tell BerkeleyDB to malloc the return value (thread safe) */
data
.
flags
=
DB_DBT_MALLOC
;
}
if
(
!
add_partial_dbt
(
&
data
,
dlen
,
doff
))
{
FREE_DBT
(
key
);
return
NULL
;
}
MYDB_BEGIN_ALLOW_THREADS
;
err
=
self
->
dbc
->
c
_get
(
self
->
dbc
,
&
key
,
&
data
,
flags
|
DB_SET_RECNO
);
err
=
_DBC
_get
(
self
->
dbc
,
&
key
,
&
data
,
flags
|
DB_SET_RECNO
);
MYDB_END_ALLOW_THREADS
;
if
((
err
==
DB_NOTFOUND
||
err
==
DB_KEYEMPTY
)
&&
self
->
mydb
->
moduleFlags
.
cursorSetReturnsNone
)
{
...
...
@@ -3621,9 +3824,7 @@ DBC_set_recno(DBCursorObject* self, PyObject* args, PyObject *kwargs)
retval
=
NULL
;
}
else
{
/* Can only be used for BTrees, so no need to return int key */
retval
=
Py_BuildValue
(
"s#s#"
,
key
.
data
,
key
.
size
,
data
.
data
,
data
.
size
);
FREE_DBT
(
data
);
retval
=
BuildValue_SS
(
key
.
data
,
key
.
size
,
data
.
data
,
data
.
size
);
}
FREE_DBT
(
key
);
...
...
@@ -3673,13 +3874,9 @@ DBC_join_item(DBCursorObject* self, PyObject* args)
CLEAR_DBT
(
key
);
CLEAR_DBT
(
data
);
if
(
CHECK_DBFLAG
(
self
->
mydb
,
DB_THREAD
))
{
/* Tell BerkeleyDB to malloc the return value (thread safe) */
key
.
flags
=
DB_DBT_MALLOC
;
}
MYDB_BEGIN_ALLOW_THREADS
;
err
=
self
->
dbc
->
c
_get
(
self
->
dbc
,
&
key
,
&
data
,
flags
|
DB_JOIN_ITEM
);
err
=
_DBC
_get
(
self
->
dbc
,
&
key
,
&
data
,
flags
|
DB_JOIN_ITEM
);
MYDB_END_ALLOW_THREADS
;
if
((
err
==
DB_NOTFOUND
||
err
==
DB_KEYEMPTY
)
&&
self
->
mydb
->
moduleFlags
.
getReturnsNone
)
{
...
...
@@ -3690,8 +3887,7 @@ DBC_join_item(DBCursorObject* self, PyObject* args)
retval
=
NULL
;
}
else
{
retval
=
Py_BuildValue
(
"s#"
,
key
.
data
,
key
.
size
);
FREE_DBT
(
key
);
retval
=
BuildValue_S
(
key
.
data
,
key
.
size
);
}
return
retval
;
...
...
@@ -3704,18 +3900,26 @@ DBC_join_item(DBCursorObject* self, PyObject* args)
static
PyObject
*
DBEnv_close
(
DBEnvObject
*
self
,
PyObject
*
ar
gs
)
DBEnv_close
_internal
(
DBEnvObject
*
self
,
int
fla
gs
)
{
int
err
,
flags
=
0
;
PyObject
*
dummy
;
int
err
;
if
(
!
PyArg_ParseTuple
(
args
,
"|i:close"
,
&
flags
))
return
NULL
;
if
(
!
self
->
closed
)
{
/* Don't close more than once */
while
(
self
->
children_txns
)
{
dummy
=
DBTxn_abort_discard_internal
(
self
->
children_txns
,
0
);
Py_XDECREF
(
dummy
);
}
while
(
self
->
children_dbs
)
{
dummy
=
DB_close_internal
(
self
->
children_dbs
,
0
);
Py_XDECREF
(
dummy
);
}
MYDB_BEGIN_ALLOW_THREADS
;
err
=
self
->
db_env
->
close
(
self
->
db_env
,
flags
);
MYDB_END_ALLOW_THREADS
;
/* after calling DBEnv->close, regardless of error, this DBEnv
* may not be accessed again (BerkeleyDB docs). */
* may not be accessed again (Berkeley
DB docs). */
self
->
closed
=
1
;
self
->
db_env
=
NULL
;
RETURN_IF_ERR
();
...
...
@@ -3723,9 +3927,19 @@ DBEnv_close(DBEnvObject* self, PyObject* args)
RETURN_NONE
();
}
static
PyObject
*
DBEnv_open
(
DBEnvObject
*
self
,
PyObject
*
args
)
DBEnv_close
(
DBEnvObject
*
self
,
PyObject
*
args
)
{
int
flags
=
0
;
if
(
!
PyArg_ParseTuple
(
args
,
"|i:close"
,
&
flags
))
return
NULL
;
return
DBEnv_close_internal
(
self
,
flags
);
}
static
PyObject
*
DBEnv_open
(
DBEnvObject
*
self
,
PyObject
*
args
)
{
int
err
,
flags
=
0
,
mode
=
0660
;
char
*
db_home
;
...
...
@@ -3982,6 +4196,25 @@ DBEnv_set_lg_max(DBEnvObject* self, PyObject* args)
RETURN_NONE
();
}
#if (DBVER >= 42)
static
PyObject
*
DBEnv_get_lg_max
(
DBEnvObject
*
self
,
PyObject
*
args
)
{
int
err
;
u_int32_t
lg_max
;
if
(
!
PyArg_ParseTuple
(
args
,
":get_lg_max"
))
return
NULL
;
CHECK_ENV_NOT_CLOSED
(
self
);
MYDB_BEGIN_ALLOW_THREADS
;
err
=
self
->
db_env
->
get_lg_max
(
self
->
db_env
,
&
lg_max
);
MYDB_END_ALLOW_THREADS
;
RETURN_IF_ERR
();
return
PyInt_FromLong
(
lg_max
);
}
#endif
#if (DBVER >= 33)
static
PyObject
*
...
...
@@ -4125,6 +4358,84 @@ DBEnv_set_tmp_dir(DBEnvObject* self, PyObject* args)
}
#if (DBVER >= 40)
static
PyObject
*
DBEnv_txn_recover
(
DBEnvObject
*
self
,
PyObject
*
args
)
{
int
flags
=
DB_FIRST
;
int
err
,
i
;
PyObject
*
list
,
*
tuple
,
*
gid
;
DBTxnObject
*
txn
;
#define PREPLIST_LEN 16
DB_PREPLIST
preplist
[
PREPLIST_LEN
];
long
retp
;
if
(
!
PyArg_ParseTuple
(
args
,
":txn_recover"
))
return
NULL
;
CHECK_ENV_NOT_CLOSED
(
self
);
list
=
PyList_New
(
0
);
if
(
!
list
)
return
NULL
;
while
(
!
0
)
{
MYDB_BEGIN_ALLOW_THREADS
err
=
self
->
db_env
->
txn_recover
(
self
->
db_env
,
preplist
,
PREPLIST_LEN
,
&
retp
,
flags
);
#undef PREPLIST_LEN
MYDB_END_ALLOW_THREADS
if
(
err
)
{
Py_DECREF
(
list
);
RETURN_IF_ERR
();
}
if
(
!
retp
)
break
;
flags
=
DB_NEXT
;
/* Prepare for next loop pass */
for
(
i
=
0
;
i
<
retp
;
i
++
)
{
gid
=
PyString_FromStringAndSize
((
char
*
)(
preplist
[
i
].
gid
),
DB_XIDDATASIZE
);
if
(
!
gid
)
{
Py_DECREF
(
list
);
return
NULL
;
}
txn
=
newDBTxnObject
(
self
,
NULL
,
preplist
[
i
].
txn
,
flags
);
if
(
!
txn
)
{
Py_DECREF
(
list
);
Py_DECREF
(
gid
);
return
NULL
;
}
txn
->
flag_prepare
=
1
;
/* Recover state */
tuple
=
PyTuple_New
(
2
);
if
(
!
tuple
)
{
Py_DECREF
(
list
);
Py_DECREF
(
gid
);
Py_DECREF
(
txn
);
return
NULL
;
}
if
(
PyTuple_SetItem
(
tuple
,
0
,
gid
))
{
Py_DECREF
(
list
);
Py_DECREF
(
gid
);
Py_DECREF
(
txn
);
Py_DECREF
(
tuple
);
return
NULL
;
}
if
(
PyTuple_SetItem
(
tuple
,
1
,
(
PyObject
*
)
txn
))
{
Py_DECREF
(
list
);
Py_DECREF
(
txn
);
Py_DECREF
(
tuple
);
/* This delete the "gid" also */
return
NULL
;
}
if
(
PyList_Append
(
list
,
tuple
))
{
Py_DECREF
(
list
);
Py_DECREF
(
tuple
);
/* This delete the "gid" and the "txn" also */
return
NULL
;
}
Py_DECREF
(
tuple
);
}
}
return
list
;
}
#endif
static
PyObject
*
DBEnv_txn_begin
(
DBEnvObject
*
self
,
PyObject
*
args
,
PyObject
*
kwargs
)
{
...
...
@@ -4141,7 +4452,7 @@ DBEnv_txn_begin(DBEnvObject* self, PyObject* args, PyObject* kwargs)
return
NULL
;
CHECK_ENV_NOT_CLOSED
(
self
);
return
(
PyObject
*
)
newDBTxnObject
(
self
,
txn
,
flags
);
return
(
PyObject
*
)
newDBTxnObject
(
self
,
(
DBTxnObject
*
)
txnobj
,
NULL
,
flags
);
}
...
...
@@ -4425,6 +4736,10 @@ DBEnv_lock_stat(DBEnvObject* self, PyObject* args)
#if (DBVER < 41)
MAKE_ENTRY
(
lastid
);
#endif
#if (DBVER >=41)
MAKE_ENTRY
(
id
);
MAKE_ENTRY
(
cur_maxid
);
#endif
MAKE_ENTRY
(
nmodes
);
MAKE_ENTRY
(
maxlocks
);
...
...
@@ -4438,6 +4753,10 @@ DBEnv_lock_stat(DBEnvObject* self, PyObject* args)
MAKE_ENTRY
(
maxnobjects
);
MAKE_ENTRY
(
nrequests
);
MAKE_ENTRY
(
nreleases
);
#if (DBVER >= 44)
MAKE_ENTRY
(
nupgrade
);
MAKE_ENTRY
(
ndowngrade
);
#endif
#if (DBVER < 44)
MAKE_ENTRY
(
nnowaits
);
/* these were renamed in 4.4 */
MAKE_ENTRY
(
nconflicts
);
...
...
@@ -4446,6 +4765,23 @@ DBEnv_lock_stat(DBEnvObject* self, PyObject* args)
MAKE_ENTRY
(
lock_wait
);
#endif
MAKE_ENTRY
(
ndeadlocks
);
#if (DBVER >= 41)
MAKE_ENTRY
(
locktimeout
);
MAKE_ENTRY
(
txntimeout
);
#endif
#if (DBVER >= 40)
MAKE_ENTRY
(
nlocktimeouts
);
MAKE_ENTRY
(
ntxntimeouts
);
#endif
#if (DBVER >= 46)
MAKE_ENTRY
(
objs_wait
);
MAKE_ENTRY
(
objs_nowait
);
MAKE_ENTRY
(
lockers_wait
);
MAKE_ENTRY
(
lockers_nowait
);
MAKE_ENTRY
(
locks_wait
);
MAKE_ENTRY
(
locks_nowait
);
MAKE_ENTRY
(
hash_len
);
#endif
MAKE_ENTRY
(
regsize
);
MAKE_ENTRY
(
region_wait
);
MAKE_ENTRY
(
region_nowait
);
...
...
@@ -4455,6 +4791,24 @@ DBEnv_lock_stat(DBEnvObject* self, PyObject* args)
return
d
;
}
#if (DBVER >= 40)
static
PyObject
*
DBEnv_log_flush
(
DBEnvObject
*
self
,
PyObject
*
args
)
{
int
err
;
if
(
!
PyArg_ParseTuple
(
args
,
":log_flush"
))
return
NULL
;
CHECK_ENV_NOT_CLOSED
(
self
);
MYDB_BEGIN_ALLOW_THREADS
err
=
self
->
db_env
->
log_flush
(
self
->
db_env
,
NULL
);
MYDB_END_ALLOW_THREADS
RETURN_IF_ERR
();
RETURN_NONE
();
}
#endif
static
PyObject
*
DBEnv_log_archive
(
DBEnvObject
*
self
,
PyObject
*
args
)
...
...
@@ -4465,120 +4819,625 @@ DBEnv_log_archive(DBEnvObject* self, PyObject* args)
PyObject
*
list
;
PyObject
*
item
=
NULL
;
if
(
!
PyArg_ParseTuple
(
args
,
"|i:log_archive"
,
&
flags
))
if
(
!
PyArg_ParseTuple
(
args
,
"|i:log_archive"
,
&
flags
))
return
NULL
;
CHECK_ENV_NOT_CLOSED
(
self
);
MYDB_BEGIN_ALLOW_THREADS
;
#if (DBVER >= 40)
err
=
self
->
db_env
->
log_archive
(
self
->
db_env
,
&
log_list
,
flags
);
#elif (DBVER == 33)
err
=
log_archive
(
self
->
db_env
,
&
log_list
,
flags
);
#else
err
=
log_archive
(
self
->
db_env
,
&
log_list
,
flags
,
NULL
);
#endif
MYDB_END_ALLOW_THREADS
;
RETURN_IF_ERR
();
list
=
PyList_New
(
0
);
if
(
list
==
NULL
)
{
if
(
log_list
)
free
(
log_list
);
return
NULL
;
}
if
(
log_list
)
{
char
**
log_list_start
;
for
(
log_list_start
=
log_list
;
*
log_list
!=
NULL
;
++
log_list
)
{
item
=
PyString_FromString
(
*
log_list
);
if
(
item
==
NULL
)
{
Py_DECREF
(
list
);
list
=
NULL
;
break
;
}
PyList_Append
(
list
,
item
);
Py_DECREF
(
item
);
}
free
(
log_list_start
);
}
return
list
;
}
static
PyObject
*
DBEnv_txn_stat
(
DBEnvObject
*
self
,
PyObject
*
args
)
{
int
err
;
DB_TXN_STAT
*
sp
;
PyObject
*
d
=
NULL
;
u_int32_t
flags
=
0
;
if
(
!
PyArg_ParseTuple
(
args
,
"|i:txn_stat"
,
&
flags
))
return
NULL
;
CHECK_ENV_NOT_CLOSED
(
self
);
MYDB_BEGIN_ALLOW_THREADS
;
#if (DBVER >= 40)
err
=
self
->
db_env
->
txn_stat
(
self
->
db_env
,
&
sp
,
flags
);
#elif (DBVER == 33)
err
=
txn_stat
(
self
->
db_env
,
&
sp
);
#else
err
=
txn_stat
(
self
->
db_env
,
&
sp
,
NULL
);
#endif
MYDB_END_ALLOW_THREADS
;
RETURN_IF_ERR
();
/* Turn the stat structure into a dictionary */
d
=
PyDict_New
();
if
(
d
==
NULL
)
{
free
(
sp
);
return
NULL
;
}
#define MAKE_ENTRY(name) _addIntToDict(d, #name, sp->st_##name)
#define MAKE_TIME_T_ENTRY(name) _addTimeTToDict(d, #name, sp->st_##name)
#define MAKE_DB_LSN_ENTRY(name) _addDB_lsnToDict(d, #name, sp->st_##name)
#if (DBVER >= 40)
MAKE_DB_LSN_ENTRY
(
last_ckp
);
#endif
MAKE_TIME_T_ENTRY
(
time_ckp
);
MAKE_ENTRY
(
last_txnid
);
MAKE_ENTRY
(
maxtxns
);
MAKE_ENTRY
(
nactive
);
MAKE_ENTRY
(
maxnactive
);
#if (DBVER >= 45)
MAKE_ENTRY
(
nsnapshot
);
MAKE_ENTRY
(
maxnsnapshot
);
#endif
MAKE_ENTRY
(
nbegins
);
MAKE_ENTRY
(
naborts
);
MAKE_ENTRY
(
ncommits
);
#if (DBVER >= 40)
MAKE_ENTRY
(
nrestores
);
#endif
MAKE_ENTRY
(
regsize
);
MAKE_ENTRY
(
region_wait
);
MAKE_ENTRY
(
region_nowait
);
#undef MAKE_DB_LSN_ENTRY
#undef MAKE_ENTRY
#undef MAKE_TIME_T_ENTRY
free
(
sp
);
return
d
;
}
static
PyObject
*
DBEnv_set_get_returns_none
(
DBEnvObject
*
self
,
PyObject
*
args
)
{
int
flags
=
0
;
int
oldValue
=
0
;
if
(
!
PyArg_ParseTuple
(
args
,
"i:set_get_returns_none"
,
&
flags
))
return
NULL
;
CHECK_ENV_NOT_CLOSED
(
self
);
if
(
self
->
moduleFlags
.
getReturnsNone
)
++
oldValue
;
if
(
self
->
moduleFlags
.
cursorSetReturnsNone
)
++
oldValue
;
self
->
moduleFlags
.
getReturnsNone
=
(
flags
>=
1
);
self
->
moduleFlags
.
cursorSetReturnsNone
=
(
flags
>=
2
);
return
PyInt_FromLong
(
oldValue
);
}
#if (DBVER >= 40)
static
PyObject
*
DBEnv_set_verbose
(
DBEnvObject
*
self
,
PyObject
*
args
)
{
int
err
;
int
which
,
onoff
;
if
(
!
PyArg_ParseTuple
(
args
,
"ii:set_verbose"
,
&
which
,
&
onoff
))
{
return
NULL
;
}
CHECK_ENV_NOT_CLOSED
(
self
);
MYDB_BEGIN_ALLOW_THREADS
;
err
=
self
->
db_env
->
set_verbose
(
self
->
db_env
,
which
,
onoff
);
MYDB_END_ALLOW_THREADS
;
RETURN_IF_ERR
();
RETURN_NONE
();
}
#if (DBVER >= 42)
static
PyObject
*
DBEnv_get_verbose
(
DBEnvObject
*
self
,
PyObject
*
args
)
{
int
err
;
int
which
;
int
verbose
;
if
(
!
PyArg_ParseTuple
(
args
,
"i:get_verbose"
,
&
which
))
{
return
NULL
;
}
CHECK_ENV_NOT_CLOSED
(
self
);
MYDB_BEGIN_ALLOW_THREADS
;
err
=
self
->
db_env
->
get_verbose
(
self
->
db_env
,
which
,
&
verbose
);
MYDB_END_ALLOW_THREADS
;
RETURN_IF_ERR
();
return
PyBool_FromLong
(
verbose
);
}
#endif
#endif
#if (DBVER >= 45)
static
void
_dbenv_event_notifyCallback
(
DB_ENV
*
db_env
,
u_int32_t
event
,
void
*
event_info
)
{
DBEnvObject
*
dbenv
;
PyObject
*
callback
;
PyObject
*
args
;
PyObject
*
result
=
NULL
;
MYDB_BEGIN_BLOCK_THREADS
;
dbenv
=
(
DBEnvObject
*
)
db_env
->
app_private
;
callback
=
dbenv
->
event_notifyCallback
;
if
(
callback
)
{
if
(
event
==
DB_EVENT_REP_NEWMASTER
)
{
args
=
Py_BuildValue
(
"(Oii)"
,
dbenv
,
event
,
*
((
int
*
)
event_info
));
}
else
{
args
=
Py_BuildValue
(
"(OiO)"
,
dbenv
,
event
,
Py_None
);
}
if
(
args
)
{
result
=
PyEval_CallObject
(
callback
,
args
);
}
if
((
!
args
)
||
(
!
result
))
{
PyErr_Print
();
}
Py_XDECREF
(
args
);
Py_XDECREF
(
result
);
}
MYDB_END_BLOCK_THREADS
;
}
#endif
#if (DBVER >= 45)
static
PyObject
*
DBEnv_set_event_notify
(
DBEnvObject
*
self
,
PyObject
*
args
)
{
int
err
;
PyObject
*
notifyFunc
;
if
(
!
PyArg_ParseTuple
(
args
,
"O:set_event_notify"
,
&
notifyFunc
))
{
return
NULL
;
}
CHECK_ENV_NOT_CLOSED
(
self
);
if
(
!
PyCallable_Check
(
notifyFunc
))
{
makeTypeError
(
"Callable"
,
notifyFunc
);
return
NULL
;
}
Py_XDECREF
(
self
->
event_notifyCallback
);
Py_INCREF
(
notifyFunc
);
self
->
event_notifyCallback
=
notifyFunc
;
MYDB_BEGIN_ALLOW_THREADS
;
err
=
self
->
db_env
->
set_event_notify
(
self
->
db_env
,
_dbenv_event_notifyCallback
);
MYDB_END_ALLOW_THREADS
;
if
(
err
)
{
Py_DECREF
(
notifyFunc
);
self
->
event_notifyCallback
=
NULL
;
}
RETURN_IF_ERR
();
RETURN_NONE
();
}
#endif
/* --------------------------------------------------------------------- */
/* REPLICATION METHODS: Base Replication */
#if (DBVER >= 45)
static
PyObject
*
DBEnv_rep_set_nsites
(
DBEnvObject
*
self
,
PyObject
*
args
)
{
int
err
;
int
nsites
;
if
(
!
PyArg_ParseTuple
(
args
,
"i:rep_set_nsites"
,
&
nsites
))
{
return
NULL
;
}
CHECK_ENV_NOT_CLOSED
(
self
);
MYDB_BEGIN_ALLOW_THREADS
;
err
=
self
->
db_env
->
rep_set_nsites
(
self
->
db_env
,
nsites
);
MYDB_END_ALLOW_THREADS
;
RETURN_IF_ERR
();
RETURN_NONE
();
}
static
PyObject
*
DBEnv_rep_get_nsites
(
DBEnvObject
*
self
,
PyObject
*
args
)
{
int
err
;
int
nsites
;
if
(
!
PyArg_ParseTuple
(
args
,
":rep_get_nsites"
))
{
return
NULL
;
}
CHECK_ENV_NOT_CLOSED
(
self
);
MYDB_BEGIN_ALLOW_THREADS
;
err
=
self
->
db_env
->
rep_get_nsites
(
self
->
db_env
,
&
nsites
);
MYDB_END_ALLOW_THREADS
;
RETURN_IF_ERR
();
return
PyInt_FromLong
(
nsites
);
}
static
PyObject
*
DBEnv_rep_set_priority
(
DBEnvObject
*
self
,
PyObject
*
args
)
{
int
err
;
int
priority
;
if
(
!
PyArg_ParseTuple
(
args
,
"i:rep_set_priority"
,
&
priority
))
{
return
NULL
;
}
CHECK_ENV_NOT_CLOSED
(
self
);
MYDB_BEGIN_ALLOW_THREADS
;
err
=
self
->
db_env
->
rep_set_priority
(
self
->
db_env
,
priority
);
MYDB_END_ALLOW_THREADS
;
RETURN_IF_ERR
();
RETURN_NONE
();
}
static
PyObject
*
DBEnv_rep_get_priority
(
DBEnvObject
*
self
,
PyObject
*
args
)
{
int
err
;
int
priority
;
if
(
!
PyArg_ParseTuple
(
args
,
":rep_get_priority"
))
{
return
NULL
;
}
CHECK_ENV_NOT_CLOSED
(
self
);
MYDB_BEGIN_ALLOW_THREADS
;
err
=
self
->
db_env
->
rep_get_priority
(
self
->
db_env
,
&
priority
);
MYDB_END_ALLOW_THREADS
;
RETURN_IF_ERR
();
return
PyInt_FromLong
(
priority
);
}
static
PyObject
*
DBEnv_rep_set_timeout
(
DBEnvObject
*
self
,
PyObject
*
args
)
{
int
err
;
int
which
,
timeout
;
if
(
!
PyArg_ParseTuple
(
args
,
"ii:rep_set_timeout"
,
&
which
,
&
timeout
))
{
return
NULL
;
}
CHECK_ENV_NOT_CLOSED
(
self
);
MYDB_BEGIN_ALLOW_THREADS
;
err
=
self
->
db_env
->
rep_set_timeout
(
self
->
db_env
,
which
,
timeout
);
MYDB_END_ALLOW_THREADS
;
RETURN_IF_ERR
();
RETURN_NONE
();
}
static
PyObject
*
DBEnv_rep_get_timeout
(
DBEnvObject
*
self
,
PyObject
*
args
)
{
int
err
;
int
which
;
u_int32_t
timeout
;
if
(
!
PyArg_ParseTuple
(
args
,
"i:rep_get_timeout"
,
&
which
))
{
return
NULL
;
}
CHECK_ENV_NOT_CLOSED
(
self
);
MYDB_BEGIN_ALLOW_THREADS
;
err
=
self
->
db_env
->
rep_get_timeout
(
self
->
db_env
,
which
,
&
timeout
);
MYDB_END_ALLOW_THREADS
;
RETURN_IF_ERR
();
return
PyInt_FromLong
(
timeout
);
}
#endif
/* --------------------------------------------------------------------- */
/* REPLICATION METHODS: Replication Manager */
#if (DBVER >= 45)
static
PyObject
*
DBEnv_repmgr_start
(
DBEnvObject
*
self
,
PyObject
*
args
,
PyObject
*
kwargs
)
{
int
err
;
int
nthreads
,
flags
;
static
char
*
kwnames
[]
=
{
"nthreads"
,
"flags"
,
NULL
};
if
(
!
PyArg_ParseTupleAndKeywords
(
args
,
kwargs
,
"ii:repmgr_start"
,
kwnames
,
&
nthreads
,
&
flags
))
{
return
NULL
;
}
CHECK_ENV_NOT_CLOSED
(
self
);
MYDB_BEGIN_ALLOW_THREADS
;
err
=
self
->
db_env
->
repmgr_start
(
self
->
db_env
,
nthreads
,
flags
);
MYDB_END_ALLOW_THREADS
;
RETURN_IF_ERR
();
RETURN_NONE
();
}
static
PyObject
*
DBEnv_repmgr_set_local_site
(
DBEnvObject
*
self
,
PyObject
*
args
,
PyObject
*
kwargs
)
{
int
err
;
char
*
host
;
int
port
;
int
flags
=
0
;
static
char
*
kwnames
[]
=
{
"host"
,
"port"
,
"flags"
,
NULL
};
if
(
!
PyArg_ParseTupleAndKeywords
(
args
,
kwargs
,
"si|i:repmgr_set_local_site"
,
kwnames
,
&
host
,
&
port
,
&
flags
))
{
return
NULL
;
}
CHECK_ENV_NOT_CLOSED
(
self
);
MYDB_BEGIN_ALLOW_THREADS
;
err
=
self
->
db_env
->
repmgr_set_local_site
(
self
->
db_env
,
host
,
port
,
flags
);
MYDB_END_ALLOW_THREADS
;
RETURN_IF_ERR
();
RETURN_NONE
();
}
static
PyObject
*
DBEnv_repmgr_add_remote_site
(
DBEnvObject
*
self
,
PyObject
*
args
,
PyObject
*
kwargs
)
{
int
err
;
char
*
host
;
int
port
;
int
flags
=
0
;
int
eidp
;
static
char
*
kwnames
[]
=
{
"host"
,
"port"
,
"flags"
,
NULL
};
if
(
!
PyArg_ParseTupleAndKeywords
(
args
,
kwargs
,
"si|i:repmgr_add_remote_site"
,
kwnames
,
&
host
,
&
port
,
&
flags
))
{
return
NULL
;
}
CHECK_ENV_NOT_CLOSED
(
self
);
MYDB_BEGIN_ALLOW_THREADS
;
err
=
self
->
db_env
->
repmgr_add_remote_site
(
self
->
db_env
,
host
,
port
,
&
eidp
,
flags
);
MYDB_END_ALLOW_THREADS
;
RETURN_IF_ERR
();
return
PyInt_FromLong
(
eidp
);
}
static
PyObject
*
DBEnv_repmgr_set_ack_policy
(
DBEnvObject
*
self
,
PyObject
*
args
)
{
int
err
;
int
ack_policy
;
if
(
!
PyArg_ParseTuple
(
args
,
"i:repmgr_set_ack_policy"
,
&
ack_policy
))
{
return
NULL
;
}
CHECK_ENV_NOT_CLOSED
(
self
);
MYDB_BEGIN_ALLOW_THREADS
;
err
=
self
->
db_env
->
repmgr_set_ack_policy
(
self
->
db_env
,
ack_policy
);
MYDB_END_ALLOW_THREADS
;
RETURN_IF_ERR
();
RETURN_NONE
();
}
static
PyObject
*
DBEnv_repmgr_get_ack_policy
(
DBEnvObject
*
self
,
PyObject
*
args
)
{
int
err
;
int
ack_policy
;
if
(
!
PyArg_ParseTuple
(
args
,
":repmgr_get_ack_policy"
))
{
return
NULL
;
}
CHECK_ENV_NOT_CLOSED
(
self
);
MYDB_BEGIN_ALLOW_THREADS
;
err
=
self
->
db_env
->
repmgr_get_ack_policy
(
self
->
db_env
,
&
ack_policy
);
MYDB_END_ALLOW_THREADS
;
RETURN_IF_ERR
();
return
PyInt_FromLong
(
ack_policy
);
}
static
PyObject
*
DBEnv_repmgr_site_list
(
DBEnvObject
*
self
,
PyObject
*
args
)
{
int
err
;
unsigned
int
countp
;
DB_REPMGR_SITE
*
listp
;
PyObject
*
stats
,
*
key
,
*
tuple
;
if
(
!
PyArg_ParseTuple
(
args
,
":repmgr_site_list"
))
{
return
NULL
;
}
CHECK_ENV_NOT_CLOSED
(
self
);
MYDB_BEGIN_ALLOW_THREADS
;
#if (DBVER >= 40)
err
=
self
->
db_env
->
log_archive
(
self
->
db_env
,
&
log_list
,
flags
);
#elif (DBVER == 33)
err
=
log_archive
(
self
->
db_env
,
&
log_list
,
flags
);
#else
err
=
log_archive
(
self
->
db_env
,
&
log_list
,
flags
,
NULL
);
#endif
err
=
self
->
db_env
->
repmgr_site_list
(
self
->
db_env
,
&
countp
,
&
listp
);
MYDB_END_ALLOW_THREADS
;
RETURN_IF_ERR
();
list
=
PyList_New
(
0
);
if
(
list
==
NULL
)
{
if
(
log_list
)
free
(
log_list
);
stats
=
PyDict_New
();
if
(
stats
==
NULL
)
{
free
(
listp
);
return
NULL
;
}
if
(
log_list
)
{
char
**
log_list_start
;
for
(
log_list_start
=
log_list
;
*
log_list
!=
NULL
;
++
log_list
)
{
item
=
PyString_FromString
(
*
log_list
);
if
(
item
==
NULL
)
{
Py_DECREF
(
list
);
list
=
NULL
;
break
;
}
PyList_Append
(
list
,
item
);
Py_DECREF
(
item
);
for
(;
countp
--
;)
{
key
=
PyInt_FromLong
(
listp
[
countp
].
eid
);
if
(
!
key
)
{
Py_DECREF
(
stats
);
free
(
listp
);
return
NULL
;
}
#if (PY_VERSION_HEX >= 0x02040000)
tuple
=
Py_BuildValue
(
"(sII)"
,
listp
[
countp
].
host
,
listp
[
countp
].
port
,
listp
[
countp
].
status
);
#else
tuple
=
Py_BuildValue
(
"(sii)"
,
listp
[
countp
].
host
,
listp
[
countp
].
port
,
listp
[
countp
].
status
);
#endif
if
(
!
tuple
)
{
Py_DECREF
(
key
);
Py_DECREF
(
stats
);
free
(
listp
);
return
NULL
;
}
if
(
PyDict_SetItem
(
stats
,
key
,
tuple
))
{
Py_DECREF
(
key
);
Py_DECREF
(
tuple
);
Py_DECREF
(
stats
);
free
(
listp
);
return
NULL
;
}
free
(
log_list_start
);
}
return
list
;
free
(
listp
);
return
stats
;
}
#endif
#if (DBVER >= 46)
static
PyObject
*
DBEnv_
txn_stat
(
DBEnvObject
*
self
,
PyObject
*
args
)
DBEnv_
repmgr_stat_print
(
DBEnvObject
*
self
,
PyObject
*
args
,
PyObject
*
kw
args
)
{
int
err
;
DB_TXN_STAT
*
sp
;
PyObject
*
d
=
NULL
;
u_int32_t
flags
=
0
;
int
flags
=
0
;
static
char
*
kwnames
[]
=
{
"flags"
,
NULL
};
if
(
!
PyArg_ParseTuple
(
args
,
"|i:txn_stat"
,
&
flags
))
if
(
!
PyArg_ParseTupleAndKeywords
(
args
,
kwargs
,
"|i:repmgr_stat_print"
,
kwnames
,
&
flags
))
{
return
NULL
;
}
CHECK_ENV_NOT_CLOSED
(
self
);
MYDB_BEGIN_ALLOW_THREADS
;
err
=
self
->
db_env
->
repmgr_stat_print
(
self
->
db_env
,
flags
);
MYDB_END_ALLOW_THREADS
;
RETURN_IF_ERR
();
RETURN_NONE
();
}
static
PyObject
*
DBEnv_repmgr_stat
(
DBEnvObject
*
self
,
PyObject
*
args
,
PyObject
*
kwargs
)
{
int
err
;
int
flags
=
0
;
DB_REPMGR_STAT
*
statp
;
PyObject
*
stats
;
static
char
*
kwnames
[]
=
{
"flags"
,
NULL
};
if
(
!
PyArg_ParseTupleAndKeywords
(
args
,
kwargs
,
"|i:repmgr_stat"
,
kwnames
,
&
flags
))
{
return
NULL
;
}
CHECK_ENV_NOT_CLOSED
(
self
);
MYDB_BEGIN_ALLOW_THREADS
;
#if (DBVER >= 40)
err
=
self
->
db_env
->
txn_stat
(
self
->
db_env
,
&
sp
,
flags
);
#elif (DBVER == 33)
err
=
txn_stat
(
self
->
db_env
,
&
sp
);
#else
err
=
txn_stat
(
self
->
db_env
,
&
sp
,
NULL
);
#endif
err
=
self
->
db_env
->
repmgr_stat
(
self
->
db_env
,
&
statp
,
flags
);
MYDB_END_ALLOW_THREADS
;
RETURN_IF_ERR
();
/* Turn the stat structure into a dictionary */
d
=
PyDict_New
();
if
(
d
==
NULL
)
{
free
(
sp
);
stats
=
PyDict_New
();
if
(
stats
==
NULL
)
{
free
(
statp
);
return
NULL
;
}
#define MAKE_ENTRY(name) _addIntToDict(d, #name, sp->st_##name)
#define MAKE_TIME_T_ENTRY(name)_addTimeTToDict(d, #name, sp->st_##name)
#define MAKE_ENTRY(name) _addIntToDict(stats, #name, statp->st_##name)
MAKE_TIME_T_ENTRY
(
time_ckp
);
MAKE_ENTRY
(
last_txnid
);
MAKE_ENTRY
(
maxtxns
);
MAKE_ENTRY
(
nactive
);
MAKE_ENTRY
(
maxnactive
);
MAKE_ENTRY
(
nbegins
);
MAKE_ENTRY
(
naborts
);
MAKE_ENTRY
(
ncommits
);
MAKE_ENTRY
(
regsize
);
MAKE_ENTRY
(
region_wait
);
MAKE_ENTRY
(
region_nowait
);
MAKE_ENTRY
(
perm_failed
);
MAKE_ENTRY
(
msgs_queued
);
MAKE_ENTRY
(
msgs_dropped
);
MAKE_ENTRY
(
connection_drop
);
MAKE_ENTRY
(
connect_fail
);
#undef MAKE_ENTRY
#undef MAKE_TIME_T_ENTRY
free
(
sp
);
return
d
;
free
(
s
tat
p
);
return
stats
;
}
#endif
static
PyObject
*
DBEnv_set_get_returns_none
(
DBEnvObject
*
self
,
PyObject
*
args
)
{
int
flags
=
0
;
int
oldValue
=
0
;
/* --------------------------------------------------------------------- */
/* DBTxn methods */
if
(
!
PyArg_ParseTuple
(
args
,
"i:set_get_returns_none"
,
&
flags
))
return
NULL
;
CHECK_ENV_NOT_CLOSED
(
self
);
if
(
self
->
moduleFlags
.
getReturnsNone
)
++
oldValue
;
if
(
self
->
moduleFlags
.
cursorSetReturnsNone
)
++
oldValue
;
self
->
moduleFlags
.
getReturnsNone
=
(
flags
>=
1
);
self
->
moduleFlags
.
cursorSetReturnsNone
=
(
flags
>=
2
);
return
PyInt_FromLong
(
oldValue
);
static
void
_close_transaction_cursors
(
DBTxnObject
*
txn
)
{
PyObject
*
dummy
;
while
(
txn
->
children_cursors
)
{
PyErr_Warn
(
PyExc_RuntimeWarning
,
"Must close cursors before resolving a transaction."
);
dummy
=
DBC_close_internal
(
txn
->
children_cursors
);
Py_XDECREF
(
dummy
);
}
}
static
void
_promote_transaction_dbs_and_sequences
(
DBTxnObject
*
txn
)
{
DBObject
*
db
;
#if (DBVER >= 43)
DBSequenceObject
*
dbs
;
#endif
/* --------------------------------------------------------------------- */
/* DBTxn methods */
while
(
txn
->
children_dbs
)
{
db
=
txn
->
children_dbs
;
EXTRACT_FROM_DOUBLE_LINKED_LIST_TXN
(
db
);
if
(
txn
->
parent_txn
)
{
INSERT_IN_DOUBLE_LINKED_LIST_TXN
(
txn
->
parent_txn
->
children_dbs
,
db
);
db
->
txn
=
txn
->
parent_txn
;
}
else
{
/* The db is already linked to its environment,
** so nothing to do.
*/
db
->
txn
=
NULL
;
}
}
#if (DBVER >= 43)
while
(
txn
->
children_sequences
)
{
dbs
=
txn
->
children_sequences
;
EXTRACT_FROM_DOUBLE_LINKED_LIST_TXN
(
dbs
);
if
(
txn
->
parent_txn
)
{
INSERT_IN_DOUBLE_LINKED_LIST_TXN
(
txn
->
parent_txn
->
children_sequences
,
dbs
);
dbs
->
txn
=
txn
->
parent_txn
;
}
else
{
/* The sequence is already linked to its
** parent db. Nothing to do.
*/
dbs
->
txn
=
NULL
;
}
}
#endif
}
static
PyObject
*
...
...
@@ -4590,15 +5449,22 @@ DBTxn_commit(DBTxnObject* self, PyObject* args)
if
(
!
PyArg_ParseTuple
(
args
,
"|i:commit"
,
&
flags
))
return
NULL
;
_close_transaction_cursors
(
self
);
if
(
!
self
->
txn
)
{
PyObject
*
t
=
Py_BuildValue
(
"(is)"
,
0
,
"DBTxn must not be used "
"after txn_commit or txn_abort"
);
"after txn_commit, txn_abort "
"or txn_discard"
);
PyErr_SetObject
(
DBError
,
t
);
Py_DECREF
(
t
);
return
NULL
;
}
self
->
flag_prepare
=
0
;
txn
=
self
->
txn
;
self
->
txn
=
NULL
;
/* this DB_TXN is no longer valid after this call */
EXTRACT_FROM_DOUBLE_LINKED_LIST
(
self
);
MYDB_BEGIN_ALLOW_THREADS
;
#if (DBVER >= 40)
err
=
txn
->
commit
(
txn
,
flags
);
...
...
@@ -4606,6 +5472,9 @@ DBTxn_commit(DBTxnObject* self, PyObject* args)
err
=
txn_commit
(
txn
,
flags
);
#endif
MYDB_END_ALLOW_THREADS
;
_promote_transaction_dbs_and_sequences
(
self
);
RETURN_IF_ERR
();
RETURN_NONE
();
}
...
...
@@ -4629,11 +5498,13 @@ DBTxn_prepare(DBTxnObject* self, PyObject* args)
if
(
!
self
->
txn
)
{
PyObject
*
t
=
Py_BuildValue
(
"(is)"
,
0
,
"DBTxn must not be used "
"after txn_commit or txn_abort"
);
"after txn_commit, txn_abort "
"or txn_discard"
);
PyErr_SetObject
(
DBError
,
t
);
Py_DECREF
(
t
);
return
NULL
;
}
self
->
flag_prepare
=
1
;
/* Prepare state */
MYDB_BEGIN_ALLOW_THREADS
;
#if (DBVER >= 40)
err
=
self
->
txn
->
prepare
(
self
->
txn
,
(
u_int8_t
*
)
gid
);
...
...
@@ -4651,7 +5522,8 @@ DBTxn_prepare(DBTxnObject* self, PyObject* args)
if
(
!
self
->
txn
)
{
PyObject
*
t
=
Py_BuildValue
(
"(is)"
,
0
,
"DBTxn must not be used "
"after txn_commit or txn_abort"
);
"after txn_commit, txn_abort "
"or txn_discard"
);
PyErr_SetObject
(
DBError
,
t
);
Py_DECREF
(
t
);
return
NULL
;
...
...
@@ -4666,34 +5538,87 @@ DBTxn_prepare(DBTxnObject* self, PyObject* args)
static
PyObject
*
DBTxn_abort
(
DBTxnObject
*
self
,
PyObject
*
args
)
DBTxn_abort
_discard_internal
(
DBTxnObject
*
self
,
int
discard
)
{
int
err
;
PyObject
*
dummy
;
int
err
=
0
;
DB_TXN
*
txn
;
if
(
!
PyArg_ParseTuple
(
args
,
":abort"
))
return
NULL
;
if
(
!
self
->
txn
)
{
PyObject
*
t
=
Py_BuildValue
(
"(is)"
,
0
,
"DBTxn must not be used "
"after txn_commit or txn_abort"
);
"after txn_commit, txn_abort "
"or txn_discard"
);
PyErr_SetObject
(
DBError
,
t
);
Py_DECREF
(
t
);
return
NULL
;
}
txn
=
self
->
txn
;
self
->
txn
=
NULL
;
/* this DB_TXN is no longer valid after this call */
_close_transaction_cursors
(
self
);
#if (DBVER >= 43)
while
(
self
->
children_sequences
)
{
dummy
=
DBSequence_close_internal
(
self
->
children_sequences
,
0
,
0
);
Py_XDECREF
(
dummy
);
}
#endif
while
(
self
->
children_dbs
)
{
dummy
=
DB_close_internal
(
self
->
children_dbs
,
0
);
Py_XDECREF
(
dummy
);
}
EXTRACT_FROM_DOUBLE_LINKED_LIST
(
self
);
MYDB_BEGIN_ALLOW_THREADS
;
if
(
discard
)
{
assert
(
!
self
->
flag_prepare
);
#if (DBVER >= 40)
err
=
txn
->
discard
(
txn
,
0
);
#else
err
=
txn_discard
(
txn
);
#endif
}
else
{
/*
** If the transaction is in the "prepare" or "recover" state,
** we better do not implicitly abort it.
*/
if
(
!
self
->
flag_prepare
)
{
#if (DBVER >= 40)
err
=
txn
->
abort
(
txn
);
err
=
txn
->
abort
(
txn
);
#else
err
=
txn_abort
(
txn
);
err
=
txn_abort
(
txn
);
#endif
}
}
MYDB_END_ALLOW_THREADS
;
RETURN_IF_ERR
();
RETURN_NONE
();
}
static
PyObject
*
DBTxn_abort
(
DBTxnObject
*
self
,
PyObject
*
args
)
{
if
(
!
PyArg_ParseTuple
(
args
,
":abort"
))
return
NULL
;
self
->
flag_prepare
=
0
;
_close_transaction_cursors
(
self
);
return
DBTxn_abort_discard_internal
(
self
,
0
);
}
static
PyObject
*
DBTxn_discard
(
DBTxnObject
*
self
,
PyObject
*
args
)
{
if
(
!
PyArg_ParseTuple
(
args
,
":discard"
))
return
NULL
;
self
->
flag_prepare
=
0
;
_close_transaction_cursors
(
self
);
return
DBTxn_abort_discard_internal
(
self
,
1
);
}
static
PyObject
*
DBTxn_id
(
DBTxnObject
*
self
,
PyObject
*
args
)
...
...
@@ -4705,7 +5630,8 @@ DBTxn_id(DBTxnObject* self, PyObject* args)
if
(
!
self
->
txn
)
{
PyObject
*
t
=
Py_BuildValue
(
"(is)"
,
0
,
"DBTxn must not be used "
"after txn_commit or txn_abort"
);
"after txn_commit, txn_abort "
"or txn_discard"
);
PyErr_SetObject
(
DBError
,
t
);
Py_DECREF
(
t
);
return
NULL
;
...
...
@@ -4726,23 +5652,40 @@ DBTxn_id(DBTxnObject* self, PyObject* args)
static
PyObject
*
DBSequence_close
(
DBSequenceObject
*
self
,
PyObject
*
args
)
DBSequence_close
_internal
(
DBSequenceObject
*
self
,
int
flags
,
int
do_not_close
)
{
int
err
,
flags
=
0
;
if
(
!
PyArg_ParseTuple
(
args
,
"|i:close"
,
&
flags
))
return
NULL
;
CHECK_SEQUENCE_NOT_CLOSED
(
self
)
int
err
=
0
;
MYDB_BEGIN_ALLOW_THREADS
err
=
self
->
sequence
->
close
(
self
->
sequence
,
flags
);
self
->
sequence
=
NULL
;
MYDB_END_ALLOW_THREADS
if
(
self
->
sequence
!=
NULL
)
{
EXTRACT_FROM_DOUBLE_LINKED_LIST
(
self
);
if
(
self
->
txn
)
{
EXTRACT_FROM_DOUBLE_LINKED_LIST_TXN
(
self
);
self
->
txn
=
NULL
;
}
RETURN_IF_ERR
();
if
(
!
do_not_close
)
{
MYDB_BEGIN_ALLOW_THREADS
err
=
self
->
sequence
->
close
(
self
->
sequence
,
flags
);
MYDB_END_ALLOW_THREADS
}
self
->
sequence
=
NULL
;
RETURN_IF_ERR
();
}
RETURN_NONE
();
}
static
PyObject
*
DBSequence_close
(
DBSequenceObject
*
self
,
PyObject
*
args
)
{
int
flags
=
0
;
if
(
!
PyArg_ParseTuple
(
args
,
"|i:close"
,
&
flags
))
return
NULL
;
return
DBSequence_close_internal
(
self
,
flags
,
0
);
}
static
PyObject
*
DBSequence_get
(
DBSequenceObject
*
self
,
PyObject
*
args
,
PyObject
*
kwargs
)
{
...
...
@@ -4765,7 +5708,6 @@ DBSequence_get(DBSequenceObject* self, PyObject* args, PyObject* kwargs)
RETURN_IF_ERR
();
return
PyLong_FromLongLong
(
value
);
}
static
PyObject
*
...
...
@@ -4784,6 +5726,10 @@ DBSequence_get_key(DBSequenceObject* self, PyObject* args)
int
err
;
DBT
key
;
PyObject
*
retval
=
NULL
;
if
(
!
PyArg_ParseTuple
(
args
,
":get_key"
))
return
NULL
;
key
.
flags
=
DB_DBT_MALLOC
;
CHECK_SEQUENCE_NOT_CLOSED
(
self
)
MYDB_BEGIN_ALLOW_THREADS
...
...
@@ -4791,7 +5737,7 @@ DBSequence_get_key(DBSequenceObject* self, PyObject* args)
MYDB_END_ALLOW_THREADS
if
(
!
err
)
retval
=
PyString_FromStringAndSize
(
key
.
data
,
key
.
size
);
retval
=
Build_PyString
(
key
.
data
,
key
.
size
);
FREE_DBT
(
key
);
RETURN_IF_ERR
();
...
...
@@ -4803,13 +5749,15 @@ static PyObject*
DBSequence_init_value
(
DBSequenceObject
*
self
,
PyObject
*
args
)
{
int
err
;
db_seq_t
value
;
PY_LONG_LONG
value
;
db_seq_t
value2
;
if
(
!
PyArg_ParseTuple
(
args
,
"L:init_value"
,
&
value
))
return
NULL
;
CHECK_SEQUENCE_NOT_CLOSED
(
self
)
value2
=
value
;
/* If truncation, compiler should show a warning */
MYDB_BEGIN_ALLOW_THREADS
err
=
self
->
sequence
->
initial_value
(
self
->
sequence
,
value
);
err
=
self
->
sequence
->
initial_value
(
self
->
sequence
,
value
2
);
MYDB_END_ALLOW_THREADS
RETURN_IF_ERR
();
...
...
@@ -4843,12 +5791,18 @@ DBSequence_open(DBSequenceObject* self, PyObject* args, PyObject* kwargs)
CLEAR_DBT
(
key
);
RETURN_IF_ERR
();
if
(
txn
)
{
INSERT_IN_DOUBLE_LINKED_LIST_TXN
(((
DBTxnObject
*
)
txnobj
)
->
children_sequences
,
self
);
self
->
txn
=
(
DBTxnObject
*
)
txnobj
;
}
RETURN_NONE
();
}
static
PyObject
*
DBSequence_remove
(
DBSequenceObject
*
self
,
PyObject
*
args
,
PyObject
*
kwargs
)
{
PyObject
*
dummy
;
int
err
,
flags
=
0
;
PyObject
*
txnobj
=
NULL
;
DB_TXN
*
txn
=
NULL
;
...
...
@@ -4866,6 +5820,9 @@ DBSequence_remove(DBSequenceObject* self, PyObject* args, PyObject* kwargs)
err
=
self
->
sequence
->
remove
(
self
->
sequence
,
txn
,
flags
);
MYDB_END_ALLOW_THREADS
dummy
=
DBSequence_close_internal
(
self
,
flags
,
1
);
Py_XDECREF
(
dummy
);
RETURN_IF_ERR
();
RETURN_NONE
();
}
...
...
@@ -4916,7 +5873,6 @@ DBSequence_set_flags(DBSequenceObject* self, PyObject* args)
RETURN_IF_ERR
();
RETURN_NONE
();
}
static
PyObject
*
...
...
@@ -4940,13 +5896,16 @@ static PyObject*
DBSequence_set_range
(
DBSequenceObject
*
self
,
PyObject
*
args
)
{
int
err
;
db_seq_t
min
,
max
;
PY_LONG_LONG
min
,
max
;
db_seq_t
min2
,
max2
;
if
(
!
PyArg_ParseTuple
(
args
,
"(LL):set_range"
,
&
min
,
&
max
))
return
NULL
;
CHECK_SEQUENCE_NOT_CLOSED
(
self
)
min2
=
min
;
/* If truncation, compiler should show a warning */
max2
=
max
;
MYDB_BEGIN_ALLOW_THREADS
err
=
self
->
sequence
->
set_range
(
self
->
sequence
,
min
,
max
);
err
=
self
->
sequence
->
set_range
(
self
->
sequence
,
min
2
,
max2
);
MYDB_END_ALLOW_THREADS
RETURN_IF_ERR
();
...
...
@@ -4957,16 +5916,19 @@ static PyObject*
DBSequence_get_range
(
DBSequenceObject
*
self
,
PyObject
*
args
)
{
int
err
;
db_seq_t
min
,
max
;
PY_LONG_LONG
min
,
max
;
db_seq_t
min2
,
max2
;
if
(
!
PyArg_ParseTuple
(
args
,
":get_range"
))
return
NULL
;
CHECK_SEQUENCE_NOT_CLOSED
(
self
)
MYDB_BEGIN_ALLOW_THREADS
err
=
self
->
sequence
->
get_range
(
self
->
sequence
,
&
min
,
&
max
);
err
=
self
->
sequence
->
get_range
(
self
->
sequence
,
&
min
2
,
&
max2
);
MYDB_END_ALLOW_THREADS
RETURN_IF_ERR
();
min
=
min2
;
/* If truncation, compiler should show a warning */
max
=
max2
;
return
Py_BuildValue
(
"(LL)"
,
min
,
max
);
}
...
...
@@ -5134,6 +6096,9 @@ static PyMethodDef DBEnv_methods[] = {
{
"set_lg_bsize"
,
(
PyCFunction
)
DBEnv_set_lg_bsize
,
METH_VARARGS
},
{
"set_lg_dir"
,
(
PyCFunction
)
DBEnv_set_lg_dir
,
METH_VARARGS
},
{
"set_lg_max"
,
(
PyCFunction
)
DBEnv_set_lg_max
,
METH_VARARGS
},
#if (DBVER >= 42)
{
"get_lg_max"
,
(
PyCFunction
)
DBEnv_get_lg_max
,
METH_VARARGS
},
#endif
#if (DBVER >= 33)
{
"set_lg_regionmax"
,(
PyCFunction
)
DBEnv_set_lg_regionmax
,
METH_VARARGS
},
#endif
...
...
@@ -5160,6 +6125,9 @@ static PyMethodDef DBEnv_methods[] = {
{
"lock_put"
,
(
PyCFunction
)
DBEnv_lock_put
,
METH_VARARGS
},
{
"lock_stat"
,
(
PyCFunction
)
DBEnv_lock_stat
,
METH_VARARGS
},
{
"log_archive"
,
(
PyCFunction
)
DBEnv_log_archive
,
METH_VARARGS
},
#if (DBVER >= 40)
{
"log_flush"
,
(
PyCFunction
)
DBEnv_log_flush
,
METH_VARARGS
},
#endif
#if (DBVER >= 40)
{
"log_stat"
,
(
PyCFunction
)
DBEnv_log_stat
,
METH_VARARGS
},
#endif
...
...
@@ -5167,6 +6135,46 @@ static PyMethodDef DBEnv_methods[] = {
{
"lsn_reset"
,
(
PyCFunction
)
DBEnv_lsn_reset
,
METH_VARARGS
|
METH_KEYWORDS
},
#endif
{
"set_get_returns_none"
,(
PyCFunction
)
DBEnv_set_get_returns_none
,
METH_VARARGS
},
#if (DBVER >= 40)
{
"txn_recover"
,
(
PyCFunction
)
DBEnv_txn_recover
,
METH_VARARGS
},
#endif
#if (DBVER >= 40)
{
"set_verbose"
,
(
PyCFunction
)
DBEnv_set_verbose
,
METH_VARARGS
},
#if (DBVER >= 42)
{
"get_verbose"
,
(
PyCFunction
)
DBEnv_get_verbose
,
METH_VARARGS
},
#endif
#endif
#if (DBVER >= 45)
{
"set_event_notify"
,
(
PyCFunction
)
DBEnv_set_event_notify
,
METH_VARARGS
},
#endif
#if (DBVER >= 45)
{
"rep_set_nsites"
,
(
PyCFunction
)
DBEnv_rep_set_nsites
,
METH_VARARGS
},
{
"rep_get_nsites"
,
(
PyCFunction
)
DBEnv_rep_get_nsites
,
METH_VARARGS
},
{
"rep_set_priority"
,
(
PyCFunction
)
DBEnv_rep_set_priority
,
METH_VARARGS
},
{
"rep_get_priority"
,
(
PyCFunction
)
DBEnv_rep_get_priority
,
METH_VARARGS
},
{
"rep_set_timeout"
,
(
PyCFunction
)
DBEnv_rep_set_timeout
,
METH_VARARGS
},
{
"rep_get_timeout"
,
(
PyCFunction
)
DBEnv_rep_get_timeout
,
METH_VARARGS
},
#endif
#if (DBVER >= 45)
{
"repmgr_start"
,
(
PyCFunction
)
DBEnv_repmgr_start
,
METH_VARARGS
|
METH_KEYWORDS
},
{
"repmgr_set_local_site"
,
(
PyCFunction
)
DBEnv_repmgr_set_local_site
,
METH_VARARGS
|
METH_KEYWORDS
},
{
"repmgr_add_remote_site"
,
(
PyCFunction
)
DBEnv_repmgr_add_remote_site
,
METH_VARARGS
|
METH_KEYWORDS
},
{
"repmgr_set_ack_policy"
,
(
PyCFunction
)
DBEnv_repmgr_set_ack_policy
,
METH_VARARGS
},
{
"repmgr_get_ack_policy"
,
(
PyCFunction
)
DBEnv_repmgr_get_ack_policy
,
METH_VARARGS
},
{
"repmgr_site_list"
,
(
PyCFunction
)
DBEnv_repmgr_site_list
,
METH_VARARGS
},
#endif
#if (DBVER >= 46)
{
"repmgr_stat"
,
(
PyCFunction
)
DBEnv_repmgr_stat
,
METH_VARARGS
|
METH_KEYWORDS
},
{
"repmgr_stat_print"
,
(
PyCFunction
)
DBEnv_repmgr_stat_print
,
METH_VARARGS
|
METH_KEYWORDS
},
#endif
{
NULL
,
NULL
}
/* sentinel */
};
...
...
@@ -5174,6 +6182,7 @@ static PyMethodDef DBEnv_methods[] = {
static
PyMethodDef
DBTxn_methods
[]
=
{
{
"commit"
,
(
PyCFunction
)
DBTxn_commit
,
METH_VARARGS
},
{
"prepare"
,
(
PyCFunction
)
DBTxn_prepare
,
METH_VARARGS
},
{
"discard"
,
(
PyCFunction
)
DBTxn_discard
,
METH_VARARGS
},
{
"abort"
,
(
PyCFunction
)
DBTxn_abort
,
METH_VARARGS
},
{
"id"
,
(
PyCFunction
)
DBTxn_id
,
METH_VARARGS
},
{
NULL
,
NULL
}
/* sentinel */
...
...
@@ -5212,11 +6221,17 @@ static PyObject*
DBEnv_getattr
(
DBEnvObject
*
self
,
char
*
name
)
{
if
(
!
strcmp
(
name
,
"db_home"
))
{
CHECK_ENV_NOT_CLOSED
(
self
);
if
(
self
->
db_env
->
db_home
==
NULL
)
{
RETURN_NONE
();
}
return
PyString_FromString
(
self
->
db_env
->
db_home
);
const
char
*
home
=
NULL
;
CHECK_ENV_NOT_CLOSED
(
self
);
#if (DBVER >= 42)
self
->
db_env
->
get_home
(
self
->
db_env
,
&
home
);
#else
home
=
self
->
db_env
->
db_home
;
#endif
if
(
home
==
NULL
)
{
RETURN_NONE
();
}
return
PyString_FromString
(
home
);
}
return
Py_FindMethod
(
DBEnv_methods
,
(
PyObject
*
)
self
,
name
);
...
...
@@ -5582,7 +6597,7 @@ DL_EXPORT(void) init_bsddb(void)
ADD_INT
(
d
,
DB_RPCCLIENT
);
#else
ADD_INT
(
d
,
DB_CLIENT
);
/* allow apps to be written using DB_RPCCLIENT on older BerkeleyDB */
/* allow apps to be written using DB_RPCCLIENT on older Berkeley
DB */
_addIntToDict
(
d
,
"DB_RPCCLIENT"
,
DB_CLIENT
);
#endif
ADD_INT
(
d
,
DB_XA_CREATE
);
...
...
@@ -5590,6 +6605,9 @@ DL_EXPORT(void) init_bsddb(void)
ADD_INT
(
d
,
DB_CREATE
);
ADD_INT
(
d
,
DB_NOMMAP
);
ADD_INT
(
d
,
DB_THREAD
);
#if (DBVER >= 45)
ADD_INT
(
d
,
DB_MULTIVERSION
);
#endif
ADD_INT
(
d
,
DB_FORCE
);
ADD_INT
(
d
,
DB_INIT_CDB
);
...
...
@@ -5599,6 +6617,10 @@ DL_EXPORT(void) init_bsddb(void)
ADD_INT
(
d
,
DB_INIT_TXN
);
ADD_INT
(
d
,
DB_JOINENV
);
#if (DBVER >= 40)
ADD_INT
(
d
,
DB_XIDDATASIZE
);
#endif
ADD_INT
(
d
,
DB_RECOVER
);
ADD_INT
(
d
,
DB_RECOVER_FATAL
);
ADD_INT
(
d
,
DB_TXN_NOSYNC
);
...
...
@@ -5645,6 +6667,13 @@ DL_EXPORT(void) init_bsddb(void)
ADD_INT
(
d
,
DB_LOCK_MINWRITE
);
#endif
#if (DBVER >= 40)
ADD_INT
(
d
,
DB_LOCK_EXPIRE
);
#endif
#if (DBVER >= 43)
ADD_INT
(
d
,
DB_LOCK_MAXWRITE
);
#endif
#if (DBVER >= 33)
/* docs say to use zero instead */
...
...
@@ -5816,6 +6845,10 @@ DL_EXPORT(void) init_bsddb(void)
ADD_INT
(
d
,
DB_NOPANIC
);
#endif
#if (DBVER >= 41)
ADD_INT
(
d
,
DB_OVERWRITE
);
#endif
#ifdef DB_REGISTER
ADD_INT
(
d
,
DB_REGISTER
);
#endif
...
...
@@ -5832,7 +6865,76 @@ DL_EXPORT(void) init_bsddb(void)
ADD_INT
(
d
,
DB_CHKSUM
);
#endif
#if (DBVER >= 44)
ADD_INT
(
d
,
DB_DSYNC_DB
);
#endif
#if (DBVER >= 45)
ADD_INT
(
d
,
DB_TXN_SNAPSHOT
);
#endif
#if (DBVER >= 40)
ADD_INT
(
d
,
DB_VERB_DEADLOCK
);
#if (DBVER >= 46)
ADD_INT
(
d
,
DB_VERB_FILEOPS
);
ADD_INT
(
d
,
DB_VERB_FILEOPS_ALL
);
#endif
ADD_INT
(
d
,
DB_VERB_RECOVERY
);
#if (DBVER >= 44)
ADD_INT
(
d
,
DB_VERB_REGISTER
);
#endif
ADD_INT
(
d
,
DB_VERB_REPLICATION
);
ADD_INT
(
d
,
DB_VERB_WAITSFOR
);
#endif
#if (DBVER >= 45)
ADD_INT
(
d
,
DB_EVENT_PANIC
);
ADD_INT
(
d
,
DB_EVENT_REP_CLIENT
);
#if (DBVER >= 46)
ADD_INT
(
d
,
DB_EVENT_REP_ELECTED
);
#endif
ADD_INT
(
d
,
DB_EVENT_REP_MASTER
);
ADD_INT
(
d
,
DB_EVENT_REP_NEWMASTER
);
#if (DBVER >= 46)
ADD_INT
(
d
,
DB_EVENT_REP_PERM_FAILED
);
#endif
ADD_INT
(
d
,
DB_EVENT_REP_STARTUPDONE
);
ADD_INT
(
d
,
DB_EVENT_WRITE_FAILED
);
#endif
#if (DBVER >= 40)
ADD_INT
(
d
,
DB_REP_MASTER
);
ADD_INT
(
d
,
DB_REP_CLIENT
);
#if (DBVER >= 45)
ADD_INT
(
d
,
DB_REP_ELECTION
);
ADD_INT
(
d
,
DB_REP_ACK_TIMEOUT
);
ADD_INT
(
d
,
DB_REP_CONNECTION_RETRY
);
ADD_INT
(
d
,
DB_REP_ELECTION_TIMEOUT
);
ADD_INT
(
d
,
DB_REP_ELECTION_RETRY
);
#endif
#if (DBVER >= 46)
ADD_INT
(
d
,
DB_REP_CHECKPOINT_DELAY
);
ADD_INT
(
d
,
DB_REP_FULL_ELECTION_TIMEOUT
);
#endif
#endif
#if (DBVER >= 45)
ADD_INT
(
d
,
DB_REPMGR_PEER
);
ADD_INT
(
d
,
DB_REPMGR_ACKS_ALL
);
ADD_INT
(
d
,
DB_REPMGR_ACKS_ALL_PEERS
);
ADD_INT
(
d
,
DB_REPMGR_ACKS_NONE
);
ADD_INT
(
d
,
DB_REPMGR_ACKS_ONE
);
ADD_INT
(
d
,
DB_REPMGR_ACKS_ONE_PEER
);
ADD_INT
(
d
,
DB_REPMGR_ACKS_QUORUM
);
ADD_INT
(
d
,
DB_REPMGR_CONNECTED
);
ADD_INT
(
d
,
DB_REPMGR_DISCONNECTED
);
ADD_INT
(
d
,
DB_STAT_CLEAR
);
ADD_INT
(
d
,
DB_STAT_ALL
);
#endif
#if (DBVER >= 43)
ADD_INT
(
d
,
DB_DSYNC_LOG
);
ADD_INT
(
d
,
DB_LOG_INMEMORY
);
ADD_INT
(
d
,
DB_BUFFER_SMALL
);
ADD_INT
(
d
,
DB_SEQ_DEC
);
...
...
@@ -5844,7 +6946,7 @@ DL_EXPORT(void) init_bsddb(void)
ADD_INT
(
d
,
DB_ENCRYPT_AES
);
ADD_INT
(
d
,
DB_AUTO_COMMIT
);
#else
/* allow
berkeleydb
4.1 aware apps to run on older versions */
/* allow
Berkeley DB
4.1 aware apps to run on older versions */
_addIntToDict
(
d
,
"DB_AUTO_COMMIT"
,
0
);
#endif
...
...
@@ -5920,6 +7022,10 @@ DL_EXPORT(void) init_bsddb(void)
MAKE_EX
(
DBNoSuchFileError
);
MAKE_EX
(
DBPermissionsError
);
#if (DBVER >= 42)
MAKE_EX
(
DBRepHandleDeadError
);
#endif
#undef MAKE_EX
/* Initiliase the C API structure and add it to the module */
...
...
Modules/bsddb.h
View file @
ef9764f1
...
...
@@ -36,7 +36,7 @@
/*
* Handwritten code to wrap version 3.x of the Berkeley DB library,
* written to replace a SWIG-generated file. It has since been updated
* to compile with BerkeleyDB versions 3.2 through 4.2.
* to compile with Berkeley
DB versions 3.2 through 4.2.
*
* This module was started by Andrew Kuchling to remove the dependency
* on SWIG in a package by Gregory P. Smith who based his work on a
...
...
@@ -105,7 +105,7 @@
#error "eek! DBVER can't handle minor versions > 9"
#endif
#define PY_BSDDB_VERSION "4.6.
0
"
#define PY_BSDDB_VERSION "4.6.
5devel2
"
/* Python object definitions */
...
...
@@ -119,17 +119,27 @@ struct behaviourFlags {
};
struct
DBObject
;
/* Forward declaration */
struct
DBCursorObject
;
/* Forward declaration */
struct
DBTxnObject
;
/* Forward declaration */
struct
DBSequenceObject
;
/* Forward declaration */
typedef
struct
{
PyObject_HEAD
DB_ENV
*
db_env
;
u_int32_t
flags
;
/* saved flags from open() */
int
closed
;
struct
behaviourFlags
moduleFlags
;
#if (DBVER >= 40)
PyObject
*
event_notifyCallback
;
#endif
struct
DBObject
*
children_dbs
;
struct
DBTxnObject
*
children_txns
;
PyObject
*
in_weakreflist
;
/* List of weak references */
}
DBEnvObject
;
typedef
struct
{
typedef
struct
DBObject
{
PyObject_HEAD
DB
*
db
;
DBEnvObject
*
myenvobj
;
/* PyObject containing the DB_ENV */
...
...
@@ -137,6 +147,15 @@ typedef struct {
u_int32_t
setflags
;
/* saved flags from set_flags() */
int
haveStat
;
struct
behaviourFlags
moduleFlags
;
struct
DBTxnObject
*
txn
;
struct
DBCursorObject
*
children_cursors
;
#if (DBVER >=43)
struct
DBSequenceObject
*
children_sequences
;
#endif
struct
DBObject
**
sibling_prev_p
;
struct
DBObject
*
sibling_next
;
struct
DBObject
**
sibling_prev_p_txn
;
struct
DBObject
*
sibling_next_txn
;
#if (DBVER >= 33)
PyObject
*
associateCallback
;
PyObject
*
btCompareCallback
;
...
...
@@ -146,18 +165,31 @@ typedef struct {
}
DBObject
;
typedef
struct
{
typedef
struct
DBCursorObject
{
PyObject_HEAD
DBC
*
dbc
;
struct
DBCursorObject
**
sibling_prev_p
;
struct
DBCursorObject
*
sibling_next
;
struct
DBCursorObject
**
sibling_prev_p_txn
;
struct
DBCursorObject
*
sibling_next_txn
;
DBObject
*
mydb
;
struct
DBTxnObject
*
txn
;
PyObject
*
in_weakreflist
;
/* List of weak references */
}
DBCursorObject
;
typedef
struct
{
typedef
struct
DBTxnObject
{
PyObject_HEAD
DB_TXN
*
txn
;
PyObject
*
env
;
DBEnvObject
*
env
;
int
flag_prepare
;
struct
DBTxnObject
*
parent_txn
;
struct
DBTxnObject
**
sibling_prev_p
;
struct
DBTxnObject
*
sibling_next
;
struct
DBTxnObject
*
children_txns
;
struct
DBObject
*
children_dbs
;
struct
DBSequenceObject
*
children_sequences
;
struct
DBCursorObject
*
children_cursors
;
PyObject
*
in_weakreflist
;
/* List of weak references */
}
DBTxnObject
;
...
...
@@ -170,13 +202,17 @@ typedef struct {
#if (DBVER >= 43)
typedef
struct
{
typedef
struct
DBSequenceObject
{
PyObject_HEAD
DB_SEQUENCE
*
sequence
;
DBObject
*
mydb
;
struct
DBTxnObject
*
txn
;
struct
DBSequenceObject
**
sibling_prev_p
;
struct
DBSequenceObject
*
sibling_next
;
struct
DBSequenceObject
**
sibling_prev_p_txn
;
struct
DBSequenceObject
*
sibling_next_txn
;
PyObject
*
in_weakreflist
;
/* List of weak references */
}
DBSequenceObject
;
staticforward
PyTypeObject
DBSequence_Type
;
#endif
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment