blob: dad1dcd980c8368fdbb1db02141be35b959a20ac [file] [log] [blame]
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001/*----------------------------------------------------------------------
2 Copyright (c) 1999-2001, Digital Creations, Fredericksburg, VA, USA
3 and Andrew Kuchling. All rights reserved.
4
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are
7 met:
8
9 o Redistributions of source code must retain the above copyright
10 notice, this list of conditions, and the disclaimer that follows.
11
12 o Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions, and the following disclaimer in
14 the documentation and/or other materials provided with the
15 distribution.
16
17 o Neither the name of Digital Creations nor the names of its
18 contributors may be used to endorse or promote products derived
19 from this software without specific prior written permission.
20
21 THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS AND CONTRIBUTORS *AS
22 IS* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
23 TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
24 PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL
25 CREATIONS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
28 OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
29 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
30 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
31 USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
32 DAMAGE.
33------------------------------------------------------------------------*/
34
35
36/*
37 * Handwritten code to wrap version 3.x of the Berkeley DB library,
Barry Warsaw9a0d7792002-12-30 20:53:52 +000038 * written to replace a SWIG-generated file. It has since been updated
Jesus Ceaef9764f2008-05-13 18:45:46 +000039 * to compile with Berkeley DB versions 3.2 through 4.2.
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000040 *
41 * This module was started by Andrew Kuchling to remove the dependency
Gregory P. Smithf8057852007-09-09 20:25:00 +000042 * on SWIG in a package by Gregory P. Smith who based his work on a
43 * similar package by Robin Dunn <robin@alldunn.com> which wrapped
44 * Berkeley DB 2.7.x.
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000045 *
Barry Warsaw9a0d7792002-12-30 20:53:52 +000046 * Development of this module then returned full circle back to Robin Dunn
47 * who worked on behalf of Digital Creations to complete the wrapping of
48 * the DB 3.x API and to build a solid unit test suite. Robin has
49 * since gone onto other projects (wxPython).
50 *
Jesus Ceaef9764f2008-05-13 18:45:46 +000051 * Gregory P. Smith <greg@krypto.org> was once again the maintainer.
52 *
Jesus Ceaca3939c2008-05-22 15:27:38 +000053 * Since January 2008, new maintainer is Jesus Cea <jcea@jcea.es>.
Jesus Ceaef9764f2008-05-13 18:45:46 +000054 * Jesus Cea licenses this code to PSF under a Contributor Agreement.
Barry Warsaw9a0d7792002-12-30 20:53:52 +000055 *
56 * Use the pybsddb-users@lists.sf.net mailing list for all questions.
Barry Warsawc74e4a52003-04-24 14:28:08 +000057 * Things can change faster than the header of this file is updated. This
58 * file is shared with the PyBSDDB project at SourceForge:
59 *
60 * http://pybsddb.sf.net
61 *
62 * This file should remain backward compatible with Python 2.1, but see PEP
63 * 291 for the most current backward compatibility requirements:
64 *
65 * http://www.python.org/peps/pep-0291.html
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000066 *
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070067 * This module contains 7 types:
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000068 *
69 * DB (Database)
70 * DBCursor (Database Cursor)
71 * DBEnv (database environment)
72 * DBTxn (An explicit database transaction)
73 * DBLock (A lock handle)
Gregory P. Smithf0547d02006-06-05 17:38:04 +000074 * DBSequence (Sequence)
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070075 * DBSite (Site)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000076 *
Jesus Cea6557aac2010-03-22 14:22:26 +000077 * More datatypes added:
78 *
79 * DBLogCursor (Log Cursor)
80 *
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000081 */
82
83/* --------------------------------------------------------------------- */
84
85/*
86 * Portions of this module, associated unit tests and build scripts are the
87 * result of a contract with The Written Word (http://thewrittenword.com/)
88 * Many thanks go out to them for causing me to raise the bar on quality and
89 * functionality, resulting in a better bsddb3 package for all of us to use.
90 *
91 * --Robin
92 */
93
94/* --------------------------------------------------------------------- */
95
Gregory P. Smitha703a212003-11-03 01:04:41 +000096#include <stddef.h> /* for offsetof() */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000097#include <Python.h>
Gregory P. Smith39250532007-10-09 06:02:21 +000098
99#define COMPILING_BSDDB_C
100#include "bsddb.h"
101#undef COMPILING_BSDDB_C
102
103static char *rcs_id = "$Id$";
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000104
105/* --------------------------------------------------------------------- */
106/* Various macro definitions */
107
Gregory P. Smith7f5b6f42006-04-08 07:10:51 +0000108#if (PY_VERSION_HEX < 0x02050000)
Neal Norwitz09a29fa2006-06-12 02:05:55 +0000109typedef int Py_ssize_t;
Gregory P. Smith7f5b6f42006-04-08 07:10:51 +0000110#endif
111
Gregory P. Smith572226c2008-05-26 19:03:35 +0000112#if (PY_VERSION_HEX < 0x02060000) /* really: before python trunk r63675 */
113/* This code now uses PyBytes* API function names instead of PyString*.
114 * These #defines map to their equivalent on earlier python versions. */
115#define PyBytes_FromStringAndSize PyString_FromStringAndSize
116#define PyBytes_FromString PyString_FromString
117#define PyBytes_AsStringAndSize PyString_AsStringAndSize
118#define PyBytes_Check PyString_Check
119#define PyBytes_GET_SIZE PyString_GET_SIZE
120#define PyBytes_AS_STRING PyString_AS_STRING
121#endif
122
Jesus Ceac5a11fa2008-07-23 11:38:42 +0000123#if (PY_VERSION_HEX >= 0x03000000)
124#define NUMBER_Check PyLong_Check
125#define NUMBER_AsLong PyLong_AsLong
126#define NUMBER_FromLong PyLong_FromLong
127#else
128#define NUMBER_Check PyInt_Check
129#define NUMBER_AsLong PyInt_AsLong
130#define NUMBER_FromLong PyInt_FromLong
131#endif
132
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000133#ifdef WITH_THREAD
134
135/* These are for when calling Python --> C */
136#define MYDB_BEGIN_ALLOW_THREADS Py_BEGIN_ALLOW_THREADS;
137#define MYDB_END_ALLOW_THREADS Py_END_ALLOW_THREADS;
138
139/* and these are for calling C --> Python */
Mark Hammonda69d4092003-04-22 23:13:27 +0000140#define MYDB_BEGIN_BLOCK_THREADS \
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000141 PyGILState_STATE __savestate = PyGILState_Ensure();
Mark Hammonda69d4092003-04-22 23:13:27 +0000142#define MYDB_END_BLOCK_THREADS \
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000143 PyGILState_Release(__savestate);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000144
145#else
Mark Hammonda69d4092003-04-22 23:13:27 +0000146/* Compiled without threads - avoid all this cruft */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000147#define MYDB_BEGIN_ALLOW_THREADS
148#define MYDB_END_ALLOW_THREADS
149#define MYDB_BEGIN_BLOCK_THREADS
150#define MYDB_END_BLOCK_THREADS
151
152#endif
153
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000154/* --------------------------------------------------------------------- */
155/* Exceptions */
156
157static PyObject* DBError; /* Base class, all others derive from this */
Gregory P. Smithe2767172003-11-02 08:06:29 +0000158static PyObject* DBCursorClosedError; /* raised when trying to use a closed cursor object */
Gregory P. Smithe9477062005-06-04 06:46:59 +0000159static PyObject* DBKeyEmptyError; /* DB_KEYEMPTY: also derives from KeyError */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000160static PyObject* DBKeyExistError; /* DB_KEYEXIST */
161static PyObject* DBLockDeadlockError; /* DB_LOCK_DEADLOCK */
162static PyObject* DBLockNotGrantedError; /* DB_LOCK_NOTGRANTED */
163static PyObject* DBNotFoundError; /* DB_NOTFOUND: also derives from KeyError */
164static PyObject* DBOldVersionError; /* DB_OLD_VERSION */
165static PyObject* DBRunRecoveryError; /* DB_RUNRECOVERY */
166static PyObject* DBVerifyBadError; /* DB_VERIFY_BAD */
167static PyObject* DBNoServerError; /* DB_NOSERVER */
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -0700168#if (DBVER < 52)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000169static PyObject* DBNoServerHomeError; /* DB_NOSERVER_HOME */
170static PyObject* DBNoServerIDError; /* DB_NOSERVER_ID */
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -0700171#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000172static PyObject* DBPageNotFoundError; /* DB_PAGE_NOTFOUND */
173static PyObject* DBSecondaryBadError; /* DB_SECONDARY_BAD */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000174
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000175static PyObject* DBInvalidArgError; /* EINVAL */
176static PyObject* DBAccessError; /* EACCES */
177static PyObject* DBNoSpaceError; /* ENOSPC */
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -0700178static PyObject* DBNoMemoryError; /* DB_BUFFER_SMALL */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000179static PyObject* DBAgainError; /* EAGAIN */
180static PyObject* DBBusyError; /* EBUSY */
181static PyObject* DBFileExistsError; /* EEXIST */
182static PyObject* DBNoSuchFileError; /* ENOENT */
183static PyObject* DBPermissionsError; /* EPERM */
184
Jesus Ceaef9764f2008-05-13 18:45:46 +0000185static PyObject* DBRepHandleDeadError; /* DB_REP_HANDLE_DEAD */
Jesus Cea6557aac2010-03-22 14:22:26 +0000186#if (DBVER >= 44)
187static PyObject* DBRepLockoutError; /* DB_REP_LOCKOUT */
188#endif
189
190#if (DBVER >= 46)
191static PyObject* DBRepLeaseExpiredError; /* DB_REP_LEASE_EXPIRED */
192#endif
193
194#if (DBVER >= 47)
195static PyObject* DBForeignConflictError; /* DB_FOREIGN_CONFLICT */
196#endif
197
Jesus Ceaef9764f2008-05-13 18:45:46 +0000198
Jesus Ceac5a11fa2008-07-23 11:38:42 +0000199static PyObject* DBRepUnavailError; /* DB_REP_UNAVAIL */
200
Matthias Klose54cc5392010-03-15 12:46:18 +0000201#if (DBVER < 48)
202#define DB_GID_SIZE DB_XIDDATASIZE
203#endif
204
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000205
206/* --------------------------------------------------------------------- */
207/* Structure definitions */
208
Gregory P. Smith39250532007-10-09 06:02:21 +0000209#if PYTHON_API_VERSION < 1010
210#error "Python 2.1 or later required"
Gregory P. Smitha703a212003-11-03 01:04:41 +0000211#endif
212
Gregory P. Smith31c50652004-06-28 01:20:40 +0000213
Gregory P. Smith39250532007-10-09 06:02:21 +0000214/* Defaults for moduleFlags in DBEnvObject and DBObject. */
Gregory P. Smith455d46f2003-07-09 04:45:59 +0000215#define DEFAULT_GET_RETURNS_NONE 1
Gregory P. Smitha703a212003-11-03 01:04:41 +0000216#define DEFAULT_CURSOR_SET_RETURNS_NONE 1 /* 0 in pybsddb < 4.2, python < 2.4 */
Gregory P. Smith455d46f2003-07-09 04:45:59 +0000217
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000218
Jesus Ceac5a11fa2008-07-23 11:38:42 +0000219/* See comment in Python 2.6 "object.h" */
220#ifndef staticforward
221#define staticforward static
222#endif
223#ifndef statichere
224#define statichere static
225#endif
226
227staticforward PyTypeObject DB_Type, DBCursor_Type, DBEnv_Type, DBTxn_Type,
Jesus Cea6557aac2010-03-22 14:22:26 +0000228 DBLock_Type, DBLogCursor_Type;
Jesus Ceaef9764f2008-05-13 18:45:46 +0000229staticforward PyTypeObject DBSequence_Type;
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -0700230#if (DBVER >= 52)
231staticforward PyTypeObject DBSite_Type;
Jesus Ceaef9764f2008-05-13 18:45:46 +0000232#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000233
Martin v. Löwis83c92012008-04-24 13:17:24 +0000234#ifndef Py_TYPE
Gregory P. Smithfc006692007-11-05 09:06:28 +0000235/* for compatibility with Python 2.5 and earlier */
Christian Heimese93237d2007-12-19 02:37:44 +0000236#define Py_TYPE(ob) (((PyObject*)(ob))->ob_type)
Gregory P. Smithfc006692007-11-05 09:06:28 +0000237#endif
238
Christian Heimese93237d2007-12-19 02:37:44 +0000239#define DBObject_Check(v) (Py_TYPE(v) == &DB_Type)
240#define DBCursorObject_Check(v) (Py_TYPE(v) == &DBCursor_Type)
Jesus Cea6557aac2010-03-22 14:22:26 +0000241#define DBLogCursorObject_Check(v) (Py_TYPE(v) == &DBLogCursor_Type)
Christian Heimese93237d2007-12-19 02:37:44 +0000242#define DBEnvObject_Check(v) (Py_TYPE(v) == &DBEnv_Type)
243#define DBTxnObject_Check(v) (Py_TYPE(v) == &DBTxn_Type)
244#define DBLockObject_Check(v) (Py_TYPE(v) == &DBLock_Type)
Christian Heimese93237d2007-12-19 02:37:44 +0000245#define DBSequenceObject_Check(v) (Py_TYPE(v) == &DBSequence_Type)
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -0700246#if (DBVER >= 52)
247#define DBSiteObject_Check(v) (Py_TYPE(v) == &DBSite_Type)
Gregory P. Smithf0547d02006-06-05 17:38:04 +0000248#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000249
Jesus Ceaef9764f2008-05-13 18:45:46 +0000250#if (DBVER < 46)
251 #define _DBC_close(dbc) dbc->c_close(dbc)
252 #define _DBC_count(dbc,a,b) dbc->c_count(dbc,a,b)
253 #define _DBC_del(dbc,a) dbc->c_del(dbc,a)
254 #define _DBC_dup(dbc,a,b) dbc->c_dup(dbc,a,b)
255 #define _DBC_get(dbc,a,b,c) dbc->c_get(dbc,a,b,c)
256 #define _DBC_pget(dbc,a,b,c,d) dbc->c_pget(dbc,a,b,c,d)
257 #define _DBC_put(dbc,a,b,c) dbc->c_put(dbc,a,b,c)
258#else
259 #define _DBC_close(dbc) dbc->close(dbc)
260 #define _DBC_count(dbc,a,b) dbc->count(dbc,a,b)
261 #define _DBC_del(dbc,a) dbc->del(dbc,a)
262 #define _DBC_dup(dbc,a,b) dbc->dup(dbc,a,b)
263 #define _DBC_get(dbc,a,b,c) dbc->get(dbc,a,b,c)
264 #define _DBC_pget(dbc,a,b,c,d) dbc->pget(dbc,a,b,c,d)
265 #define _DBC_put(dbc,a,b,c) dbc->put(dbc,a,b,c)
266#endif
267
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000268
269/* --------------------------------------------------------------------- */
270/* Utility macros and functions */
271
Jesus Ceaef9764f2008-05-13 18:45:46 +0000272#define INSERT_IN_DOUBLE_LINKED_LIST(backlink,object) \
273 { \
274 object->sibling_next=backlink; \
275 object->sibling_prev_p=&(backlink); \
276 backlink=object; \
277 if (object->sibling_next) { \
278 object->sibling_next->sibling_prev_p=&(object->sibling_next); \
279 } \
280 }
281
282#define EXTRACT_FROM_DOUBLE_LINKED_LIST(object) \
283 { \
284 if (object->sibling_next) { \
285 object->sibling_next->sibling_prev_p=object->sibling_prev_p; \
286 } \
287 *(object->sibling_prev_p)=object->sibling_next; \
288 }
289
290#define EXTRACT_FROM_DOUBLE_LINKED_LIST_MAYBE_NULL(object) \
291 { \
292 if (object->sibling_next) { \
293 object->sibling_next->sibling_prev_p=object->sibling_prev_p; \
294 } \
295 if (object->sibling_prev_p) { \
296 *(object->sibling_prev_p)=object->sibling_next; \
297 } \
298 }
299
300#define INSERT_IN_DOUBLE_LINKED_LIST_TXN(backlink,object) \
301 { \
302 object->sibling_next_txn=backlink; \
303 object->sibling_prev_p_txn=&(backlink); \
304 backlink=object; \
305 if (object->sibling_next_txn) { \
306 object->sibling_next_txn->sibling_prev_p_txn= \
307 &(object->sibling_next_txn); \
308 } \
309 }
310
311#define EXTRACT_FROM_DOUBLE_LINKED_LIST_TXN(object) \
312 { \
313 if (object->sibling_next_txn) { \
314 object->sibling_next_txn->sibling_prev_p_txn= \
315 object->sibling_prev_p_txn; \
316 } \
317 *(object->sibling_prev_p_txn)=object->sibling_next_txn; \
318 }
319
320
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000321#define RETURN_IF_ERR() \
322 if (makeDBError(err)) { \
323 return NULL; \
324 }
325
326#define RETURN_NONE() Py_INCREF(Py_None); return Py_None;
327
Gregory P. Smithe2767172003-11-02 08:06:29 +0000328#define _CHECK_OBJECT_NOT_CLOSED(nonNull, pyErrObj, name) \
329 if ((nonNull) == NULL) { \
330 PyObject *errTuple = NULL; \
331 errTuple = Py_BuildValue("(is)", 0, #name " object has been closed"); \
Jesus Ceac5a11fa2008-07-23 11:38:42 +0000332 if (errTuple) { \
333 PyErr_SetObject((pyErrObj), errTuple); \
334 Py_DECREF(errTuple); \
335 } \
Gregory P. Smithe2767172003-11-02 08:06:29 +0000336 return NULL; \
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000337 }
338
Gregory P. Smithe2767172003-11-02 08:06:29 +0000339#define CHECK_DB_NOT_CLOSED(dbobj) \
340 _CHECK_OBJECT_NOT_CLOSED(dbobj->db, DBError, DB)
341
342#define CHECK_ENV_NOT_CLOSED(env) \
343 _CHECK_OBJECT_NOT_CLOSED(env->db_env, DBError, DBEnv)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000344
345#define CHECK_CURSOR_NOT_CLOSED(curs) \
Gregory P. Smithe2767172003-11-02 08:06:29 +0000346 _CHECK_OBJECT_NOT_CLOSED(curs->dbc, DBCursorClosedError, DBCursor)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000347
Jesus Cea6557aac2010-03-22 14:22:26 +0000348#define CHECK_LOGCURSOR_NOT_CLOSED(logcurs) \
349 _CHECK_OBJECT_NOT_CLOSED(logcurs->logc, DBCursorClosedError, DBLogCursor)
350
Gregory P. Smithf0547d02006-06-05 17:38:04 +0000351#define CHECK_SEQUENCE_NOT_CLOSED(curs) \
352 _CHECK_OBJECT_NOT_CLOSED(curs->sequence, DBError, DBSequence)
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -0700353
354#if (DBVER >= 52)
355#define CHECK_SITE_NOT_CLOSED(db_site) \
356 _CHECK_OBJECT_NOT_CLOSED(db_site->site, DBError, DBSite)
Gregory P. Smithf0547d02006-06-05 17:38:04 +0000357#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000358
359#define CHECK_DBFLAG(mydb, flag) (((mydb)->flags & (flag)) || \
360 (((mydb)->myenvobj != NULL) && ((mydb)->myenvobj->flags & (flag))))
361
362#define CLEAR_DBT(dbt) (memset(&(dbt), 0, sizeof(dbt)))
363
364#define FREE_DBT(dbt) if ((dbt.flags & (DB_DBT_MALLOC|DB_DBT_REALLOC)) && \
Gregory P. Smithdc5af702004-06-27 23:32:34 +0000365 dbt.data != NULL) { free(dbt.data); dbt.data = NULL; }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000366
367
368static int makeDBError(int err);
369
370
371/* Return the access method type of the DBObject */
372static int _DB_get_type(DBObject* self)
373{
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000374 DBTYPE type;
375 int err;
Jesus Ceac5a11fa2008-07-23 11:38:42 +0000376
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000377 err = self->db->get_type(self->db, &type);
378 if (makeDBError(err)) {
379 return -1;
380 }
381 return type;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000382}
383
384
385/* Create a DBT structure (containing key and data values) from Python
386 strings. Returns 1 on success, 0 on an error. */
387static int make_dbt(PyObject* obj, DBT* dbt)
388{
389 CLEAR_DBT(*dbt);
390 if (obj == Py_None) {
391 /* no need to do anything, the structure has already been zeroed */
392 }
393 else if (!PyArg_Parse(obj, "s#", &dbt->data, &dbt->size)) {
394 PyErr_SetString(PyExc_TypeError,
Jesus Cea4907d272008-08-31 14:00:51 +0000395#if (PY_VERSION_HEX < 0x03000000)
Gregory P. Smithdc5af702004-06-27 23:32:34 +0000396 "Data values must be of type string or None.");
Jesus Cea4907d272008-08-31 14:00:51 +0000397#else
398 "Data values must be of type bytes or None.");
399#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000400 return 0;
401 }
402 return 1;
403}
404
405
406/* Recno and Queue DBs can have integer keys. This function figures out
407 what's been given, verifies that it's allowed, and then makes the DBT.
408
Gregory P. Smithdc5af702004-06-27 23:32:34 +0000409 Caller MUST call FREE_DBT(key) when done. */
Barry Warsaw9a0d7792002-12-30 20:53:52 +0000410static int
411make_key_dbt(DBObject* self, PyObject* keyobj, DBT* key, int* pflags)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000412{
413 db_recno_t recno;
414 int type;
415
416 CLEAR_DBT(*key);
Gustavo Niemeyerf073b752004-01-20 15:24:29 +0000417 if (keyobj == Py_None) {
Gustavo Niemeyer024f2de2004-01-20 15:14:55 +0000418 type = _DB_get_type(self);
Gustavo Niemeyer8974f722004-01-20 15:20:03 +0000419 if (type == -1)
420 return 0;
Gustavo Niemeyer024f2de2004-01-20 15:14:55 +0000421 if (type == DB_RECNO || type == DB_QUEUE) {
422 PyErr_SetString(
423 PyExc_TypeError,
424 "None keys not allowed for Recno and Queue DB's");
425 return 0;
426 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000427 /* no need to do anything, the structure has already been zeroed */
428 }
429
Christian Heimes593daf52008-05-26 12:51:38 +0000430 else if (PyBytes_Check(keyobj)) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000431 /* verify access method type */
432 type = _DB_get_type(self);
433 if (type == -1)
434 return 0;
435 if (type == DB_RECNO || type == DB_QUEUE) {
Barry Warsaw9a0d7792002-12-30 20:53:52 +0000436 PyErr_SetString(
437 PyExc_TypeError,
Jesus Cea4907d272008-08-31 14:00:51 +0000438#if (PY_VERSION_HEX < 0x03000000)
Barry Warsaw9a0d7792002-12-30 20:53:52 +0000439 "String keys not allowed for Recno and Queue DB's");
Jesus Cea4907d272008-08-31 14:00:51 +0000440#else
441 "Bytes keys not allowed for Recno and Queue DB's");
442#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000443 return 0;
444 }
445
Gregory P. Smith10bed542007-10-09 06:50:43 +0000446 /*
447 * NOTE(gps): I don't like doing a data copy here, it seems
448 * wasteful. But without a clean way to tell FREE_DBT if it
449 * should free key->data or not we have to. Other places in
450 * the code check for DB_THREAD and forceably set DBT_MALLOC
451 * when we otherwise would leave flags 0 to indicate that.
452 */
Christian Heimes593daf52008-05-26 12:51:38 +0000453 key->data = malloc(PyBytes_GET_SIZE(keyobj));
Gregory P. Smith10bed542007-10-09 06:50:43 +0000454 if (key->data == NULL) {
455 PyErr_SetString(PyExc_MemoryError, "Key memory allocation failed");
456 return 0;
457 }
Christian Heimes593daf52008-05-26 12:51:38 +0000458 memcpy(key->data, PyBytes_AS_STRING(keyobj),
459 PyBytes_GET_SIZE(keyobj));
Gregory P. Smith10bed542007-10-09 06:50:43 +0000460 key->flags = DB_DBT_REALLOC;
Christian Heimes593daf52008-05-26 12:51:38 +0000461 key->size = PyBytes_GET_SIZE(keyobj);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000462 }
463
Jesus Ceac5a11fa2008-07-23 11:38:42 +0000464 else if (NUMBER_Check(keyobj)) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000465 /* verify access method type */
466 type = _DB_get_type(self);
467 if (type == -1)
468 return 0;
469 if (type == DB_BTREE && pflags != NULL) {
Barry Warsaw9a0d7792002-12-30 20:53:52 +0000470 /* if BTREE then an Integer key is allowed with the
471 * DB_SET_RECNO flag */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000472 *pflags |= DB_SET_RECNO;
473 }
474 else if (type != DB_RECNO && type != DB_QUEUE) {
Barry Warsaw9a0d7792002-12-30 20:53:52 +0000475 PyErr_SetString(
476 PyExc_TypeError,
477 "Integer keys only allowed for Recno and Queue DB's");
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000478 return 0;
479 }
480
Barry Warsaw9a0d7792002-12-30 20:53:52 +0000481 /* Make a key out of the requested recno, use allocated space so DB
482 * will be able to realloc room for the real key if needed. */
Jesus Ceac5a11fa2008-07-23 11:38:42 +0000483 recno = NUMBER_AsLong(keyobj);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000484 key->data = malloc(sizeof(db_recno_t));
485 if (key->data == NULL) {
486 PyErr_SetString(PyExc_MemoryError, "Key memory allocation failed");
487 return 0;
488 }
489 key->ulen = key->size = sizeof(db_recno_t);
490 memcpy(key->data, &recno, sizeof(db_recno_t));
491 key->flags = DB_DBT_REALLOC;
492 }
493 else {
494 PyErr_Format(PyExc_TypeError,
Jesus Cea4907d272008-08-31 14:00:51 +0000495#if (PY_VERSION_HEX < 0x03000000)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000496 "String or Integer object expected for key, %s found",
Jesus Cea4907d272008-08-31 14:00:51 +0000497#else
498 "Bytes or Integer object expected for key, %s found",
499#endif
Christian Heimese93237d2007-12-19 02:37:44 +0000500 Py_TYPE(keyobj)->tp_name);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000501 return 0;
502 }
503
504 return 1;
505}
506
507
508/* Add partial record access to an existing DBT data struct.
509 If dlen and doff are set, then the DB_DBT_PARTIAL flag will be set
510 and the data storage/retrieval will be done using dlen and doff. */
511static int add_partial_dbt(DBT* d, int dlen, int doff) {
512 /* if neither were set we do nothing (-1 is the default value) */
513 if ((dlen == -1) && (doff == -1)) {
514 return 1;
515 }
516
517 if ((dlen < 0) || (doff < 0)) {
518 PyErr_SetString(PyExc_TypeError, "dlen and doff must both be >= 0");
519 return 0;
520 }
521
522 d->flags = d->flags | DB_DBT_PARTIAL;
523 d->dlen = (unsigned int) dlen;
524 d->doff = (unsigned int) doff;
525 return 1;
526}
527
Gregory P. Smith8b7e9172004-12-13 09:51:23 +0000528/* a safe strcpy() without the zeroing behaviour and semantics of strncpy. */
529/* TODO: make this use the native libc strlcpy() when available (BSD) */
530unsigned int our_strlcpy(char* dest, const char* src, unsigned int n)
531{
532 unsigned int srclen, copylen;
533
534 srclen = strlen(src);
535 if (n <= 0)
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000536 return srclen;
Gregory P. Smith8b7e9172004-12-13 09:51:23 +0000537 copylen = (srclen > n-1) ? n-1 : srclen;
538 /* populate dest[0] thru dest[copylen-1] */
539 memcpy(dest, src, copylen);
540 /* guarantee null termination */
541 dest[copylen] = 0;
542
543 return srclen;
544}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000545
Barry Warsaw9a0d7792002-12-30 20:53:52 +0000546/* Callback used to save away more information about errors from the DB
547 * library. */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000548static char _db_errmsg[1024];
Gregory P. Smith8b7e9172004-12-13 09:51:23 +0000549static void _db_errorCallback(const DB_ENV *db_env,
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000550 const char* prefix, const char* msg)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000551{
Gregory P. Smith8b7e9172004-12-13 09:51:23 +0000552 our_strlcpy(_db_errmsg, msg, sizeof(_db_errmsg));
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000553}
554
555
Jesus Ceaef9764f2008-05-13 18:45:46 +0000556/*
557** We need these functions because some results
558** are undefined if pointer is NULL. Some other
559** give None instead of "".
560**
561** This functions are static and will be
562** -I hope- inlined.
563*/
564static const char *DummyString = "This string is a simple placeholder";
565static PyObject *Build_PyString(const char *p,int s)
566{
567 if (!p) {
568 p=DummyString;
569 assert(s==0);
570 }
Christian Heimes593daf52008-05-26 12:51:38 +0000571 return PyBytes_FromStringAndSize(p,s);
Jesus Ceaef9764f2008-05-13 18:45:46 +0000572}
573
574static PyObject *BuildValue_S(const void *p,int s)
575{
576 if (!p) {
577 p=DummyString;
578 assert(s==0);
579 }
Jesus Cea4907d272008-08-31 14:00:51 +0000580 return PyBytes_FromStringAndSize(p, s);
Jesus Ceaef9764f2008-05-13 18:45:46 +0000581}
582
583static PyObject *BuildValue_SS(const void *p1,int s1,const void *p2,int s2)
584{
Jesus Cea4907d272008-08-31 14:00:51 +0000585PyObject *a, *b, *r;
586
Jesus Ceaef9764f2008-05-13 18:45:46 +0000587 if (!p1) {
588 p1=DummyString;
589 assert(s1==0);
590 }
591 if (!p2) {
592 p2=DummyString;
593 assert(s2==0);
594 }
Jesus Cea4907d272008-08-31 14:00:51 +0000595
596 if (!(a = PyBytes_FromStringAndSize(p1, s1))) {
597 return NULL;
598 }
599 if (!(b = PyBytes_FromStringAndSize(p2, s2))) {
600 Py_DECREF(a);
601 return NULL;
602 }
603
Jesus Cea4907d272008-08-31 14:00:51 +0000604 r = PyTuple_Pack(2, a, b) ;
Jesus Cea4907d272008-08-31 14:00:51 +0000605 Py_DECREF(a);
606 Py_DECREF(b);
607 return r;
Jesus Ceaef9764f2008-05-13 18:45:46 +0000608}
609
610static PyObject *BuildValue_IS(int i,const void *p,int s)
611{
Jesus Cea4907d272008-08-31 14:00:51 +0000612 PyObject *a, *r;
613
Jesus Ceaef9764f2008-05-13 18:45:46 +0000614 if (!p) {
615 p=DummyString;
616 assert(s==0);
617 }
Jesus Cea4907d272008-08-31 14:00:51 +0000618
619 if (!(a = PyBytes_FromStringAndSize(p, s))) {
620 return NULL;
621 }
622
623 r = Py_BuildValue("iO", i, a);
624 Py_DECREF(a);
625 return r;
Jesus Ceaef9764f2008-05-13 18:45:46 +0000626}
627
Jesus Cea4907d272008-08-31 14:00:51 +0000628static PyObject *BuildValue_LS(long l,const void *p,int s)
Jesus Ceaef9764f2008-05-13 18:45:46 +0000629{
Jesus Cea4907d272008-08-31 14:00:51 +0000630 PyObject *a, *r;
631
Jesus Ceaef9764f2008-05-13 18:45:46 +0000632 if (!p) {
633 p=DummyString;
634 assert(s==0);
635 }
Jesus Cea4907d272008-08-31 14:00:51 +0000636
637 if (!(a = PyBytes_FromStringAndSize(p, s))) {
638 return NULL;
639 }
640
641 r = Py_BuildValue("lO", l, a);
642 Py_DECREF(a);
643 return r;
Jesus Ceaef9764f2008-05-13 18:45:46 +0000644}
645
646
647
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000648/* make a nice exception object to raise for errors. */
649static int makeDBError(int err)
650{
651 char errTxt[2048]; /* really big, just in case... */
Barry Warsaw9a0d7792002-12-30 20:53:52 +0000652 PyObject *errObj = NULL;
653 PyObject *errTuple = NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000654 int exceptionRaised = 0;
Neal Norwitzdce937f2006-07-23 08:01:43 +0000655 unsigned int bytes_left;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000656
657 switch (err) {
Jesus Cea6557aac2010-03-22 14:22:26 +0000658 case 0: /* successful, no error */
659 return 0;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000660
661 case DB_KEYEMPTY: errObj = DBKeyEmptyError; break;
662 case DB_KEYEXIST: errObj = DBKeyExistError; break;
663 case DB_LOCK_DEADLOCK: errObj = DBLockDeadlockError; break;
664 case DB_LOCK_NOTGRANTED: errObj = DBLockNotGrantedError; break;
665 case DB_NOTFOUND: errObj = DBNotFoundError; break;
666 case DB_OLD_VERSION: errObj = DBOldVersionError; break;
667 case DB_RUNRECOVERY: errObj = DBRunRecoveryError; break;
668 case DB_VERIFY_BAD: errObj = DBVerifyBadError; break;
669 case DB_NOSERVER: errObj = DBNoServerError; break;
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -0700670#if (DBVER < 52)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000671 case DB_NOSERVER_HOME: errObj = DBNoServerHomeError; break;
672 case DB_NOSERVER_ID: errObj = DBNoServerIDError; break;
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -0700673#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000674 case DB_PAGE_NOTFOUND: errObj = DBPageNotFoundError; break;
675 case DB_SECONDARY_BAD: errObj = DBSecondaryBadError; break;
Gregory P. Smith8b7e9172004-12-13 09:51:23 +0000676 case DB_BUFFER_SMALL: errObj = DBNoMemoryError; break;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000677
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000678 case ENOMEM: errObj = PyExc_MemoryError; break;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000679 case EINVAL: errObj = DBInvalidArgError; break;
680 case EACCES: errObj = DBAccessError; break;
681 case ENOSPC: errObj = DBNoSpaceError; break;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000682 case EAGAIN: errObj = DBAgainError; break;
683 case EBUSY : errObj = DBBusyError; break;
684 case EEXIST: errObj = DBFileExistsError; break;
685 case ENOENT: errObj = DBNoSuchFileError; break;
686 case EPERM : errObj = DBPermissionsError; break;
687
Jesus Ceaef9764f2008-05-13 18:45:46 +0000688 case DB_REP_HANDLE_DEAD : errObj = DBRepHandleDeadError; break;
Jesus Cea6557aac2010-03-22 14:22:26 +0000689#if (DBVER >= 44)
690 case DB_REP_LOCKOUT : errObj = DBRepLockoutError; break;
691#endif
692
693#if (DBVER >= 46)
694 case DB_REP_LEASE_EXPIRED : errObj = DBRepLeaseExpiredError; break;
695#endif
696
697#if (DBVER >= 47)
698 case DB_FOREIGN_CONFLICT : errObj = DBForeignConflictError; break;
699#endif
Jesus Ceaef9764f2008-05-13 18:45:46 +0000700
Jesus Ceac5a11fa2008-07-23 11:38:42 +0000701 case DB_REP_UNAVAIL : errObj = DBRepUnavailError; break;
702
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000703 default: errObj = DBError; break;
704 }
705
706 if (errObj != NULL) {
Neal Norwitzdce937f2006-07-23 08:01:43 +0000707 bytes_left = our_strlcpy(errTxt, db_strerror(err), sizeof(errTxt));
708 /* Ensure that bytes_left never goes negative */
709 if (_db_errmsg[0] && bytes_left < (sizeof(errTxt) - 4)) {
710 bytes_left = sizeof(errTxt) - bytes_left - 4 - 1;
711 assert(bytes_left >= 0);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000712 strcat(errTxt, " -- ");
Neal Norwitzdce937f2006-07-23 08:01:43 +0000713 strncat(errTxt, _db_errmsg, bytes_left);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000714 }
Neal Norwitzdce937f2006-07-23 08:01:43 +0000715 _db_errmsg[0] = 0;
Barry Warsaw9a0d7792002-12-30 20:53:52 +0000716
Jesus Ceac5a11fa2008-07-23 11:38:42 +0000717 errTuple = Py_BuildValue("(is)", err, errTxt);
718 if (errTuple == NULL) {
719 Py_DECREF(errObj);
720 return !0;
721 }
Barry Warsaw9a0d7792002-12-30 20:53:52 +0000722 PyErr_SetObject(errObj, errTuple);
Jesus Ceac5a11fa2008-07-23 11:38:42 +0000723 Py_DECREF(errTuple);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000724 }
725
726 return ((errObj != NULL) || exceptionRaised);
727}
728
729
730
731/* set a type exception */
732static void makeTypeError(char* expected, PyObject* found)
733{
734 PyErr_Format(PyExc_TypeError, "Expected %s argument, %s found.",
Christian Heimese93237d2007-12-19 02:37:44 +0000735 expected, Py_TYPE(found)->tp_name);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000736}
737
738
739/* verify that an obj is either None or a DBTxn, and set the txn pointer */
740static int checkTxnObj(PyObject* txnobj, DB_TXN** txn)
741{
742 if (txnobj == Py_None || txnobj == NULL) {
743 *txn = NULL;
744 return 1;
745 }
746 if (DBTxnObject_Check(txnobj)) {
747 *txn = ((DBTxnObject*)txnobj)->txn;
748 return 1;
749 }
750 else
751 makeTypeError("DBTxn", txnobj);
752 return 0;
753}
754
755
756/* Delete a key from a database
757 Returns 0 on success, -1 on an error. */
758static int _DB_delete(DBObject* self, DB_TXN *txn, DBT *key, int flags)
759{
760 int err;
761
762 MYDB_BEGIN_ALLOW_THREADS;
763 err = self->db->del(self->db, txn, key, 0);
764 MYDB_END_ALLOW_THREADS;
765 if (makeDBError(err)) {
766 return -1;
767 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000768 return 0;
769}
770
771
772/* Store a key into a database
773 Returns 0 on success, -1 on an error. */
774static int _DB_put(DBObject* self, DB_TXN *txn, DBT *key, DBT *data, int flags)
775{
776 int err;
777
778 MYDB_BEGIN_ALLOW_THREADS;
779 err = self->db->put(self->db, txn, key, data, flags);
780 MYDB_END_ALLOW_THREADS;
781 if (makeDBError(err)) {
782 return -1;
783 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000784 return 0;
785}
786
787/* Get a key/data pair from a cursor */
788static PyObject* _DBCursor_get(DBCursorObject* self, int extra_flags,
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000789 PyObject *args, PyObject *kwargs, char *format)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000790{
791 int err;
792 PyObject* retval = NULL;
793 DBT key, data;
794 int dlen = -1;
795 int doff = -1;
796 int flags = 0;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +0000797 static char* kwnames[] = { "flags", "dlen", "doff", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000798
799 if (!PyArg_ParseTupleAndKeywords(args, kwargs, format, kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000800 &flags, &dlen, &doff))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000801 return NULL;
802
803 CHECK_CURSOR_NOT_CLOSED(self);
804
805 flags |= extra_flags;
806 CLEAR_DBT(key);
807 CLEAR_DBT(data);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000808 if (!add_partial_dbt(&data, dlen, doff))
809 return NULL;
810
811 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +0000812 err = _DBC_get(self->dbc, &key, &data, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000813 MYDB_END_ALLOW_THREADS;
814
Gregory P. Smithe9477062005-06-04 06:46:59 +0000815 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000816 && self->mydb->moduleFlags.getReturnsNone) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000817 Py_INCREF(Py_None);
818 retval = Py_None;
819 }
820 else if (makeDBError(err)) {
821 retval = NULL;
822 }
823 else { /* otherwise, success! */
824
825 /* if Recno or Queue, return the key as an Int */
826 switch (_DB_get_type(self->mydb)) {
827 case -1:
828 retval = NULL;
829 break;
830
831 case DB_RECNO:
832 case DB_QUEUE:
Jesus Ceaef9764f2008-05-13 18:45:46 +0000833 retval = BuildValue_IS(*((db_recno_t*)key.data), data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000834 break;
835 case DB_HASH:
836 case DB_BTREE:
837 default:
Jesus Ceaef9764f2008-05-13 18:45:46 +0000838 retval = BuildValue_SS(key.data, key.size, data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000839 break;
840 }
841 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000842 return retval;
843}
844
845
846/* add an integer to a dictionary using the given name as a key */
847static void _addIntToDict(PyObject* dict, char *name, int value)
848{
Jesus Ceac5a11fa2008-07-23 11:38:42 +0000849 PyObject* v = NUMBER_FromLong((long) value);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000850 if (!v || PyDict_SetItemString(dict, name, v))
851 PyErr_Clear();
852
853 Py_XDECREF(v);
854}
Kristján Valur Jónssonbd77c032007-04-26 15:24:54 +0000855
856/* The same, when the value is a time_t */
857static void _addTimeTToDict(PyObject* dict, char *name, time_t value)
858{
859 PyObject* v;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000860 /* if the value fits in regular int, use that. */
Jesus Ceaef9764f2008-05-13 18:45:46 +0000861#ifdef PY_LONG_LONG
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000862 if (sizeof(time_t) > sizeof(long))
863 v = PyLong_FromLongLong((PY_LONG_LONG) value);
864 else
Kristján Valur Jónssonbd77c032007-04-26 15:24:54 +0000865#endif
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000866 v = NUMBER_FromLong((long) value);
Kristján Valur Jónssonbd77c032007-04-26 15:24:54 +0000867 if (!v || PyDict_SetItemString(dict, name, v))
868 PyErr_Clear();
869
870 Py_XDECREF(v);
871}
872
Gregory P. Smithf0547d02006-06-05 17:38:04 +0000873/* add an db_seq_t to a dictionary using the given name as a key */
874static void _addDb_seq_tToDict(PyObject* dict, char *name, db_seq_t value)
875{
876 PyObject* v = PyLong_FromLongLong(value);
877 if (!v || PyDict_SetItemString(dict, name, v))
878 PyErr_Clear();
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000879
Gregory P. Smithf0547d02006-06-05 17:38:04 +0000880 Py_XDECREF(v);
881}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000882
Jesus Ceaef9764f2008-05-13 18:45:46 +0000883static void _addDB_lsnToDict(PyObject* dict, char *name, DB_LSN value)
884{
885 PyObject *v = Py_BuildValue("(ll)",value.file,value.offset);
886 if (!v || PyDict_SetItemString(dict, name, v))
887 PyErr_Clear();
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000888
Jesus Ceaef9764f2008-05-13 18:45:46 +0000889 Py_XDECREF(v);
890}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000891
892/* --------------------------------------------------------------------- */
893/* Allocators and deallocators */
894
895static DBObject*
896newDBObject(DBEnvObject* arg, int flags)
897{
898 DBObject* self;
899 DB_ENV* db_env = NULL;
900 int err;
901
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000902 self = PyObject_New(DBObject, &DB_Type);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000903 if (self == NULL)
904 return NULL;
905
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000906 self->flags = 0;
907 self->setflags = 0;
908 self->myenvobj = NULL;
Jesus Ceac5a11fa2008-07-23 11:38:42 +0000909 self->db = NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +0000910 self->children_cursors = NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +0000911 self->children_sequences = NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000912 self->associateCallback = NULL;
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +0000913 self->btCompareCallback = NULL;
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -0700914 self->dupCompareCallback = NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000915 self->primaryDBType = 0;
Jesus Ceac5a11fa2008-07-23 11:38:42 +0000916 Py_INCREF(Py_None);
Jesus Cea4907d272008-08-31 14:00:51 +0000917 self->private_obj = Py_None;
Gregory P. Smith31c50652004-06-28 01:20:40 +0000918 self->in_weakreflist = NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000919
920 /* keep a reference to our python DBEnv object */
921 if (arg) {
922 Py_INCREF(arg);
923 self->myenvobj = arg;
924 db_env = arg->db_env;
Jesus Ceaef9764f2008-05-13 18:45:46 +0000925 INSERT_IN_DOUBLE_LINKED_LIST(self->myenvobj->children_dbs,self);
926 } else {
927 self->sibling_prev_p=NULL;
928 self->sibling_next=NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000929 }
Jesus Ceaef9764f2008-05-13 18:45:46 +0000930 self->txn=NULL;
931 self->sibling_prev_p_txn=NULL;
932 self->sibling_next_txn=NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000933
934 if (self->myenvobj)
Gregory P. Smith455d46f2003-07-09 04:45:59 +0000935 self->moduleFlags = self->myenvobj->moduleFlags;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000936 else
Gregory P. Smith455d46f2003-07-09 04:45:59 +0000937 self->moduleFlags.getReturnsNone = DEFAULT_GET_RETURNS_NONE;
938 self->moduleFlags.cursorSetReturnsNone = DEFAULT_CURSOR_SET_RETURNS_NONE;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000939
940 MYDB_BEGIN_ALLOW_THREADS;
941 err = db_create(&self->db, db_env, flags);
Neal Norwitzdce937f2006-07-23 08:01:43 +0000942 if (self->db != NULL) {
943 self->db->set_errcall(self->db, _db_errorCallback);
Neal Norwitzdce937f2006-07-23 08:01:43 +0000944 self->db->app_private = (void*)self;
Neal Norwitzdce937f2006-07-23 08:01:43 +0000945 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000946 MYDB_END_ALLOW_THREADS;
Gregory P. Smith31c50652004-06-28 01:20:40 +0000947 /* TODO add a weakref(self) to the self->myenvobj->open_child_weakrefs
948 * list so that a DBEnv can refuse to close without aborting any open
Gregory P. Smithf0547d02006-06-05 17:38:04 +0000949 * DBTxns and closing any open DBs first. */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000950 if (makeDBError(err)) {
951 if (self->myenvobj) {
952 Py_DECREF(self->myenvobj);
953 self->myenvobj = NULL;
954 }
Gregory P. Smith664782e2008-05-17 06:12:02 +0000955 Py_DECREF(self);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000956 self = NULL;
957 }
958 return self;
959}
960
961
Jesus Ceaef9764f2008-05-13 18:45:46 +0000962/* Forward declaration */
Jesus Cea5cd5f122008-09-23 18:54:08 +0000963static PyObject *DB_close_internal(DBObject* self, int flags, int do_not_close);
Jesus Ceaef9764f2008-05-13 18:45:46 +0000964
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000965static void
966DB_dealloc(DBObject* self)
967{
Jesus Ceaef9764f2008-05-13 18:45:46 +0000968 PyObject *dummy;
969
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000970 if (self->db != NULL) {
Jesus Cea5cd5f122008-09-23 18:54:08 +0000971 dummy=DB_close_internal(self, 0, 0);
972 /*
973 ** Raising exceptions while doing
974 ** garbage collection is a fatal error.
975 */
976 if (dummy)
977 Py_DECREF(dummy);
978 else
979 PyErr_Clear();
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000980 }
Gregory P. Smith31c50652004-06-28 01:20:40 +0000981 if (self->in_weakreflist != NULL) {
982 PyObject_ClearWeakRefs((PyObject *) self);
983 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000984 if (self->myenvobj) {
985 Py_DECREF(self->myenvobj);
986 self->myenvobj = NULL;
987 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000988 if (self->associateCallback != NULL) {
989 Py_DECREF(self->associateCallback);
990 self->associateCallback = NULL;
991 }
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +0000992 if (self->btCompareCallback != NULL) {
993 Py_DECREF(self->btCompareCallback);
994 self->btCompareCallback = NULL;
995 }
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -0700996 if (self->dupCompareCallback != NULL) {
997 Py_DECREF(self->dupCompareCallback);
998 self->dupCompareCallback = NULL;
999 }
Jesus Cea4907d272008-08-31 14:00:51 +00001000 Py_DECREF(self->private_obj);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001001 PyObject_Del(self);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001002}
1003
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001004static DBCursorObject*
Jesus Ceaef9764f2008-05-13 18:45:46 +00001005newDBCursorObject(DBC* dbc, DBTxnObject *txn, DBObject* db)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001006{
Neal Norwitzb4a55812004-07-09 23:30:57 +00001007 DBCursorObject* self = PyObject_New(DBCursorObject, &DBCursor_Type);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001008 if (self == NULL)
1009 return NULL;
1010
1011 self->dbc = dbc;
1012 self->mydb = db;
Jesus Ceaef9764f2008-05-13 18:45:46 +00001013
1014 INSERT_IN_DOUBLE_LINKED_LIST(self->mydb->children_cursors,self);
1015 if (txn && ((PyObject *)txn!=Py_None)) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001016 INSERT_IN_DOUBLE_LINKED_LIST_TXN(txn->children_cursors,self);
1017 self->txn=txn;
Jesus Ceaef9764f2008-05-13 18:45:46 +00001018 } else {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001019 self->txn=NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00001020 }
1021
Gregory P. Smitha703a212003-11-03 01:04:41 +00001022 self->in_weakreflist = NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001023 Py_INCREF(self->mydb);
1024 return self;
1025}
1026
1027
Jesus Ceaef9764f2008-05-13 18:45:46 +00001028/* Forward declaration */
1029static PyObject *DBC_close_internal(DBCursorObject* self);
1030
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001031static void
1032DBCursor_dealloc(DBCursorObject* self)
1033{
Jesus Ceaef9764f2008-05-13 18:45:46 +00001034 PyObject *dummy;
Gregory P. Smitha703a212003-11-03 01:04:41 +00001035
Jesus Ceaef9764f2008-05-13 18:45:46 +00001036 if (self->dbc != NULL) {
Jesus Cea5cd5f122008-09-23 18:54:08 +00001037 dummy=DBC_close_internal(self);
1038 /*
1039 ** Raising exceptions while doing
1040 ** garbage collection is a fatal error.
1041 */
1042 if (dummy)
1043 Py_DECREF(dummy);
1044 else
1045 PyErr_Clear();
Jesus Ceaef9764f2008-05-13 18:45:46 +00001046 }
Gregory P. Smitha703a212003-11-03 01:04:41 +00001047 if (self->in_weakreflist != NULL) {
1048 PyObject_ClearWeakRefs((PyObject *) self);
1049 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00001050 Py_DECREF(self->mydb);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001051 PyObject_Del(self);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001052}
1053
1054
Jesus Cea6557aac2010-03-22 14:22:26 +00001055static DBLogCursorObject*
1056newDBLogCursorObject(DB_LOGC* dblogc, DBEnvObject* env)
1057{
1058 DBLogCursorObject* self;
1059
1060 self = PyObject_New(DBLogCursorObject, &DBLogCursor_Type);
1061
1062 if (self == NULL)
1063 return NULL;
1064
1065 self->logc = dblogc;
1066 self->env = env;
1067
1068 INSERT_IN_DOUBLE_LINKED_LIST(self->env->children_logcursors, self);
1069
1070 self->in_weakreflist = NULL;
1071 Py_INCREF(self->env);
1072 return self;
1073}
1074
1075
1076/* Forward declaration */
1077static PyObject *DBLogCursor_close_internal(DBLogCursorObject* self);
1078
1079static void
1080DBLogCursor_dealloc(DBLogCursorObject* self)
1081{
1082 PyObject *dummy;
1083
1084 if (self->logc != NULL) {
1085 dummy = DBLogCursor_close_internal(self);
1086 /*
1087 ** Raising exceptions while doing
1088 ** garbage collection is a fatal error.
1089 */
1090 if (dummy)
1091 Py_DECREF(dummy);
1092 else
1093 PyErr_Clear();
1094 }
1095 if (self->in_weakreflist != NULL) {
1096 PyObject_ClearWeakRefs((PyObject *) self);
1097 }
1098 Py_DECREF(self->env);
1099 PyObject_Del(self);
1100}
1101
1102
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001103static DBEnvObject*
1104newDBEnvObject(int flags)
1105{
1106 int err;
Neal Norwitzb4a55812004-07-09 23:30:57 +00001107 DBEnvObject* self = PyObject_New(DBEnvObject, &DBEnv_Type);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001108 if (self == NULL)
1109 return NULL;
1110
Jesus Cea5cd5f122008-09-23 18:54:08 +00001111 self->db_env = NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001112 self->closed = 1;
1113 self->flags = flags;
Gregory P. Smith455d46f2003-07-09 04:45:59 +00001114 self->moduleFlags.getReturnsNone = DEFAULT_GET_RETURNS_NONE;
1115 self->moduleFlags.cursorSetReturnsNone = DEFAULT_CURSOR_SET_RETURNS_NONE;
Jesus Ceaef9764f2008-05-13 18:45:46 +00001116 self->children_dbs = NULL;
1117 self->children_txns = NULL;
Jesus Cea6557aac2010-03-22 14:22:26 +00001118 self->children_logcursors = NULL ;
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07001119#if (DBVER >= 52)
1120 self->children_sites = NULL;
1121#endif
Jesus Ceac5a11fa2008-07-23 11:38:42 +00001122 Py_INCREF(Py_None);
Jesus Cea4907d272008-08-31 14:00:51 +00001123 self->private_obj = Py_None;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00001124 Py_INCREF(Py_None);
1125 self->rep_transport = Py_None;
Gregory P. Smith31c50652004-06-28 01:20:40 +00001126 self->in_weakreflist = NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00001127 self->event_notifyCallback = NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00001128
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001129 MYDB_BEGIN_ALLOW_THREADS;
1130 err = db_env_create(&self->db_env, flags);
1131 MYDB_END_ALLOW_THREADS;
1132 if (makeDBError(err)) {
Gregory P. Smith664782e2008-05-17 06:12:02 +00001133 Py_DECREF(self);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001134 self = NULL;
1135 }
1136 else {
1137 self->db_env->set_errcall(self->db_env, _db_errorCallback);
Jesus Cea4907d272008-08-31 14:00:51 +00001138 self->db_env->app_private = self;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001139 }
1140 return self;
1141}
1142
Jesus Ceaef9764f2008-05-13 18:45:46 +00001143/* Forward declaration */
1144static PyObject *DBEnv_close_internal(DBEnvObject* self, int flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001145
1146static void
1147DBEnv_dealloc(DBEnvObject* self)
1148{
Jesus Ceaef9764f2008-05-13 18:45:46 +00001149 PyObject *dummy;
1150
Jesus Ceaac25fab2008-09-03 17:50:32 +00001151 if (self->db_env) {
Jesus Cea5cd5f122008-09-23 18:54:08 +00001152 dummy=DBEnv_close_internal(self, 0);
1153 /*
1154 ** Raising exceptions while doing
1155 ** garbage collection is a fatal error.
1156 */
1157 if (dummy)
1158 Py_DECREF(dummy);
1159 else
1160 PyErr_Clear();
Jesus Ceaef9764f2008-05-13 18:45:46 +00001161 }
1162
Jesus Ceaef9764f2008-05-13 18:45:46 +00001163 Py_XDECREF(self->event_notifyCallback);
1164 self->event_notifyCallback = NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00001165
Gregory P. Smith31c50652004-06-28 01:20:40 +00001166 if (self->in_weakreflist != NULL) {
1167 PyObject_ClearWeakRefs((PyObject *) self);
1168 }
Jesus Cea4907d272008-08-31 14:00:51 +00001169 Py_DECREF(self->private_obj);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00001170 Py_DECREF(self->rep_transport);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001171 PyObject_Del(self);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001172}
1173
1174
1175static DBTxnObject*
Jesus Ceaef9764f2008-05-13 18:45:46 +00001176newDBTxnObject(DBEnvObject* myenv, DBTxnObject *parent, DB_TXN *txn, int flags)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001177{
1178 int err;
Gregory P. Smith664782e2008-05-17 06:12:02 +00001179 DB_TXN *parent_txn = NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00001180
Neal Norwitzb4a55812004-07-09 23:30:57 +00001181 DBTxnObject* self = PyObject_New(DBTxnObject, &DBTxn_Type);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001182 if (self == NULL)
1183 return NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00001184
Gregory P. Smith31c50652004-06-28 01:20:40 +00001185 self->in_weakreflist = NULL;
Gregory P. Smith664782e2008-05-17 06:12:02 +00001186 self->children_txns = NULL;
1187 self->children_dbs = NULL;
1188 self->children_cursors = NULL;
1189 self->children_sequences = NULL;
1190 self->flag_prepare = 0;
1191 self->parent_txn = NULL;
1192 self->env = NULL;
Jesus Cea6557aac2010-03-22 14:22:26 +00001193 /* We initialize just in case "txn_begin" fails */
1194 self->txn = NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001195
Jesus Ceaef9764f2008-05-13 18:45:46 +00001196 if (parent && ((PyObject *)parent!=Py_None)) {
Gregory P. Smith664782e2008-05-17 06:12:02 +00001197 parent_txn = parent->txn;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001198 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00001199
1200 if (txn) {
Gregory P. Smith664782e2008-05-17 06:12:02 +00001201 self->txn = txn;
Jesus Ceaef9764f2008-05-13 18:45:46 +00001202 } else {
1203 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00001204 err = myenv->db_env->txn_begin(myenv->db_env, parent_txn, &(self->txn), flags);
Jesus Ceaef9764f2008-05-13 18:45:46 +00001205 MYDB_END_ALLOW_THREADS;
1206
1207 if (makeDBError(err)) {
Jesus Cea6557aac2010-03-22 14:22:26 +00001208 /* Free object half initialized */
Gregory P. Smith664782e2008-05-17 06:12:02 +00001209 Py_DECREF(self);
Jesus Ceaef9764f2008-05-13 18:45:46 +00001210 return NULL;
1211 }
1212 }
1213
Gregory P. Smith664782e2008-05-17 06:12:02 +00001214 /* Can't use 'parent' because could be 'parent==Py_None' */
1215 if (parent_txn) {
1216 self->parent_txn = parent;
Jesus Ceaef9764f2008-05-13 18:45:46 +00001217 Py_INCREF(parent);
1218 self->env = NULL;
Gregory P. Smith664782e2008-05-17 06:12:02 +00001219 INSERT_IN_DOUBLE_LINKED_LIST(parent->children_txns, self);
Jesus Ceaef9764f2008-05-13 18:45:46 +00001220 } else {
Gregory P. Smith664782e2008-05-17 06:12:02 +00001221 self->parent_txn = NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00001222 Py_INCREF(myenv);
1223 self->env = myenv;
Gregory P. Smith664782e2008-05-17 06:12:02 +00001224 INSERT_IN_DOUBLE_LINKED_LIST(myenv->children_txns, self);
Jesus Ceaef9764f2008-05-13 18:45:46 +00001225 }
1226
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001227 return self;
1228}
1229
Jesus Ceaef9764f2008-05-13 18:45:46 +00001230/* Forward declaration */
1231static PyObject *
1232DBTxn_abort_discard_internal(DBTxnObject* self, int discard);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001233
1234static void
1235DBTxn_dealloc(DBTxnObject* self)
1236{
Jesus Ceaef9764f2008-05-13 18:45:46 +00001237 PyObject *dummy;
1238
1239 if (self->txn) {
1240 int flag_prepare = self->flag_prepare;
Jesus Cea5cd5f122008-09-23 18:54:08 +00001241
Jesus Cea6557aac2010-03-22 14:22:26 +00001242 dummy=DBTxn_abort_discard_internal(self, 0);
Jesus Cea5cd5f122008-09-23 18:54:08 +00001243 /*
1244 ** Raising exceptions while doing
1245 ** garbage collection is a fatal error.
1246 */
1247 if (dummy)
1248 Py_DECREF(dummy);
1249 else
1250 PyErr_Clear();
1251
Jesus Ceaef9764f2008-05-13 18:45:46 +00001252 if (!flag_prepare) {
1253 PyErr_Warn(PyExc_RuntimeWarning,
1254 "DBTxn aborted in destructor. No prior commit() or abort().");
1255 }
1256 }
1257
Gregory P. Smith31c50652004-06-28 01:20:40 +00001258 if (self->in_weakreflist != NULL) {
1259 PyObject_ClearWeakRefs((PyObject *) self);
1260 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001261
Jesus Ceaef9764f2008-05-13 18:45:46 +00001262 if (self->env) {
1263 Py_DECREF(self->env);
1264 } else {
Jesus Cea6557aac2010-03-22 14:22:26 +00001265 /*
1266 ** We can have "self->env==NULL" and "self->parent_txn==NULL"
1267 ** if something happens when creating the transaction object
1268 ** and we abort the object while half done.
1269 */
1270 Py_XDECREF(self->parent_txn);
Gregory P. Smith31c50652004-06-28 01:20:40 +00001271 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001272 PyObject_Del(self);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001273}
1274
1275
1276static DBLockObject*
1277newDBLockObject(DBEnvObject* myenv, u_int32_t locker, DBT* obj,
1278 db_lockmode_t lock_mode, int flags)
1279{
1280 int err;
Neal Norwitzb4a55812004-07-09 23:30:57 +00001281 DBLockObject* self = PyObject_New(DBLockObject, &DBLock_Type);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001282 if (self == NULL)
1283 return NULL;
Gregory P. Smith31c50652004-06-28 01:20:40 +00001284 self->in_weakreflist = NULL;
Jesus Cea6557aac2010-03-22 14:22:26 +00001285 self->lock_initialized = 0; /* Just in case the call fails */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001286
1287 MYDB_BEGIN_ALLOW_THREADS;
Barry Warsaw9a0d7792002-12-30 20:53:52 +00001288 err = myenv->db_env->lock_get(myenv->db_env, locker, flags, obj, lock_mode,
1289 &self->lock);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001290 MYDB_END_ALLOW_THREADS;
1291 if (makeDBError(err)) {
Gregory P. Smith664782e2008-05-17 06:12:02 +00001292 Py_DECREF(self);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001293 self = NULL;
Jesus Cea6557aac2010-03-22 14:22:26 +00001294 } else {
1295 self->lock_initialized = 1;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001296 }
1297
1298 return self;
1299}
1300
1301
1302static void
1303DBLock_dealloc(DBLockObject* self)
1304{
Gregory P. Smith31c50652004-06-28 01:20:40 +00001305 if (self->in_weakreflist != NULL) {
1306 PyObject_ClearWeakRefs((PyObject *) self);
1307 }
Gregory P. Smith31c50652004-06-28 01:20:40 +00001308 /* TODO: is this lock held? should we release it? */
Jesus Cea6557aac2010-03-22 14:22:26 +00001309 /* CAUTION: The lock can be not initialized if the creation has failed */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001310
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001311 PyObject_Del(self);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001312}
1313
1314
Gregory P. Smithf0547d02006-06-05 17:38:04 +00001315static DBSequenceObject*
1316newDBSequenceObject(DBObject* mydb, int flags)
1317{
1318 int err;
1319 DBSequenceObject* self = PyObject_New(DBSequenceObject, &DBSequence_Type);
1320 if (self == NULL)
1321 return NULL;
1322 Py_INCREF(mydb);
1323 self->mydb = mydb;
Gregory P. Smithf0547d02006-06-05 17:38:04 +00001324
Jesus Ceaef9764f2008-05-13 18:45:46 +00001325 INSERT_IN_DOUBLE_LINKED_LIST(self->mydb->children_sequences,self);
Gregory P. Smith664782e2008-05-17 06:12:02 +00001326 self->txn = NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00001327
1328 self->in_weakreflist = NULL;
Jesus Cea6557aac2010-03-22 14:22:26 +00001329 self->sequence = NULL; /* Just in case the call fails */
Gregory P. Smithf0547d02006-06-05 17:38:04 +00001330
1331 MYDB_BEGIN_ALLOW_THREADS;
1332 err = db_sequence_create(&self->sequence, self->mydb->db, flags);
1333 MYDB_END_ALLOW_THREADS;
1334 if (makeDBError(err)) {
Gregory P. Smith664782e2008-05-17 06:12:02 +00001335 Py_DECREF(self);
Gregory P. Smithf0547d02006-06-05 17:38:04 +00001336 self = NULL;
1337 }
1338
1339 return self;
1340}
1341
Jesus Ceaef9764f2008-05-13 18:45:46 +00001342/* Forward declaration */
1343static PyObject
1344*DBSequence_close_internal(DBSequenceObject* self, int flags, int do_not_close);
Gregory P. Smithf0547d02006-06-05 17:38:04 +00001345
1346static void
1347DBSequence_dealloc(DBSequenceObject* self)
1348{
Jesus Ceaef9764f2008-05-13 18:45:46 +00001349 PyObject *dummy;
1350
1351 if (self->sequence != NULL) {
1352 dummy=DBSequence_close_internal(self,0,0);
Jesus Cea5cd5f122008-09-23 18:54:08 +00001353 /*
1354 ** Raising exceptions while doing
1355 ** garbage collection is a fatal error.
1356 */
1357 if (dummy)
1358 Py_DECREF(dummy);
1359 else
1360 PyErr_Clear();
Jesus Ceaef9764f2008-05-13 18:45:46 +00001361 }
1362
Gregory P. Smithf0547d02006-06-05 17:38:04 +00001363 if (self->in_weakreflist != NULL) {
1364 PyObject_ClearWeakRefs((PyObject *) self);
1365 }
Gregory P. Smithf0547d02006-06-05 17:38:04 +00001366
1367 Py_DECREF(self->mydb);
1368 PyObject_Del(self);
1369}
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07001370
1371#if (DBVER >= 52)
1372static DBSiteObject*
1373newDBSiteObject(DB_SITE* sitep, DBEnvObject* env)
1374{
1375 DBSiteObject* self;
1376
1377 self = PyObject_New(DBSiteObject, &DBSite_Type);
1378
1379 if (self == NULL)
1380 return NULL;
1381
1382 self->site = sitep;
1383 self->env = env;
1384
1385 INSERT_IN_DOUBLE_LINKED_LIST(self->env->children_sites, self);
1386
1387 self->in_weakreflist = NULL;
1388 Py_INCREF(self->env);
1389 return self;
1390}
1391
1392/* Forward declaration */
1393static PyObject *DBSite_close_internal(DBSiteObject* self);
1394
1395static void
1396DBSite_dealloc(DBSiteObject* self)
1397{
1398 PyObject *dummy;
1399
1400 if (self->site != NULL) {
1401 dummy = DBSite_close_internal(self);
1402 /*
1403 ** Raising exceptions while doing
1404 ** garbage collection is a fatal error.
1405 */
1406 if (dummy)
1407 Py_DECREF(dummy);
1408 else
1409 PyErr_Clear();
1410 }
1411 if (self->in_weakreflist != NULL) {
1412 PyObject_ClearWeakRefs((PyObject *) self);
1413 }
1414 Py_DECREF(self->env);
1415 PyObject_Del(self);
1416}
Gregory P. Smithf0547d02006-06-05 17:38:04 +00001417#endif
1418
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001419/* --------------------------------------------------------------------- */
1420/* DB methods */
1421
1422static PyObject*
Jesus Cea4907d272008-08-31 14:00:51 +00001423DB_append(DBObject* self, PyObject* args, PyObject* kwargs)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001424{
1425 PyObject* txnobj = NULL;
1426 PyObject* dataobj;
1427 db_recno_t recno;
1428 DBT key, data;
1429 DB_TXN *txn = NULL;
Jesus Cea4907d272008-08-31 14:00:51 +00001430 static char* kwnames[] = { "data", "txn", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001431
Jesus Cea4907d272008-08-31 14:00:51 +00001432 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O:append", kwnames,
1433 &dataobj, &txnobj))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001434 return NULL;
1435
1436 CHECK_DB_NOT_CLOSED(self);
1437
1438 /* make a dummy key out of a recno */
1439 recno = 0;
1440 CLEAR_DBT(key);
1441 key.data = &recno;
1442 key.size = sizeof(recno);
1443 key.ulen = key.size;
1444 key.flags = DB_DBT_USERMEM;
1445
1446 if (!make_dbt(dataobj, &data)) return NULL;
1447 if (!checkTxnObj(txnobj, &txn)) return NULL;
1448
1449 if (-1 == _DB_put(self, txn, &key, &data, DB_APPEND))
1450 return NULL;
1451
Jesus Ceac5a11fa2008-07-23 11:38:42 +00001452 return NUMBER_FromLong(recno);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001453}
1454
1455
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001456static int
Barry Warsaw9a0d7792002-12-30 20:53:52 +00001457_db_associateCallback(DB* db, const DBT* priKey, const DBT* priData,
1458 DBT* secKey)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001459{
1460 int retval = DB_DONOTINDEX;
1461 DBObject* secondaryDB = (DBObject*)db->app_private;
1462 PyObject* callback = secondaryDB->associateCallback;
1463 int type = secondaryDB->primaryDBType;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001464 PyObject* args;
Thomas Wouters89ba3812006-03-07 14:14:51 +00001465 PyObject* result = NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001466
1467
1468 if (callback != NULL) {
1469 MYDB_BEGIN_BLOCK_THREADS;
1470
Thomas Woutersb3153832006-03-08 01:47:19 +00001471 if (type == DB_RECNO || type == DB_QUEUE)
Jesus Ceaef9764f2008-05-13 18:45:46 +00001472 args = BuildValue_LS(*((db_recno_t*)priKey->data), priData->data, priData->size);
Thomas Woutersb3153832006-03-08 01:47:19 +00001473 else
Jesus Ceaef9764f2008-05-13 18:45:46 +00001474 args = BuildValue_SS(priKey->data, priKey->size, priData->data, priData->size);
Thomas Wouters098f6942006-03-07 14:13:17 +00001475 if (args != NULL) {
Thomas Wouters098f6942006-03-07 14:13:17 +00001476 result = PyEval_CallObject(callback, args);
1477 }
1478 if (args == NULL || result == NULL) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001479 PyErr_Print();
1480 }
1481 else if (result == Py_None) {
1482 retval = DB_DONOTINDEX;
1483 }
Jesus Ceac5a11fa2008-07-23 11:38:42 +00001484 else if (NUMBER_Check(result)) {
1485 retval = NUMBER_AsLong(result);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001486 }
Christian Heimes593daf52008-05-26 12:51:38 +00001487 else if (PyBytes_Check(result)) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001488 char* data;
Martin v. Löwis18e16552006-02-15 17:27:45 +00001489 Py_ssize_t size;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001490
1491 CLEAR_DBT(*secKey);
Christian Heimes593daf52008-05-26 12:51:38 +00001492 PyBytes_AsStringAndSize(result, &data, &size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001493 secKey->flags = DB_DBT_APPMALLOC; /* DB will free */
1494 secKey->data = malloc(size); /* TODO, check this */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001495 if (secKey->data) {
1496 memcpy(secKey->data, data, size);
1497 secKey->size = size;
1498 retval = 0;
1499 }
1500 else {
1501 PyErr_SetString(PyExc_MemoryError,
Barry Warsaw9a0d7792002-12-30 20:53:52 +00001502 "malloc failed in _db_associateCallback");
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001503 PyErr_Print();
1504 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001505 }
Jesus Cea6557aac2010-03-22 14:22:26 +00001506#if (DBVER >= 46)
1507 else if (PyList_Check(result))
1508 {
1509 char* data;
1510 Py_ssize_t size;
1511 int i, listlen;
1512 DBT* dbts;
1513
1514 listlen = PyList_Size(result);
1515
1516 dbts = (DBT *)malloc(sizeof(DBT) * listlen);
1517
1518 for (i=0; i<listlen; i++)
1519 {
1520 if (!PyBytes_Check(PyList_GetItem(result, i)))
1521 {
1522 PyErr_SetString(
1523 PyExc_TypeError,
1524#if (PY_VERSION_HEX < 0x03000000)
1525"The list returned by DB->associate callback should be a list of strings.");
1526#else
1527"The list returned by DB->associate callback should be a list of bytes.");
1528#endif
1529 PyErr_Print();
1530 }
1531
1532 PyBytes_AsStringAndSize(
1533 PyList_GetItem(result, i),
1534 &data, &size);
1535
1536 CLEAR_DBT(dbts[i]);
1537 dbts[i].data = malloc(size); /* TODO, check this */
1538
1539 if (dbts[i].data)
1540 {
1541 memcpy(dbts[i].data, data, size);
1542 dbts[i].size = size;
1543 dbts[i].ulen = dbts[i].size;
1544 dbts[i].flags = DB_DBT_APPMALLOC; /* DB will free */
1545 }
1546 else
1547 {
1548 PyErr_SetString(PyExc_MemoryError,
1549 "malloc failed in _db_associateCallback (list)");
1550 PyErr_Print();
1551 }
1552 }
1553
1554 CLEAR_DBT(*secKey);
1555
1556 secKey->data = dbts;
1557 secKey->size = listlen;
1558 secKey->flags = DB_DBT_APPMALLOC | DB_DBT_MULTIPLE;
1559 retval = 0;
1560 }
1561#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001562 else {
Barry Warsaw9a0d7792002-12-30 20:53:52 +00001563 PyErr_SetString(
1564 PyExc_TypeError,
Jesus Cea6557aac2010-03-22 14:22:26 +00001565#if (PY_VERSION_HEX < 0x03000000)
1566"DB associate callback should return DB_DONOTINDEX/string/list of strings.");
1567#else
1568"DB associate callback should return DB_DONOTINDEX/bytes/list of bytes.");
1569#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001570 PyErr_Print();
1571 }
1572
Thomas Woutersb3153832006-03-08 01:47:19 +00001573 Py_XDECREF(args);
1574 Py_XDECREF(result);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001575
1576 MYDB_END_BLOCK_THREADS;
1577 }
1578 return retval;
1579}
1580
1581
1582static PyObject*
1583DB_associate(DBObject* self, PyObject* args, PyObject* kwargs)
1584{
1585 int err, flags=0;
1586 DBObject* secondaryDB;
1587 PyObject* callback;
Barry Warsaw9a0d7792002-12-30 20:53:52 +00001588 PyObject *txnobj = NULL;
1589 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00001590 static char* kwnames[] = {"secondaryDB", "callback", "flags", "txn",
Jeremy Hyltonaf68c872005-12-10 18:50:16 +00001591 NULL};
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001592
Barry Warsaw9a0d7792002-12-30 20:53:52 +00001593 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|iO:associate", kwnames,
1594 &secondaryDB, &callback, &flags,
1595 &txnobj)) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001596 return NULL;
Barry Warsaw9a0d7792002-12-30 20:53:52 +00001597 }
1598
Barry Warsaw9a0d7792002-12-30 20:53:52 +00001599 if (!checkTxnObj(txnobj, &txn)) return NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001600
1601 CHECK_DB_NOT_CLOSED(self);
1602 if (!DBObject_Check(secondaryDB)) {
1603 makeTypeError("DB", (PyObject*)secondaryDB);
1604 return NULL;
1605 }
Gregory P. Smith91116b62005-06-06 10:28:06 +00001606 CHECK_DB_NOT_CLOSED(secondaryDB);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001607 if (callback == Py_None) {
1608 callback = NULL;
1609 }
1610 else if (!PyCallable_Check(callback)) {
1611 makeTypeError("Callable", callback);
1612 return NULL;
1613 }
1614
1615 /* Save a reference to the callback in the secondary DB. */
Gregory P. Smith692ca9a2005-06-06 09:55:06 +00001616 Py_XDECREF(secondaryDB->associateCallback);
Thomas Woutersb3153832006-03-08 01:47:19 +00001617 Py_XINCREF(callback);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001618 secondaryDB->associateCallback = callback;
1619 secondaryDB->primaryDBType = _DB_get_type(self);
1620
Martin v. Löwisb2c7aff2002-11-23 11:26:07 +00001621 /* PyEval_InitThreads is called here due to a quirk in python 1.5
1622 * - 2.2.1 (at least) according to Russell Williamson <merel@wt.net>:
1623 * The global interepreter lock is not initialized until the first
1624 * thread is created using thread.start_new_thread() or fork() is
1625 * called. that would cause the ALLOW_THREADS here to segfault due
1626 * to a null pointer reference if no threads or child processes
1627 * have been created. This works around that and is a no-op if
1628 * threads have already been initialized.
1629 * (see pybsddb-users mailing list post on 2002-08-07)
1630 */
Gregory P. Smithaa71f5f2003-01-17 07:56:16 +00001631#ifdef WITH_THREAD
Martin v. Löwisb2c7aff2002-11-23 11:26:07 +00001632 PyEval_InitThreads();
Gregory P. Smithaa71f5f2003-01-17 07:56:16 +00001633#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001634 MYDB_BEGIN_ALLOW_THREADS;
Barry Warsaw9a0d7792002-12-30 20:53:52 +00001635 err = self->db->associate(self->db,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001636 txn,
Barry Warsaw9a0d7792002-12-30 20:53:52 +00001637 secondaryDB->db,
1638 _db_associateCallback,
1639 flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001640 MYDB_END_ALLOW_THREADS;
1641
1642 if (err) {
Gregory P. Smith692ca9a2005-06-06 09:55:06 +00001643 Py_XDECREF(secondaryDB->associateCallback);
1644 secondaryDB->associateCallback = NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001645 secondaryDB->primaryDBType = 0;
1646 }
1647
1648 RETURN_IF_ERR();
1649 RETURN_NONE();
1650}
1651
1652
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001653static PyObject*
Jesus Cea5cd5f122008-09-23 18:54:08 +00001654DB_close_internal(DBObject* self, int flags, int do_not_close)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001655{
Jesus Ceaef9764f2008-05-13 18:45:46 +00001656 PyObject *dummy;
Jesus Cea5cd5f122008-09-23 18:54:08 +00001657 int err = 0;
Jesus Ceaef9764f2008-05-13 18:45:46 +00001658
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001659 if (self->db != NULL) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00001660 /* Can be NULL if db is not in an environment */
1661 EXTRACT_FROM_DOUBLE_LINKED_LIST_MAYBE_NULL(self);
Jesus Cea4907d272008-08-31 14:00:51 +00001662
Jesus Ceaef9764f2008-05-13 18:45:46 +00001663 if (self->txn) {
1664 EXTRACT_FROM_DOUBLE_LINKED_LIST_TXN(self);
1665 self->txn=NULL;
1666 }
1667
1668 while(self->children_cursors) {
1669 dummy=DBC_close_internal(self->children_cursors);
1670 Py_XDECREF(dummy);
1671 }
1672
Jesus Ceaef9764f2008-05-13 18:45:46 +00001673 while(self->children_sequences) {
1674 dummy=DBSequence_close_internal(self->children_sequences,0,0);
1675 Py_XDECREF(dummy);
1676 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00001677
Jesus Cea5cd5f122008-09-23 18:54:08 +00001678 /*
1679 ** "do_not_close" is used to dispose all related objects in the
1680 ** tree, without actually releasing the "root" object.
1681 ** This is done, for example, because function calls like
1682 ** "DB.verify()" implicitly close the underlying handle. So
1683 ** the handle doesn't need to be closed, but related objects
1684 ** must be cleaned up.
1685 */
1686 if (!do_not_close) {
1687 MYDB_BEGIN_ALLOW_THREADS;
1688 err = self->db->close(self->db, flags);
1689 MYDB_END_ALLOW_THREADS;
1690 self->db = NULL;
1691 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001692 RETURN_IF_ERR();
1693 }
1694 RETURN_NONE();
1695}
1696
Jesus Ceaef9764f2008-05-13 18:45:46 +00001697static PyObject*
1698DB_close(DBObject* self, PyObject* args)
1699{
1700 int flags=0;
1701 if (!PyArg_ParseTuple(args,"|i:close", &flags))
1702 return NULL;
Jesus Cea5cd5f122008-09-23 18:54:08 +00001703 return DB_close_internal(self, flags, 0);
Jesus Ceaef9764f2008-05-13 18:45:46 +00001704}
1705
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001706
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001707static PyObject*
1708_DB_consume(DBObject* self, PyObject* args, PyObject* kwargs, int consume_flag)
1709{
1710 int err, flags=0, type;
1711 PyObject* txnobj = NULL;
1712 PyObject* retval = NULL;
1713 DBT key, data;
1714 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00001715 static char* kwnames[] = { "txn", "flags", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001716
1717 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Oi:consume", kwnames,
1718 &txnobj, &flags))
1719 return NULL;
1720
1721 CHECK_DB_NOT_CLOSED(self);
1722 type = _DB_get_type(self);
1723 if (type == -1)
1724 return NULL;
1725 if (type != DB_QUEUE) {
Barry Warsaw9a0d7792002-12-30 20:53:52 +00001726 PyErr_SetString(PyExc_TypeError,
1727 "Consume methods only allowed for Queue DB's");
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001728 return NULL;
1729 }
1730 if (!checkTxnObj(txnobj, &txn))
1731 return NULL;
1732
1733 CLEAR_DBT(key);
1734 CLEAR_DBT(data);
1735 if (CHECK_DBFLAG(self, DB_THREAD)) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00001736 /* Tell Berkeley DB to malloc the return value (thread safe) */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001737 data.flags = DB_DBT_MALLOC;
1738 key.flags = DB_DBT_MALLOC;
1739 }
1740
1741 MYDB_BEGIN_ALLOW_THREADS;
1742 err = self->db->get(self->db, txn, &key, &data, flags|consume_flag);
1743 MYDB_END_ALLOW_THREADS;
1744
Gregory P. Smithe9477062005-06-04 06:46:59 +00001745 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001746 && self->moduleFlags.getReturnsNone) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001747 err = 0;
1748 Py_INCREF(Py_None);
1749 retval = Py_None;
1750 }
1751 else if (!err) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00001752 retval = BuildValue_SS(key.data, key.size, data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001753 FREE_DBT(key);
1754 FREE_DBT(data);
1755 }
1756
1757 RETURN_IF_ERR();
1758 return retval;
1759}
1760
1761static PyObject*
1762DB_consume(DBObject* self, PyObject* args, PyObject* kwargs, int consume_flag)
1763{
1764 return _DB_consume(self, args, kwargs, DB_CONSUME);
1765}
1766
1767static PyObject*
Barry Warsaw9a0d7792002-12-30 20:53:52 +00001768DB_consume_wait(DBObject* self, PyObject* args, PyObject* kwargs,
1769 int consume_flag)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001770{
1771 return _DB_consume(self, args, kwargs, DB_CONSUME_WAIT);
1772}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001773
1774
1775static PyObject*
1776DB_cursor(DBObject* self, PyObject* args, PyObject* kwargs)
1777{
1778 int err, flags=0;
1779 DBC* dbc;
1780 PyObject* txnobj = NULL;
1781 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00001782 static char* kwnames[] = { "txn", "flags", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001783
1784 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Oi:cursor", kwnames,
1785 &txnobj, &flags))
1786 return NULL;
1787 CHECK_DB_NOT_CLOSED(self);
1788 if (!checkTxnObj(txnobj, &txn))
1789 return NULL;
1790
1791 MYDB_BEGIN_ALLOW_THREADS;
1792 err = self->db->cursor(self->db, txn, &dbc, flags);
1793 MYDB_END_ALLOW_THREADS;
1794 RETURN_IF_ERR();
Jesus Ceaef9764f2008-05-13 18:45:46 +00001795 return (PyObject*) newDBCursorObject(dbc, (DBTxnObject *)txnobj, self);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001796}
1797
1798
1799static PyObject*
1800DB_delete(DBObject* self, PyObject* args, PyObject* kwargs)
1801{
1802 PyObject* txnobj = NULL;
1803 int flags = 0;
1804 PyObject* keyobj;
1805 DBT key;
1806 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00001807 static char* kwnames[] = { "key", "txn", "flags", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001808
1809 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|Oi:delete", kwnames,
1810 &keyobj, &txnobj, &flags))
1811 return NULL;
1812 CHECK_DB_NOT_CLOSED(self);
1813 if (!make_key_dbt(self, keyobj, &key, NULL))
1814 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00001815 if (!checkTxnObj(txnobj, &txn)) {
1816 FREE_DBT(key);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001817 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00001818 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001819
Gregory P. Smithdc5af702004-06-27 23:32:34 +00001820 if (-1 == _DB_delete(self, txn, &key, 0)) {
1821 FREE_DBT(key);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001822 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00001823 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001824
1825 FREE_DBT(key);
1826 RETURN_NONE();
1827}
1828
1829
Jesus Cea6557aac2010-03-22 14:22:26 +00001830#if (DBVER >= 47)
1831/*
1832** This function is available since Berkeley DB 4.4,
1833** but 4.6 version is so buggy that we only support
1834** it from BDB 4.7 and newer.
1835*/
1836static PyObject*
1837DB_compact(DBObject* self, PyObject* args, PyObject* kwargs)
1838{
1839 PyObject* txnobj = NULL;
1840 PyObject *startobj = NULL, *stopobj = NULL;
1841 int flags = 0;
1842 DB_TXN *txn = NULL;
1843 DBT *start_p = NULL, *stop_p = NULL;
1844 DBT start, stop;
1845 int err;
1846 DB_COMPACT c_data = { 0 };
1847 static char* kwnames[] = { "txn", "start", "stop", "flags",
1848 "compact_fillpercent", "compact_pages",
1849 "compact_timeout", NULL };
1850
1851
1852 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OOOiiiI:compact", kwnames,
1853 &txnobj, &startobj, &stopobj, &flags,
1854 &c_data.compact_fillpercent,
1855 &c_data.compact_pages,
1856 &c_data.compact_timeout))
1857 return NULL;
1858
1859 CHECK_DB_NOT_CLOSED(self);
1860 if (!checkTxnObj(txnobj, &txn)) {
1861 return NULL;
1862 }
1863
1864 if (startobj && make_key_dbt(self, startobj, &start, NULL)) {
1865 start_p = &start;
1866 }
1867 if (stopobj && make_key_dbt(self, stopobj, &stop, NULL)) {
1868 stop_p = &stop;
1869 }
1870
1871 MYDB_BEGIN_ALLOW_THREADS;
1872 err = self->db->compact(self->db, txn, start_p, stop_p, &c_data,
1873 flags, NULL);
1874 MYDB_END_ALLOW_THREADS;
1875
1876 if (startobj)
1877 FREE_DBT(start);
1878 if (stopobj)
1879 FREE_DBT(stop);
1880
1881 RETURN_IF_ERR();
1882
1883 return PyLong_FromUnsignedLong(c_data.compact_pages_truncated);
1884}
1885#endif
1886
1887
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001888static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00001889DB_fd(DBObject* self)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001890{
1891 int err, the_fd;
1892
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001893 CHECK_DB_NOT_CLOSED(self);
1894
1895 MYDB_BEGIN_ALLOW_THREADS;
1896 err = self->db->fd(self->db, &the_fd);
1897 MYDB_END_ALLOW_THREADS;
1898 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00001899 return NUMBER_FromLong(the_fd);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001900}
1901
1902
Jesus Cea6557aac2010-03-22 14:22:26 +00001903#if (DBVER >= 46)
1904static PyObject*
1905DB_exists(DBObject* self, PyObject* args, PyObject* kwargs)
1906{
1907 int err, flags=0;
1908 PyObject* txnobj = NULL;
1909 PyObject* keyobj;
1910 DBT key;
1911 DB_TXN *txn;
1912
1913 static char* kwnames[] = {"key", "txn", "flags", NULL};
1914
1915 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|Oi:exists", kwnames,
1916 &keyobj, &txnobj, &flags))
1917 return NULL;
1918
1919 CHECK_DB_NOT_CLOSED(self);
1920 if (!make_key_dbt(self, keyobj, &key, NULL))
1921 return NULL;
1922 if (!checkTxnObj(txnobj, &txn)) {
1923 FREE_DBT(key);
1924 return NULL;
1925 }
1926
1927 MYDB_BEGIN_ALLOW_THREADS;
1928 err = self->db->exists(self->db, txn, &key, flags);
1929 MYDB_END_ALLOW_THREADS;
1930
1931 FREE_DBT(key);
1932
1933 if (!err) {
1934 Py_INCREF(Py_True);
1935 return Py_True;
1936 }
1937 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)) {
1938 Py_INCREF(Py_False);
1939 return Py_False;
1940 }
1941
1942 /*
1943 ** If we reach there, there was an error. The
1944 ** "return" should be unreachable.
1945 */
1946 RETURN_IF_ERR();
1947 assert(0); /* This coude SHOULD be unreachable */
1948 return NULL;
1949}
1950#endif
1951
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001952static PyObject*
1953DB_get(DBObject* self, PyObject* args, PyObject* kwargs)
1954{
1955 int err, flags=0;
1956 PyObject* txnobj = NULL;
1957 PyObject* keyobj;
1958 PyObject* dfltobj = NULL;
1959 PyObject* retval = NULL;
1960 int dlen = -1;
1961 int doff = -1;
1962 DBT key, data;
1963 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00001964 static char* kwnames[] = {"key", "default", "txn", "flags", "dlen",
Jeremy Hyltonaf68c872005-12-10 18:50:16 +00001965 "doff", NULL};
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001966
1967 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|OOiii:get", kwnames,
Barry Warsaw9a0d7792002-12-30 20:53:52 +00001968 &keyobj, &dfltobj, &txnobj, &flags, &dlen,
1969 &doff))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001970 return NULL;
1971
1972 CHECK_DB_NOT_CLOSED(self);
1973 if (!make_key_dbt(self, keyobj, &key, &flags))
1974 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00001975 if (!checkTxnObj(txnobj, &txn)) {
1976 FREE_DBT(key);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001977 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00001978 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001979
1980 CLEAR_DBT(data);
1981 if (CHECK_DBFLAG(self, DB_THREAD)) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00001982 /* Tell Berkeley DB to malloc the return value (thread safe) */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001983 data.flags = DB_DBT_MALLOC;
1984 }
Gregory P. Smithdc5af702004-06-27 23:32:34 +00001985 if (!add_partial_dbt(&data, dlen, doff)) {
1986 FREE_DBT(key);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001987 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00001988 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001989
1990 MYDB_BEGIN_ALLOW_THREADS;
1991 err = self->db->get(self->db, txn, &key, &data, flags);
1992 MYDB_END_ALLOW_THREADS;
1993
Gregory P. Smithe9477062005-06-04 06:46:59 +00001994 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY) && (dfltobj != NULL)) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001995 err = 0;
1996 Py_INCREF(dfltobj);
1997 retval = dfltobj;
1998 }
Gregory P. Smithe9477062005-06-04 06:46:59 +00001999 else if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002000 && self->moduleFlags.getReturnsNone) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002001 err = 0;
2002 Py_INCREF(Py_None);
2003 retval = Py_None;
2004 }
2005 else if (!err) {
2006 if (flags & DB_SET_RECNO) /* return both key and data */
Jesus Ceaef9764f2008-05-13 18:45:46 +00002007 retval = BuildValue_SS(key.data, key.size, data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002008 else /* return just the data */
Jesus Ceaef9764f2008-05-13 18:45:46 +00002009 retval = Build_PyString(data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002010 FREE_DBT(data);
2011 }
Gregory P. Smithdc5af702004-06-27 23:32:34 +00002012 FREE_DBT(key);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002013
2014 RETURN_IF_ERR();
2015 return retval;
2016}
2017
Gregory P. Smith19699a92004-06-28 04:06:49 +00002018static PyObject*
2019DB_pget(DBObject* self, PyObject* args, PyObject* kwargs)
2020{
2021 int err, flags=0;
2022 PyObject* txnobj = NULL;
2023 PyObject* keyobj;
2024 PyObject* dfltobj = NULL;
2025 PyObject* retval = NULL;
2026 int dlen = -1;
2027 int doff = -1;
2028 DBT key, pkey, data;
2029 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002030 static char* kwnames[] = {"key", "default", "txn", "flags", "dlen",
Jeremy Hyltonaf68c872005-12-10 18:50:16 +00002031 "doff", NULL};
Gregory P. Smith19699a92004-06-28 04:06:49 +00002032
2033 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|OOiii:pget", kwnames,
2034 &keyobj, &dfltobj, &txnobj, &flags, &dlen,
2035 &doff))
2036 return NULL;
2037
2038 CHECK_DB_NOT_CLOSED(self);
2039 if (!make_key_dbt(self, keyobj, &key, &flags))
2040 return NULL;
2041 if (!checkTxnObj(txnobj, &txn)) {
2042 FREE_DBT(key);
2043 return NULL;
2044 }
2045
2046 CLEAR_DBT(data);
2047 if (CHECK_DBFLAG(self, DB_THREAD)) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00002048 /* Tell Berkeley DB to malloc the return value (thread safe) */
Gregory P. Smith19699a92004-06-28 04:06:49 +00002049 data.flags = DB_DBT_MALLOC;
2050 }
2051 if (!add_partial_dbt(&data, dlen, doff)) {
2052 FREE_DBT(key);
2053 return NULL;
2054 }
2055
2056 CLEAR_DBT(pkey);
2057 pkey.flags = DB_DBT_MALLOC;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002058
Gregory P. Smith19699a92004-06-28 04:06:49 +00002059 MYDB_BEGIN_ALLOW_THREADS;
2060 err = self->db->pget(self->db, txn, &key, &pkey, &data, flags);
2061 MYDB_END_ALLOW_THREADS;
2062
Gregory P. Smithe9477062005-06-04 06:46:59 +00002063 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY) && (dfltobj != NULL)) {
Gregory P. Smith19699a92004-06-28 04:06:49 +00002064 err = 0;
2065 Py_INCREF(dfltobj);
2066 retval = dfltobj;
2067 }
Gregory P. Smithe9477062005-06-04 06:46:59 +00002068 else if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002069 && self->moduleFlags.getReturnsNone) {
Gregory P. Smith19699a92004-06-28 04:06:49 +00002070 err = 0;
2071 Py_INCREF(Py_None);
2072 retval = Py_None;
2073 }
2074 else if (!err) {
2075 PyObject *pkeyObj;
2076 PyObject *dataObj;
Jesus Ceaef9764f2008-05-13 18:45:46 +00002077 dataObj = Build_PyString(data.data, data.size);
Gregory P. Smith19699a92004-06-28 04:06:49 +00002078
2079 if (self->primaryDBType == DB_RECNO ||
2080 self->primaryDBType == DB_QUEUE)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002081 pkeyObj = NUMBER_FromLong(*(int *)pkey.data);
Gregory P. Smith19699a92004-06-28 04:06:49 +00002082 else
Jesus Ceaef9764f2008-05-13 18:45:46 +00002083 pkeyObj = Build_PyString(pkey.data, pkey.size);
Gregory P. Smith19699a92004-06-28 04:06:49 +00002084
2085 if (flags & DB_SET_RECNO) /* return key , pkey and data */
2086 {
2087 PyObject *keyObj;
2088 int type = _DB_get_type(self);
2089 if (type == DB_RECNO || type == DB_QUEUE)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002090 keyObj = NUMBER_FromLong(*(int *)key.data);
Gregory P. Smith19699a92004-06-28 04:06:49 +00002091 else
Jesus Ceaef9764f2008-05-13 18:45:46 +00002092 keyObj = Build_PyString(key.data, key.size);
Gregory P. Smith4e414d82006-01-24 19:55:02 +00002093 retval = PyTuple_Pack(3, keyObj, pkeyObj, dataObj);
Thomas Woutersb3153832006-03-08 01:47:19 +00002094 Py_DECREF(keyObj);
Gregory P. Smith19699a92004-06-28 04:06:49 +00002095 }
2096 else /* return just the pkey and data */
2097 {
Gregory P. Smith4e414d82006-01-24 19:55:02 +00002098 retval = PyTuple_Pack(2, pkeyObj, dataObj);
Gregory P. Smith19699a92004-06-28 04:06:49 +00002099 }
Thomas Woutersb3153832006-03-08 01:47:19 +00002100 Py_DECREF(dataObj);
2101 Py_DECREF(pkeyObj);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002102 FREE_DBT(pkey);
Gregory P. Smith19699a92004-06-28 04:06:49 +00002103 FREE_DBT(data);
2104 }
2105 FREE_DBT(key);
2106
2107 RETURN_IF_ERR();
2108 return retval;
2109}
2110
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002111
2112/* Return size of entry */
2113static PyObject*
2114DB_get_size(DBObject* self, PyObject* args, PyObject* kwargs)
2115{
2116 int err, flags=0;
2117 PyObject* txnobj = NULL;
2118 PyObject* keyobj;
2119 PyObject* retval = NULL;
2120 DBT key, data;
2121 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002122 static char* kwnames[] = { "key", "txn", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002123
2124 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O:get_size", kwnames,
2125 &keyobj, &txnobj))
2126 return NULL;
2127 CHECK_DB_NOT_CLOSED(self);
2128 if (!make_key_dbt(self, keyobj, &key, &flags))
2129 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00002130 if (!checkTxnObj(txnobj, &txn)) {
2131 FREE_DBT(key);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002132 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00002133 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002134 CLEAR_DBT(data);
2135
Gregory P. Smith8b7e9172004-12-13 09:51:23 +00002136 /* We don't allocate any memory, forcing a DB_BUFFER_SMALL error and
2137 thus getting the record size. */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002138 data.flags = DB_DBT_USERMEM;
2139 data.ulen = 0;
2140 MYDB_BEGIN_ALLOW_THREADS;
2141 err = self->db->get(self->db, txn, &key, &data, flags);
2142 MYDB_END_ALLOW_THREADS;
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07002143 if ((err == DB_BUFFER_SMALL) || (err == 0)) {
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002144 retval = NUMBER_FromLong((long)data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002145 err = 0;
2146 }
2147
2148 FREE_DBT(key);
2149 FREE_DBT(data);
2150 RETURN_IF_ERR();
2151 return retval;
2152}
2153
2154
2155static PyObject*
2156DB_get_both(DBObject* self, PyObject* args, PyObject* kwargs)
2157{
2158 int err, flags=0;
2159 PyObject* txnobj = NULL;
2160 PyObject* keyobj;
2161 PyObject* dataobj;
2162 PyObject* retval = NULL;
2163 DBT key, data;
Neal Norwitz994ebed2007-06-03 20:32:50 +00002164 void *orig_data;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002165 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002166 static char* kwnames[] = { "key", "data", "txn", "flags", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002167
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002168 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|Oi:get_both", kwnames,
2169 &keyobj, &dataobj, &txnobj, &flags))
2170 return NULL;
2171
2172 CHECK_DB_NOT_CLOSED(self);
2173 if (!make_key_dbt(self, keyobj, &key, NULL))
2174 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00002175 if ( !make_dbt(dataobj, &data) ||
2176 !checkTxnObj(txnobj, &txn) )
2177 {
2178 FREE_DBT(key);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002179 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00002180 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002181
2182 flags |= DB_GET_BOTH;
Neal Norwitz994ebed2007-06-03 20:32:50 +00002183 orig_data = data.data;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002184
2185 if (CHECK_DBFLAG(self, DB_THREAD)) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00002186 /* Tell Berkeley DB to malloc the return value (thread safe) */
Neal Norwitz994ebed2007-06-03 20:32:50 +00002187 /* XXX(nnorwitz): At least 4.4.20 and 4.5.20 require this flag. */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002188 data.flags = DB_DBT_MALLOC;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002189 }
2190
2191 MYDB_BEGIN_ALLOW_THREADS;
2192 err = self->db->get(self->db, txn, &key, &data, flags);
2193 MYDB_END_ALLOW_THREADS;
2194
Gregory P. Smithe9477062005-06-04 06:46:59 +00002195 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002196 && self->moduleFlags.getReturnsNone) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002197 err = 0;
2198 Py_INCREF(Py_None);
2199 retval = Py_None;
2200 }
2201 else if (!err) {
Neal Norwitz994ebed2007-06-03 20:32:50 +00002202 /* XXX(nnorwitz): can we do: retval = dataobj; Py_INCREF(retval); */
Jesus Ceaef9764f2008-05-13 18:45:46 +00002203 retval = Build_PyString(data.data, data.size);
Neal Norwitz994ebed2007-06-03 20:32:50 +00002204
2205 /* Even though the flags require DB_DBT_MALLOC, data is not always
2206 allocated. 4.4: allocated, 4.5: *not* allocated. :-( */
2207 if (data.data != orig_data)
2208 FREE_DBT(data);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002209 }
2210
2211 FREE_DBT(key);
2212 RETURN_IF_ERR();
2213 return retval;
2214}
2215
2216
2217static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002218DB_get_byteswapped(DBObject* self)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002219{
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002220 int err = 0;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002221 int retval = -1;
2222
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002223 CHECK_DB_NOT_CLOSED(self);
2224
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002225 MYDB_BEGIN_ALLOW_THREADS;
2226 err = self->db->get_byteswapped(self->db, &retval);
2227 MYDB_END_ALLOW_THREADS;
2228 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002229 return NUMBER_FromLong(retval);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002230}
2231
2232
2233static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002234DB_get_type(DBObject* self)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002235{
2236 int type;
2237
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002238 CHECK_DB_NOT_CLOSED(self);
2239
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002240 type = _DB_get_type(self);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002241 if (type == -1)
2242 return NULL;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002243 return NUMBER_FromLong(type);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002244}
2245
2246
2247static PyObject*
2248DB_join(DBObject* self, PyObject* args)
2249{
2250 int err, flags=0;
2251 int length, x;
2252 PyObject* cursorsObj;
2253 DBC** cursors;
2254 DBC* dbc;
2255
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002256 if (!PyArg_ParseTuple(args,"O|i:join", &cursorsObj, &flags))
2257 return NULL;
2258
2259 CHECK_DB_NOT_CLOSED(self);
2260
2261 if (!PySequence_Check(cursorsObj)) {
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002262 PyErr_SetString(PyExc_TypeError,
2263 "Sequence of DBCursor objects expected");
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002264 return NULL;
2265 }
2266
2267 length = PyObject_Length(cursorsObj);
2268 cursors = malloc((length+1) * sizeof(DBC*));
Neal Norwitz5aa96892006-08-13 18:11:43 +00002269 if (!cursors) {
Jesus Cea6557aac2010-03-22 14:22:26 +00002270 PyErr_NoMemory();
2271 return NULL;
Neal Norwitz5aa96892006-08-13 18:11:43 +00002272 }
2273
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002274 cursors[length] = NULL;
2275 for (x=0; x<length; x++) {
2276 PyObject* item = PySequence_GetItem(cursorsObj, x);
Thomas Woutersb3153832006-03-08 01:47:19 +00002277 if (item == NULL) {
2278 free(cursors);
2279 return NULL;
2280 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002281 if (!DBCursorObject_Check(item)) {
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002282 PyErr_SetString(PyExc_TypeError,
2283 "Sequence of DBCursor objects expected");
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002284 free(cursors);
2285 return NULL;
2286 }
2287 cursors[x] = ((DBCursorObject*)item)->dbc;
Thomas Woutersb2820ae2006-03-12 00:01:38 +00002288 Py_DECREF(item);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002289 }
2290
2291 MYDB_BEGIN_ALLOW_THREADS;
2292 err = self->db->join(self->db, cursors, &dbc, flags);
2293 MYDB_END_ALLOW_THREADS;
2294 free(cursors);
2295 RETURN_IF_ERR();
2296
Gregory P. Smith7441e652003-11-03 21:35:31 +00002297 /* FIXME: this is a buggy interface. The returned cursor
2298 contains internal references to the passed in cursors
2299 but does not hold python references to them or prevent
2300 them from being closed prematurely. This can cause
2301 python to crash when things are done in the wrong order. */
Jesus Ceaef9764f2008-05-13 18:45:46 +00002302 return (PyObject*) newDBCursorObject(dbc, NULL, self);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002303}
2304
2305
2306static PyObject*
2307DB_key_range(DBObject* self, PyObject* args, PyObject* kwargs)
2308{
2309 int err, flags=0;
2310 PyObject* txnobj = NULL;
2311 PyObject* keyobj;
2312 DBT key;
2313 DB_TXN *txn = NULL;
2314 DB_KEY_RANGE range;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002315 static char* kwnames[] = { "key", "txn", "flags", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002316
2317 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|Oi:key_range", kwnames,
2318 &keyobj, &txnobj, &flags))
2319 return NULL;
2320 CHECK_DB_NOT_CLOSED(self);
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002321 if (!make_dbt(keyobj, &key))
2322 /* BTree only, don't need to allow for an int key */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002323 return NULL;
2324 if (!checkTxnObj(txnobj, &txn))
2325 return NULL;
2326
2327 MYDB_BEGIN_ALLOW_THREADS;
2328 err = self->db->key_range(self->db, txn, &key, &range, flags);
2329 MYDB_END_ALLOW_THREADS;
2330
2331 RETURN_IF_ERR();
2332 return Py_BuildValue("ddd", range.less, range.equal, range.greater);
2333}
2334
2335
2336static PyObject*
2337DB_open(DBObject* self, PyObject* args, PyObject* kwargs)
2338{
2339 int err, type = DB_UNKNOWN, flags=0, mode=0660;
2340 char* filename = NULL;
2341 char* dbname = NULL;
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002342 PyObject *txnobj = NULL;
2343 DB_TXN *txn = NULL;
2344 /* with dbname */
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002345 static char* kwnames[] = {
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002346 "filename", "dbname", "dbtype", "flags", "mode", "txn", NULL};
2347 /* without dbname */
Tim Peters85b10522006-02-28 18:33:35 +00002348 static char* kwnames_basic[] = {
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002349 "filename", "dbtype", "flags", "mode", "txn", NULL};
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002350
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002351 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "z|ziiiO:open", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002352 &filename, &dbname, &type, &flags, &mode,
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002353 &txnobj))
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002354 {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002355 PyErr_Clear();
2356 type = DB_UNKNOWN; flags = 0; mode = 0660;
2357 filename = NULL; dbname = NULL;
2358 if (!PyArg_ParseTupleAndKeywords(args, kwargs,"z|iiiO:open",
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002359 kwnames_basic,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002360 &filename, &type, &flags, &mode,
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002361 &txnobj))
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002362 return NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002363 }
2364
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002365 if (!checkTxnObj(txnobj, &txn)) return NULL;
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002366
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002367 if (NULL == self->db) {
Thomas Woutersb3153832006-03-08 01:47:19 +00002368 PyObject *t = Py_BuildValue("(is)", 0,
2369 "Cannot call open() twice for DB object");
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002370 if (t) {
2371 PyErr_SetObject(DBError, t);
2372 Py_DECREF(t);
2373 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002374 return NULL;
2375 }
2376
Jesus Ceaef9764f2008-05-13 18:45:46 +00002377 if (txn) { /* Can't use 'txnobj' because could be 'txnobj==Py_None' */
2378 INSERT_IN_DOUBLE_LINKED_LIST_TXN(((DBTxnObject *)txnobj)->children_dbs,self);
2379 self->txn=(DBTxnObject *)txnobj;
2380 } else {
2381 self->txn=NULL;
2382 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00002383
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002384 MYDB_BEGIN_ALLOW_THREADS;
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002385 err = self->db->open(self->db, txn, filename, dbname, type, flags, mode);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002386 MYDB_END_ALLOW_THREADS;
Jesus Cea6557aac2010-03-22 14:22:26 +00002387
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002388 if (makeDBError(err)) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00002389 PyObject *dummy;
2390
Jesus Cea5cd5f122008-09-23 18:54:08 +00002391 dummy=DB_close_internal(self, 0, 0);
Jesus Ceaef9764f2008-05-13 18:45:46 +00002392 Py_XDECREF(dummy);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002393 return NULL;
2394 }
2395
Gregory P. Smithec10a4a2007-11-05 02:32:26 +00002396 self->db->get_flags(self->db, &self->setflags);
2397
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002398 self->flags = flags;
Jesus Ceaef9764f2008-05-13 18:45:46 +00002399
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002400 RETURN_NONE();
2401}
2402
2403
2404static PyObject*
2405DB_put(DBObject* self, PyObject* args, PyObject* kwargs)
2406{
2407 int flags=0;
2408 PyObject* txnobj = NULL;
2409 int dlen = -1;
2410 int doff = -1;
2411 PyObject* keyobj, *dataobj, *retval;
2412 DBT key, data;
2413 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002414 static char* kwnames[] = { "key", "data", "txn", "flags", "dlen",
Jeremy Hyltonaf68c872005-12-10 18:50:16 +00002415 "doff", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002416
2417 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|Oiii:put", kwnames,
2418 &keyobj, &dataobj, &txnobj, &flags, &dlen, &doff))
2419 return NULL;
2420
2421 CHECK_DB_NOT_CLOSED(self);
Gregory P. Smithdc5af702004-06-27 23:32:34 +00002422 if (!make_key_dbt(self, keyobj, &key, NULL))
2423 return NULL;
2424 if ( !make_dbt(dataobj, &data) ||
2425 !add_partial_dbt(&data, dlen, doff) ||
2426 !checkTxnObj(txnobj, &txn) )
2427 {
2428 FREE_DBT(key);
2429 return NULL;
2430 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002431
2432 if (-1 == _DB_put(self, txn, &key, &data, flags)) {
2433 FREE_DBT(key);
2434 return NULL;
2435 }
2436
2437 if (flags & DB_APPEND)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002438 retval = NUMBER_FromLong(*((db_recno_t*)key.data));
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002439 else {
2440 retval = Py_None;
2441 Py_INCREF(retval);
2442 }
2443 FREE_DBT(key);
2444 return retval;
2445}
2446
2447
2448
2449static PyObject*
2450DB_remove(DBObject* self, PyObject* args, PyObject* kwargs)
2451{
2452 char* filename;
2453 char* database = NULL;
2454 int err, flags=0;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002455 static char* kwnames[] = { "filename", "dbname", "flags", NULL};
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002456
2457 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|zi:remove", kwnames,
2458 &filename, &database, &flags))
2459 return NULL;
2460 CHECK_DB_NOT_CLOSED(self);
2461
Jesus Cea4907d272008-08-31 14:00:51 +00002462 EXTRACT_FROM_DOUBLE_LINKED_LIST_MAYBE_NULL(self);
2463
2464 MYDB_BEGIN_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002465 err = self->db->remove(self->db, filename, database, flags);
Jesus Cea4907d272008-08-31 14:00:51 +00002466 MYDB_END_ALLOW_THREADS;
2467
Gregory P. Smithf655dff2003-05-15 00:13:18 +00002468 self->db = NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002469 RETURN_IF_ERR();
2470 RETURN_NONE();
2471}
2472
2473
2474
2475static PyObject*
2476DB_rename(DBObject* self, PyObject* args)
2477{
2478 char* filename;
2479 char* database;
2480 char* newname;
2481 int err, flags=0;
2482
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002483 if (!PyArg_ParseTuple(args, "sss|i:rename", &filename, &database, &newname,
2484 &flags))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002485 return NULL;
2486 CHECK_DB_NOT_CLOSED(self);
2487
2488 MYDB_BEGIN_ALLOW_THREADS;
2489 err = self->db->rename(self->db, filename, database, newname, flags);
2490 MYDB_END_ALLOW_THREADS;
2491 RETURN_IF_ERR();
2492 RETURN_NONE();
2493}
2494
2495
2496static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002497DB_get_private(DBObject* self)
2498{
2499 /* We can give out the private field even if db is closed */
Jesus Cea4907d272008-08-31 14:00:51 +00002500 Py_INCREF(self->private_obj);
2501 return self->private_obj;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002502}
2503
2504static PyObject*
Jesus Cea4907d272008-08-31 14:00:51 +00002505DB_set_private(DBObject* self, PyObject* private_obj)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002506{
2507 /* We can set the private field even if db is closed */
Jesus Cea4907d272008-08-31 14:00:51 +00002508 Py_DECREF(self->private_obj);
2509 Py_INCREF(private_obj);
2510 self->private_obj = private_obj;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002511 RETURN_NONE();
2512}
2513
Jesus Cea6557aac2010-03-22 14:22:26 +00002514#if (DBVER >= 46)
2515static PyObject*
2516DB_set_priority(DBObject* self, PyObject* args)
2517{
2518 int err, priority;
2519
2520 if (!PyArg_ParseTuple(args,"i:set_priority", &priority))
2521 return NULL;
2522 CHECK_DB_NOT_CLOSED(self);
2523
2524 MYDB_BEGIN_ALLOW_THREADS;
2525 err = self->db->set_priority(self->db, priority);
2526 MYDB_END_ALLOW_THREADS;
2527 RETURN_IF_ERR();
2528 RETURN_NONE();
2529}
2530
2531static PyObject*
2532DB_get_priority(DBObject* self)
2533{
2534 int err = 0;
2535 DB_CACHE_PRIORITY priority;
2536
2537 CHECK_DB_NOT_CLOSED(self);
2538
2539 MYDB_BEGIN_ALLOW_THREADS;
2540 err = self->db->get_priority(self->db, &priority);
2541 MYDB_END_ALLOW_THREADS;
2542 RETURN_IF_ERR();
2543 return NUMBER_FromLong(priority);
2544}
2545#endif
2546
2547static PyObject*
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07002548DB_get_dbname(DBObject* self)
2549{
2550 int err;
2551 const char *filename, *dbname;
2552
2553 CHECK_DB_NOT_CLOSED(self);
2554
2555 MYDB_BEGIN_ALLOW_THREADS;
2556 err = self->db->get_dbname(self->db, &filename, &dbname);
2557 MYDB_END_ALLOW_THREADS;
2558 RETURN_IF_ERR();
2559 /* If "dbname==NULL", it is correctly converted to "None" */
2560 return Py_BuildValue("(ss)", filename, dbname);
2561}
2562
2563static PyObject*
2564DB_get_open_flags(DBObject* self)
2565{
2566 int err;
2567 unsigned int flags;
2568
2569 CHECK_DB_NOT_CLOSED(self);
2570
2571 MYDB_BEGIN_ALLOW_THREADS;
2572 err = self->db->get_open_flags(self->db, &flags);
2573 MYDB_END_ALLOW_THREADS;
2574 RETURN_IF_ERR();
2575 return NUMBER_FromLong(flags);
2576}
2577
2578static PyObject*
Jesus Cea6557aac2010-03-22 14:22:26 +00002579DB_set_q_extentsize(DBObject* self, PyObject* args)
2580{
2581 int err;
2582 u_int32_t extentsize;
2583
2584 if (!PyArg_ParseTuple(args,"i:set_q_extentsize", &extentsize))
2585 return NULL;
2586 CHECK_DB_NOT_CLOSED(self);
2587
2588 MYDB_BEGIN_ALLOW_THREADS;
2589 err = self->db->set_q_extentsize(self->db, extentsize);
2590 MYDB_END_ALLOW_THREADS;
2591 RETURN_IF_ERR();
2592 RETURN_NONE();
2593}
2594
Jesus Cea6557aac2010-03-22 14:22:26 +00002595static PyObject*
2596DB_get_q_extentsize(DBObject* self)
2597{
2598 int err = 0;
2599 u_int32_t extentsize;
2600
2601 CHECK_DB_NOT_CLOSED(self);
2602
2603 MYDB_BEGIN_ALLOW_THREADS;
2604 err = self->db->get_q_extentsize(self->db, &extentsize);
2605 MYDB_END_ALLOW_THREADS;
2606 RETURN_IF_ERR();
2607 return NUMBER_FromLong(extentsize);
2608}
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002609
2610static PyObject*
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002611DB_set_bt_minkey(DBObject* self, PyObject* args)
2612{
2613 int err, minkey;
2614
Jesus Cea6557aac2010-03-22 14:22:26 +00002615 if (!PyArg_ParseTuple(args,"i:set_bt_minkey", &minkey))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002616 return NULL;
2617 CHECK_DB_NOT_CLOSED(self);
2618
2619 MYDB_BEGIN_ALLOW_THREADS;
2620 err = self->db->set_bt_minkey(self->db, minkey);
2621 MYDB_END_ALLOW_THREADS;
2622 RETURN_IF_ERR();
2623 RETURN_NONE();
2624}
2625
Jesus Cea6557aac2010-03-22 14:22:26 +00002626static PyObject*
2627DB_get_bt_minkey(DBObject* self)
2628{
2629 int err;
2630 u_int32_t bt_minkey;
2631
2632 CHECK_DB_NOT_CLOSED(self);
2633
2634 MYDB_BEGIN_ALLOW_THREADS;
2635 err = self->db->get_bt_minkey(self->db, &bt_minkey);
2636 MYDB_END_ALLOW_THREADS;
2637 RETURN_IF_ERR();
2638 return NUMBER_FromLong(bt_minkey);
2639}
Jesus Cea6557aac2010-03-22 14:22:26 +00002640
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002641static int
Georg Brandlef1701f2006-03-07 14:57:48 +00002642_default_cmp(const DBT *leftKey,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002643 const DBT *rightKey)
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002644{
2645 int res;
2646 int lsize = leftKey->size, rsize = rightKey->size;
2647
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002648 res = memcmp(leftKey->data, rightKey->data,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002649 lsize < rsize ? lsize : rsize);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002650
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002651 if (res == 0) {
2652 if (lsize < rsize) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002653 res = -1;
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002654 }
2655 else if (lsize > rsize) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002656 res = 1;
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002657 }
2658 }
2659 return res;
2660}
2661
2662static int
Jesus Ceaef9764f2008-05-13 18:45:46 +00002663_db_compareCallback(DB* db,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002664 const DBT *leftKey,
2665 const DBT *rightKey)
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002666{
2667 int res = 0;
2668 PyObject *args;
Thomas Woutersb2820ae2006-03-12 00:01:38 +00002669 PyObject *result = NULL;
Georg Brandlef1701f2006-03-07 14:57:48 +00002670 DBObject *self = (DBObject *)db->app_private;
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002671
2672 if (self == NULL || self->btCompareCallback == NULL) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002673 MYDB_BEGIN_BLOCK_THREADS;
2674 PyErr_SetString(PyExc_TypeError,
2675 (self == 0
2676 ? "DB_bt_compare db is NULL."
2677 : "DB_bt_compare callback is NULL."));
2678 /* we're in a callback within the DB code, we can't raise */
2679 PyErr_Print();
2680 res = _default_cmp(leftKey, rightKey);
2681 MYDB_END_BLOCK_THREADS;
Georg Brandlef1701f2006-03-07 14:57:48 +00002682 } else {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002683 MYDB_BEGIN_BLOCK_THREADS;
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002684
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002685 args = BuildValue_SS(leftKey->data, leftKey->size, rightKey->data, rightKey->size);
2686 if (args != NULL) {
2687 result = PyEval_CallObject(self->btCompareCallback, args);
2688 }
2689 if (args == NULL || result == NULL) {
2690 /* we're in a callback within the DB code, we can't raise */
2691 PyErr_Print();
2692 res = _default_cmp(leftKey, rightKey);
2693 } else if (NUMBER_Check(result)) {
2694 res = NUMBER_AsLong(result);
2695 } else {
2696 PyErr_SetString(PyExc_TypeError,
2697 "DB_bt_compare callback MUST return an int.");
2698 /* we're in a callback within the DB code, we can't raise */
2699 PyErr_Print();
2700 res = _default_cmp(leftKey, rightKey);
2701 }
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002702
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002703 Py_XDECREF(args);
2704 Py_XDECREF(result);
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002705
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002706 MYDB_END_BLOCK_THREADS;
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002707 }
2708 return res;
2709}
2710
2711static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002712DB_set_bt_compare(DBObject* self, PyObject* comparator)
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002713{
2714 int err;
Thomas Woutersb3153832006-03-08 01:47:19 +00002715 PyObject *tuple, *result;
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002716
Georg Brandlef1701f2006-03-07 14:57:48 +00002717 CHECK_DB_NOT_CLOSED(self);
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002718
Georg Brandlef1701f2006-03-07 14:57:48 +00002719 if (!PyCallable_Check(comparator)) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002720 makeTypeError("Callable", comparator);
2721 return NULL;
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002722 }
2723
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002724 /*
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002725 * Perform a test call of the comparator function with two empty
2726 * string objects here. verify that it returns an int (0).
2727 * err if not.
2728 */
Thomas Woutersb3153832006-03-08 01:47:19 +00002729 tuple = Py_BuildValue("(ss)", "", "");
Georg Brandlef1701f2006-03-07 14:57:48 +00002730 result = PyEval_CallObject(comparator, tuple);
2731 Py_DECREF(tuple);
Thomas Woutersb3153832006-03-08 01:47:19 +00002732 if (result == NULL)
2733 return NULL;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002734 if (!NUMBER_Check(result)) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002735 Py_DECREF(result);
2736 PyErr_SetString(PyExc_TypeError,
2737 "callback MUST return an int");
2738 return NULL;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002739 } else if (NUMBER_AsLong(result) != 0) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002740 Py_DECREF(result);
2741 PyErr_SetString(PyExc_TypeError,
2742 "callback failed to return 0 on two empty strings");
2743 return NULL;
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002744 }
Thomas Woutersb3153832006-03-08 01:47:19 +00002745 Py_DECREF(result);
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002746
2747 /* We don't accept multiple set_bt_compare operations, in order to
2748 * simplify the code. This would have no real use, as one cannot
2749 * change the function once the db is opened anyway */
2750 if (self->btCompareCallback != NULL) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002751 PyErr_SetString(PyExc_RuntimeError, "set_bt_compare() cannot be called more than once");
2752 return NULL;
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002753 }
2754
Georg Brandlef1701f2006-03-07 14:57:48 +00002755 Py_INCREF(comparator);
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002756 self->btCompareCallback = comparator;
2757
2758 /* This is to workaround a problem with un-initialized threads (see
2759 comment in DB_associate) */
2760#ifdef WITH_THREAD
2761 PyEval_InitThreads();
2762#endif
2763
Thomas Woutersb3153832006-03-08 01:47:19 +00002764 err = self->db->set_bt_compare(self->db, _db_compareCallback);
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002765
2766 if (err) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002767 /* restore the old state in case of error */
2768 Py_DECREF(comparator);
2769 self->btCompareCallback = NULL;
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002770 }
2771
Georg Brandlef1701f2006-03-07 14:57:48 +00002772 RETURN_IF_ERR();
2773 RETURN_NONE();
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002774}
2775
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07002776static int
2777_db_dupCompareCallback(DB* db,
2778 const DBT *leftKey,
2779 const DBT *rightKey)
2780{
2781 int res = 0;
2782 PyObject *args;
2783 PyObject *result = NULL;
2784 DBObject *self = (DBObject *)db->app_private;
2785
2786 if (self == NULL || self->dupCompareCallback == NULL) {
2787 MYDB_BEGIN_BLOCK_THREADS;
2788 PyErr_SetString(PyExc_TypeError,
2789 (self == 0
2790 ? "DB_dup_compare db is NULL."
2791 : "DB_dup_compare callback is NULL."));
2792 /* we're in a callback within the DB code, we can't raise */
2793 PyErr_Print();
2794 res = _default_cmp(leftKey, rightKey);
2795 MYDB_END_BLOCK_THREADS;
2796 } else {
2797 MYDB_BEGIN_BLOCK_THREADS;
2798
2799 args = BuildValue_SS(leftKey->data, leftKey->size, rightKey->data, rightKey->size);
2800 if (args != NULL) {
2801 result = PyEval_CallObject(self->dupCompareCallback, args);
2802 }
2803 if (args == NULL || result == NULL) {
2804 /* we're in a callback within the DB code, we can't raise */
2805 PyErr_Print();
2806 res = _default_cmp(leftKey, rightKey);
2807 } else if (NUMBER_Check(result)) {
2808 res = NUMBER_AsLong(result);
2809 } else {
2810 PyErr_SetString(PyExc_TypeError,
2811 "DB_dup_compare callback MUST return an int.");
2812 /* we're in a callback within the DB code, we can't raise */
2813 PyErr_Print();
2814 res = _default_cmp(leftKey, rightKey);
2815 }
2816
2817 Py_XDECREF(args);
2818 Py_XDECREF(result);
2819
2820 MYDB_END_BLOCK_THREADS;
2821 }
2822 return res;
2823}
2824
2825static PyObject*
2826DB_set_dup_compare(DBObject* self, PyObject* comparator)
2827{
2828 int err;
2829 PyObject *tuple, *result;
2830
2831 CHECK_DB_NOT_CLOSED(self);
2832
2833 if (!PyCallable_Check(comparator)) {
2834 makeTypeError("Callable", comparator);
2835 return NULL;
2836 }
2837
2838 /*
2839 * Perform a test call of the comparator function with two empty
2840 * string objects here. verify that it returns an int (0).
2841 * err if not.
2842 */
2843 tuple = Py_BuildValue("(ss)", "", "");
2844 result = PyEval_CallObject(comparator, tuple);
2845 Py_DECREF(tuple);
2846 if (result == NULL)
2847 return NULL;
2848 if (!NUMBER_Check(result)) {
2849 Py_DECREF(result);
2850 PyErr_SetString(PyExc_TypeError,
2851 "callback MUST return an int");
2852 return NULL;
2853 } else if (NUMBER_AsLong(result) != 0) {
2854 Py_DECREF(result);
2855 PyErr_SetString(PyExc_TypeError,
2856 "callback failed to return 0 on two empty strings");
2857 return NULL;
2858 }
2859 Py_DECREF(result);
2860
2861 /* We don't accept multiple set_dup_compare operations, in order to
2862 * simplify the code. This would have no real use, as one cannot
2863 * change the function once the db is opened anyway */
2864 if (self->dupCompareCallback != NULL) {
2865 PyErr_SetString(PyExc_RuntimeError, "set_dup_compare() cannot be called more than once");
2866 return NULL;
2867 }
2868
2869 Py_INCREF(comparator);
2870 self->dupCompareCallback = comparator;
2871
2872 /* This is to workaround a problem with un-initialized threads (see
2873 comment in DB_associate) */
2874#ifdef WITH_THREAD
2875 PyEval_InitThreads();
2876#endif
2877
2878 err = self->db->set_dup_compare(self->db, _db_dupCompareCallback);
2879
2880 if (err) {
2881 /* restore the old state in case of error */
2882 Py_DECREF(comparator);
2883 self->dupCompareCallback = NULL;
2884 }
2885
2886 RETURN_IF_ERR();
2887 RETURN_NONE();
2888}
2889
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002890
2891static PyObject*
2892DB_set_cachesize(DBObject* self, PyObject* args)
2893{
2894 int err;
2895 int gbytes = 0, bytes = 0, ncache = 0;
2896
2897 if (!PyArg_ParseTuple(args,"ii|i:set_cachesize",
2898 &gbytes,&bytes,&ncache))
2899 return NULL;
2900 CHECK_DB_NOT_CLOSED(self);
2901
2902 MYDB_BEGIN_ALLOW_THREADS;
2903 err = self->db->set_cachesize(self->db, gbytes, bytes, ncache);
2904 MYDB_END_ALLOW_THREADS;
2905 RETURN_IF_ERR();
2906 RETURN_NONE();
2907}
2908
Jesus Cea6557aac2010-03-22 14:22:26 +00002909static PyObject*
2910DB_get_cachesize(DBObject* self)
2911{
2912 int err;
2913 u_int32_t gbytes, bytes;
2914 int ncache;
2915
2916 CHECK_DB_NOT_CLOSED(self);
2917
2918 MYDB_BEGIN_ALLOW_THREADS;
2919 err = self->db->get_cachesize(self->db, &gbytes, &bytes, &ncache);
2920 MYDB_END_ALLOW_THREADS;
2921
2922 RETURN_IF_ERR();
2923
2924 return Py_BuildValue("(iii)", gbytes, bytes, ncache);
2925}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002926
2927static PyObject*
2928DB_set_flags(DBObject* self, PyObject* args)
2929{
2930 int err, flags;
2931
2932 if (!PyArg_ParseTuple(args,"i:set_flags", &flags))
2933 return NULL;
2934 CHECK_DB_NOT_CLOSED(self);
2935
2936 MYDB_BEGIN_ALLOW_THREADS;
2937 err = self->db->set_flags(self->db, flags);
2938 MYDB_END_ALLOW_THREADS;
2939 RETURN_IF_ERR();
2940
2941 self->setflags |= flags;
2942 RETURN_NONE();
2943}
2944
Jesus Cea6557aac2010-03-22 14:22:26 +00002945static PyObject*
2946DB_get_flags(DBObject* self)
2947{
2948 int err;
2949 u_int32_t flags;
2950
2951 CHECK_DB_NOT_CLOSED(self);
2952
2953 MYDB_BEGIN_ALLOW_THREADS;
2954 err = self->db->get_flags(self->db, &flags);
2955 MYDB_END_ALLOW_THREADS;
2956 RETURN_IF_ERR();
2957 return NUMBER_FromLong(flags);
2958}
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07002959
2960static PyObject*
2961DB_get_transactional(DBObject* self)
2962{
2963 int err;
2964
2965 CHECK_DB_NOT_CLOSED(self);
2966
2967 MYDB_BEGIN_ALLOW_THREADS;
2968 err = self->db->get_transactional(self->db);
2969 MYDB_END_ALLOW_THREADS;
2970
2971 if(err == 0) {
2972 Py_INCREF(Py_False);
2973 return Py_False;
2974 } else if(err == 1) {
2975 Py_INCREF(Py_True);
2976 return Py_True;
2977 }
2978
2979 /*
2980 ** If we reach there, there was an error. The
2981 ** "return" should be unreachable.
2982 */
2983 RETURN_IF_ERR();
2984 assert(0); /* This code SHOULD be unreachable */
2985 return NULL;
2986}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002987
2988static PyObject*
2989DB_set_h_ffactor(DBObject* self, PyObject* args)
2990{
2991 int err, ffactor;
2992
2993 if (!PyArg_ParseTuple(args,"i:set_h_ffactor", &ffactor))
2994 return NULL;
2995 CHECK_DB_NOT_CLOSED(self);
2996
2997 MYDB_BEGIN_ALLOW_THREADS;
2998 err = self->db->set_h_ffactor(self->db, ffactor);
2999 MYDB_END_ALLOW_THREADS;
3000 RETURN_IF_ERR();
3001 RETURN_NONE();
3002}
3003
Jesus Cea6557aac2010-03-22 14:22:26 +00003004static PyObject*
3005DB_get_h_ffactor(DBObject* self)
3006{
3007 int err;
3008 u_int32_t ffactor;
3009
3010 CHECK_DB_NOT_CLOSED(self);
3011
3012 MYDB_BEGIN_ALLOW_THREADS;
3013 err = self->db->get_h_ffactor(self->db, &ffactor);
3014 MYDB_END_ALLOW_THREADS;
3015 RETURN_IF_ERR();
3016 return NUMBER_FromLong(ffactor);
3017}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003018
3019static PyObject*
3020DB_set_h_nelem(DBObject* self, PyObject* args)
3021{
3022 int err, nelem;
3023
3024 if (!PyArg_ParseTuple(args,"i:set_h_nelem", &nelem))
3025 return NULL;
3026 CHECK_DB_NOT_CLOSED(self);
3027
3028 MYDB_BEGIN_ALLOW_THREADS;
3029 err = self->db->set_h_nelem(self->db, nelem);
3030 MYDB_END_ALLOW_THREADS;
3031 RETURN_IF_ERR();
3032 RETURN_NONE();
3033}
3034
Jesus Cea6557aac2010-03-22 14:22:26 +00003035static PyObject*
3036DB_get_h_nelem(DBObject* self)
3037{
3038 int err;
3039 u_int32_t nelem;
3040
3041 CHECK_DB_NOT_CLOSED(self);
3042
3043 MYDB_BEGIN_ALLOW_THREADS;
3044 err = self->db->get_h_nelem(self->db, &nelem);
3045 MYDB_END_ALLOW_THREADS;
3046 RETURN_IF_ERR();
3047 return NUMBER_FromLong(nelem);
3048}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003049
3050static PyObject*
3051DB_set_lorder(DBObject* self, PyObject* args)
3052{
3053 int err, lorder;
3054
3055 if (!PyArg_ParseTuple(args,"i:set_lorder", &lorder))
3056 return NULL;
3057 CHECK_DB_NOT_CLOSED(self);
3058
3059 MYDB_BEGIN_ALLOW_THREADS;
3060 err = self->db->set_lorder(self->db, lorder);
3061 MYDB_END_ALLOW_THREADS;
3062 RETURN_IF_ERR();
3063 RETURN_NONE();
3064}
3065
Jesus Cea6557aac2010-03-22 14:22:26 +00003066static PyObject*
3067DB_get_lorder(DBObject* self)
3068{
3069 int err;
3070 int lorder;
3071
3072 CHECK_DB_NOT_CLOSED(self);
3073
3074 MYDB_BEGIN_ALLOW_THREADS;
3075 err = self->db->get_lorder(self->db, &lorder);
3076 MYDB_END_ALLOW_THREADS;
3077 RETURN_IF_ERR();
3078 return NUMBER_FromLong(lorder);
3079}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003080
3081static PyObject*
3082DB_set_pagesize(DBObject* self, PyObject* args)
3083{
3084 int err, pagesize;
3085
3086 if (!PyArg_ParseTuple(args,"i:set_pagesize", &pagesize))
3087 return NULL;
3088 CHECK_DB_NOT_CLOSED(self);
3089
3090 MYDB_BEGIN_ALLOW_THREADS;
3091 err = self->db->set_pagesize(self->db, pagesize);
3092 MYDB_END_ALLOW_THREADS;
3093 RETURN_IF_ERR();
3094 RETURN_NONE();
3095}
3096
Jesus Cea6557aac2010-03-22 14:22:26 +00003097static PyObject*
3098DB_get_pagesize(DBObject* self)
3099{
3100 int err;
3101 u_int32_t pagesize;
3102
3103 CHECK_DB_NOT_CLOSED(self);
3104
3105 MYDB_BEGIN_ALLOW_THREADS;
3106 err = self->db->get_pagesize(self->db, &pagesize);
3107 MYDB_END_ALLOW_THREADS;
3108 RETURN_IF_ERR();
3109 return NUMBER_FromLong(pagesize);
3110}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003111
3112static PyObject*
3113DB_set_re_delim(DBObject* self, PyObject* args)
3114{
3115 int err;
3116 char delim;
3117
3118 if (!PyArg_ParseTuple(args,"b:set_re_delim", &delim)) {
3119 PyErr_Clear();
3120 if (!PyArg_ParseTuple(args,"c:set_re_delim", &delim))
3121 return NULL;
3122 }
3123
3124 CHECK_DB_NOT_CLOSED(self);
3125
3126 MYDB_BEGIN_ALLOW_THREADS;
3127 err = self->db->set_re_delim(self->db, delim);
3128 MYDB_END_ALLOW_THREADS;
3129 RETURN_IF_ERR();
3130 RETURN_NONE();
3131}
3132
Jesus Cea6557aac2010-03-22 14:22:26 +00003133static PyObject*
3134DB_get_re_delim(DBObject* self)
3135{
3136 int err, re_delim;
3137
3138 CHECK_DB_NOT_CLOSED(self);
3139
3140 MYDB_BEGIN_ALLOW_THREADS;
3141 err = self->db->get_re_delim(self->db, &re_delim);
3142 MYDB_END_ALLOW_THREADS;
3143 RETURN_IF_ERR();
3144 return NUMBER_FromLong(re_delim);
3145}
Jesus Cea6557aac2010-03-22 14:22:26 +00003146
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003147static PyObject*
3148DB_set_re_len(DBObject* self, PyObject* args)
3149{
3150 int err, len;
3151
3152 if (!PyArg_ParseTuple(args,"i:set_re_len", &len))
3153 return NULL;
3154 CHECK_DB_NOT_CLOSED(self);
3155
3156 MYDB_BEGIN_ALLOW_THREADS;
3157 err = self->db->set_re_len(self->db, len);
3158 MYDB_END_ALLOW_THREADS;
3159 RETURN_IF_ERR();
3160 RETURN_NONE();
3161}
3162
Jesus Cea6557aac2010-03-22 14:22:26 +00003163static PyObject*
3164DB_get_re_len(DBObject* self)
3165{
3166 int err;
3167 u_int32_t re_len;
3168
3169 CHECK_DB_NOT_CLOSED(self);
3170
3171 MYDB_BEGIN_ALLOW_THREADS;
3172 err = self->db->get_re_len(self->db, &re_len);
3173 MYDB_END_ALLOW_THREADS;
3174 RETURN_IF_ERR();
3175 return NUMBER_FromLong(re_len);
3176}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003177
3178static PyObject*
3179DB_set_re_pad(DBObject* self, PyObject* args)
3180{
3181 int err;
3182 char pad;
3183
3184 if (!PyArg_ParseTuple(args,"b:set_re_pad", &pad)) {
3185 PyErr_Clear();
3186 if (!PyArg_ParseTuple(args,"c:set_re_pad", &pad))
3187 return NULL;
3188 }
3189 CHECK_DB_NOT_CLOSED(self);
3190
3191 MYDB_BEGIN_ALLOW_THREADS;
3192 err = self->db->set_re_pad(self->db, pad);
3193 MYDB_END_ALLOW_THREADS;
3194 RETURN_IF_ERR();
3195 RETURN_NONE();
3196}
3197
Jesus Cea6557aac2010-03-22 14:22:26 +00003198static PyObject*
3199DB_get_re_pad(DBObject* self)
3200{
3201 int err, re_pad;
3202
3203 CHECK_DB_NOT_CLOSED(self);
3204
3205 MYDB_BEGIN_ALLOW_THREADS;
3206 err = self->db->get_re_pad(self->db, &re_pad);
3207 MYDB_END_ALLOW_THREADS;
3208 RETURN_IF_ERR();
3209 return NUMBER_FromLong(re_pad);
3210}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003211
3212static PyObject*
3213DB_set_re_source(DBObject* self, PyObject* args)
3214{
3215 int err;
Jesus Cea6557aac2010-03-22 14:22:26 +00003216 char *source;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003217
Jesus Cea6557aac2010-03-22 14:22:26 +00003218 if (!PyArg_ParseTuple(args,"s:set_re_source", &source))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003219 return NULL;
3220 CHECK_DB_NOT_CLOSED(self);
3221
3222 MYDB_BEGIN_ALLOW_THREADS;
Jesus Cea6557aac2010-03-22 14:22:26 +00003223 err = self->db->set_re_source(self->db, source);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003224 MYDB_END_ALLOW_THREADS;
3225 RETURN_IF_ERR();
3226 RETURN_NONE();
3227}
3228
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003229static PyObject*
Jesus Cea6557aac2010-03-22 14:22:26 +00003230DB_get_re_source(DBObject* self)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003231{
3232 int err;
Jesus Cea6557aac2010-03-22 14:22:26 +00003233 const char *source;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003234
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003235 CHECK_DB_NOT_CLOSED(self);
3236
3237 MYDB_BEGIN_ALLOW_THREADS;
Jesus Cea6557aac2010-03-22 14:22:26 +00003238 err = self->db->get_re_source(self->db, &source);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003239 MYDB_END_ALLOW_THREADS;
3240 RETURN_IF_ERR();
Jesus Cea6557aac2010-03-22 14:22:26 +00003241 return PyBytes_FromString(source);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003242}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003243
3244static PyObject*
Gregory P. Smith8b7e9172004-12-13 09:51:23 +00003245DB_stat(DBObject* self, PyObject* args, PyObject* kwargs)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003246{
3247 int err, flags = 0, type;
3248 void* sp;
3249 PyObject* d;
Gregory P. Smith8b7e9172004-12-13 09:51:23 +00003250 PyObject* txnobj = NULL;
3251 DB_TXN *txn = NULL;
Gregory P. Smith2fa06792006-09-19 17:35:04 +00003252 static char* kwnames[] = { "flags", "txn", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003253
Gregory P. Smith8b7e9172004-12-13 09:51:23 +00003254 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|iO:stat", kwnames,
3255 &flags, &txnobj))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003256 return NULL;
Gregory P. Smith8b7e9172004-12-13 09:51:23 +00003257 if (!checkTxnObj(txnobj, &txn))
3258 return NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003259 CHECK_DB_NOT_CLOSED(self);
3260
3261 MYDB_BEGIN_ALLOW_THREADS;
Gregory P. Smith8b7e9172004-12-13 09:51:23 +00003262 err = self->db->stat(self->db, txn, &sp, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003263 MYDB_END_ALLOW_THREADS;
3264 RETURN_IF_ERR();
3265
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003266 /* Turn the stat structure into a dictionary */
3267 type = _DB_get_type(self);
3268 if ((type == -1) || ((d = PyDict_New()) == NULL)) {
3269 free(sp);
3270 return NULL;
3271 }
3272
3273#define MAKE_HASH_ENTRY(name) _addIntToDict(d, #name, ((DB_HASH_STAT*)sp)->hash_##name)
3274#define MAKE_BT_ENTRY(name) _addIntToDict(d, #name, ((DB_BTREE_STAT*)sp)->bt_##name)
3275#define MAKE_QUEUE_ENTRY(name) _addIntToDict(d, #name, ((DB_QUEUE_STAT*)sp)->qs_##name)
3276
3277 switch (type) {
3278 case DB_HASH:
3279 MAKE_HASH_ENTRY(magic);
3280 MAKE_HASH_ENTRY(version);
3281 MAKE_HASH_ENTRY(nkeys);
3282 MAKE_HASH_ENTRY(ndata);
Jesus Ceaef9764f2008-05-13 18:45:46 +00003283#if (DBVER >= 46)
3284 MAKE_HASH_ENTRY(pagecnt);
3285#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003286 MAKE_HASH_ENTRY(pagesize);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003287 MAKE_HASH_ENTRY(ffactor);
3288 MAKE_HASH_ENTRY(buckets);
3289 MAKE_HASH_ENTRY(free);
3290 MAKE_HASH_ENTRY(bfree);
3291 MAKE_HASH_ENTRY(bigpages);
3292 MAKE_HASH_ENTRY(big_bfree);
3293 MAKE_HASH_ENTRY(overflows);
3294 MAKE_HASH_ENTRY(ovfl_free);
3295 MAKE_HASH_ENTRY(dup);
3296 MAKE_HASH_ENTRY(dup_free);
3297 break;
3298
3299 case DB_BTREE:
3300 case DB_RECNO:
3301 MAKE_BT_ENTRY(magic);
3302 MAKE_BT_ENTRY(version);
3303 MAKE_BT_ENTRY(nkeys);
3304 MAKE_BT_ENTRY(ndata);
Jesus Ceaef9764f2008-05-13 18:45:46 +00003305#if (DBVER >= 46)
3306 MAKE_BT_ENTRY(pagecnt);
3307#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003308 MAKE_BT_ENTRY(pagesize);
3309 MAKE_BT_ENTRY(minkey);
3310 MAKE_BT_ENTRY(re_len);
3311 MAKE_BT_ENTRY(re_pad);
3312 MAKE_BT_ENTRY(levels);
3313 MAKE_BT_ENTRY(int_pg);
3314 MAKE_BT_ENTRY(leaf_pg);
3315 MAKE_BT_ENTRY(dup_pg);
3316 MAKE_BT_ENTRY(over_pg);
Jesus Ceaef9764f2008-05-13 18:45:46 +00003317 MAKE_BT_ENTRY(empty_pg);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003318 MAKE_BT_ENTRY(free);
3319 MAKE_BT_ENTRY(int_pgfree);
3320 MAKE_BT_ENTRY(leaf_pgfree);
3321 MAKE_BT_ENTRY(dup_pgfree);
3322 MAKE_BT_ENTRY(over_pgfree);
3323 break;
3324
3325 case DB_QUEUE:
3326 MAKE_QUEUE_ENTRY(magic);
3327 MAKE_QUEUE_ENTRY(version);
3328 MAKE_QUEUE_ENTRY(nkeys);
3329 MAKE_QUEUE_ENTRY(ndata);
3330 MAKE_QUEUE_ENTRY(pagesize);
Jesus Ceaef9764f2008-05-13 18:45:46 +00003331 MAKE_QUEUE_ENTRY(extentsize);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003332 MAKE_QUEUE_ENTRY(pages);
3333 MAKE_QUEUE_ENTRY(re_len);
3334 MAKE_QUEUE_ENTRY(re_pad);
3335 MAKE_QUEUE_ENTRY(pgfree);
3336#if (DBVER == 31)
3337 MAKE_QUEUE_ENTRY(start);
3338#endif
3339 MAKE_QUEUE_ENTRY(first_recno);
3340 MAKE_QUEUE_ENTRY(cur_recno);
3341 break;
3342
3343 default:
3344 PyErr_SetString(PyExc_TypeError, "Unknown DB type, unable to stat");
3345 Py_DECREF(d);
3346 d = NULL;
3347 }
3348
3349#undef MAKE_HASH_ENTRY
3350#undef MAKE_BT_ENTRY
3351#undef MAKE_QUEUE_ENTRY
3352
3353 free(sp);
3354 return d;
3355}
3356
Jesus Cea6557aac2010-03-22 14:22:26 +00003357static PyObject*
3358DB_stat_print(DBObject* self, PyObject* args, PyObject *kwargs)
3359{
3360 int err;
3361 int flags=0;
3362 static char* kwnames[] = { "flags", NULL };
3363
3364 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:stat_print",
3365 kwnames, &flags))
3366 {
3367 return NULL;
3368 }
3369 CHECK_DB_NOT_CLOSED(self);
3370 MYDB_BEGIN_ALLOW_THREADS;
3371 err = self->db->stat_print(self->db, flags);
3372 MYDB_END_ALLOW_THREADS;
3373 RETURN_IF_ERR();
3374 RETURN_NONE();
3375}
Jesus Cea6557aac2010-03-22 14:22:26 +00003376
3377
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003378static PyObject*
3379DB_sync(DBObject* self, PyObject* args)
3380{
3381 int err;
3382 int flags = 0;
3383
3384 if (!PyArg_ParseTuple(args,"|i:sync", &flags ))
3385 return NULL;
3386 CHECK_DB_NOT_CLOSED(self);
3387
3388 MYDB_BEGIN_ALLOW_THREADS;
3389 err = self->db->sync(self->db, flags);
3390 MYDB_END_ALLOW_THREADS;
3391 RETURN_IF_ERR();
3392 RETURN_NONE();
3393}
3394
3395
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003396static PyObject*
3397DB_truncate(DBObject* self, PyObject* args, PyObject* kwargs)
3398{
3399 int err, flags=0;
3400 u_int32_t count=0;
3401 PyObject* txnobj = NULL;
3402 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003403 static char* kwnames[] = { "txn", "flags", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003404
3405 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Oi:cursor", kwnames,
3406 &txnobj, &flags))
3407 return NULL;
3408 CHECK_DB_NOT_CLOSED(self);
3409 if (!checkTxnObj(txnobj, &txn))
3410 return NULL;
3411
3412 MYDB_BEGIN_ALLOW_THREADS;
3413 err = self->db->truncate(self->db, txn, &count, flags);
3414 MYDB_END_ALLOW_THREADS;
3415 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00003416 return NUMBER_FromLong(count);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003417}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003418
3419
3420static PyObject*
3421DB_upgrade(DBObject* self, PyObject* args)
3422{
3423 int err, flags=0;
3424 char *filename;
3425
3426 if (!PyArg_ParseTuple(args,"s|i:upgrade", &filename, &flags))
3427 return NULL;
3428 CHECK_DB_NOT_CLOSED(self);
3429
3430 MYDB_BEGIN_ALLOW_THREADS;
3431 err = self->db->upgrade(self->db, filename, flags);
3432 MYDB_END_ALLOW_THREADS;
3433 RETURN_IF_ERR();
3434 RETURN_NONE();
3435}
3436
3437
3438static PyObject*
3439DB_verify(DBObject* self, PyObject* args, PyObject* kwargs)
3440{
3441 int err, flags=0;
3442 char* fileName;
3443 char* dbName=NULL;
3444 char* outFileName=NULL;
3445 FILE* outFile=NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003446 static char* kwnames[] = { "filename", "dbname", "outfile", "flags",
Jeremy Hyltonaf68c872005-12-10 18:50:16 +00003447 NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003448
3449 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|zzi:verify", kwnames,
3450 &fileName, &dbName, &outFileName, &flags))
3451 return NULL;
3452
3453 CHECK_DB_NOT_CLOSED(self);
3454 if (outFileName)
3455 outFile = fopen(outFileName, "w");
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003456 /* XXX(nnorwitz): it should probably be an exception if outFile
3457 can't be opened. */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003458
Jesus Ceaef9764f2008-05-13 18:45:46 +00003459 { /* DB.verify acts as a DB handle destructor (like close) */
3460 PyObject *error;
3461
Jesus Cea5cd5f122008-09-23 18:54:08 +00003462 error=DB_close_internal(self, 0, 1);
Jesus Cea6557aac2010-03-22 14:22:26 +00003463 if (error) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00003464 return error;
3465 }
3466 }
Gregory P. Smith41631e82003-09-21 00:08:14 +00003467
Jesus Cea5cd5f122008-09-23 18:54:08 +00003468 MYDB_BEGIN_ALLOW_THREADS;
3469 err = self->db->verify(self->db, fileName, dbName, outFile, flags);
3470 MYDB_END_ALLOW_THREADS;
3471
3472 self->db = NULL; /* Implicit close; related objects already released */
3473
3474 if (outFile)
3475 fclose(outFile);
3476
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003477 RETURN_IF_ERR();
3478 RETURN_NONE();
3479}
3480
3481
3482static PyObject*
3483DB_set_get_returns_none(DBObject* self, PyObject* args)
3484{
3485 int flags=0;
Gregory P. Smith455d46f2003-07-09 04:45:59 +00003486 int oldValue=0;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003487
3488 if (!PyArg_ParseTuple(args,"i:set_get_returns_none", &flags))
3489 return NULL;
3490 CHECK_DB_NOT_CLOSED(self);
3491
Gregory P. Smith455d46f2003-07-09 04:45:59 +00003492 if (self->moduleFlags.getReturnsNone)
3493 ++oldValue;
3494 if (self->moduleFlags.cursorSetReturnsNone)
3495 ++oldValue;
3496 self->moduleFlags.getReturnsNone = (flags >= 1);
3497 self->moduleFlags.cursorSetReturnsNone = (flags >= 2);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00003498 return NUMBER_FromLong(oldValue);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003499}
3500
Barry Warsaw9a0d7792002-12-30 20:53:52 +00003501static PyObject*
3502DB_set_encrypt(DBObject* self, PyObject* args, PyObject* kwargs)
3503{
3504 int err;
3505 u_int32_t flags=0;
3506 char *passwd = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003507 static char* kwnames[] = { "passwd", "flags", NULL };
Barry Warsaw9a0d7792002-12-30 20:53:52 +00003508
3509 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|i:set_encrypt", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003510 &passwd, &flags)) {
3511 return NULL;
Barry Warsaw9a0d7792002-12-30 20:53:52 +00003512 }
3513
3514 MYDB_BEGIN_ALLOW_THREADS;
3515 err = self->db->set_encrypt(self->db, passwd, flags);
3516 MYDB_END_ALLOW_THREADS;
3517
3518 RETURN_IF_ERR();
3519 RETURN_NONE();
3520}
Jesus Cea6557aac2010-03-22 14:22:26 +00003521
Jesus Cea6557aac2010-03-22 14:22:26 +00003522static PyObject*
3523DB_get_encrypt_flags(DBObject* self)
3524{
3525 int err;
3526 u_int32_t flags;
3527
3528 MYDB_BEGIN_ALLOW_THREADS;
3529 err = self->db->get_encrypt_flags(self->db, &flags);
3530 MYDB_END_ALLOW_THREADS;
3531
3532 RETURN_IF_ERR();
3533
3534 return NUMBER_FromLong(flags);
3535}
Jesus Cea6557aac2010-03-22 14:22:26 +00003536
Barry Warsaw9a0d7792002-12-30 20:53:52 +00003537
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003538
3539/*-------------------------------------------------------------- */
3540/* Mapping and Dictionary-like access routines */
3541
Martin v. Löwis70ee3cc2006-06-12 04:26:31 +00003542Py_ssize_t DB_length(PyObject* _self)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003543{
3544 int err;
Gregory P. Smith3c228b12006-06-05 23:59:37 +00003545 Py_ssize_t size = 0;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003546 void* sp;
Martin v. Löwis70ee3cc2006-06-12 04:26:31 +00003547 DBObject* self = (DBObject*)_self;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003548
3549 if (self->db == NULL) {
Thomas Woutersb3153832006-03-08 01:47:19 +00003550 PyObject *t = Py_BuildValue("(is)", 0, "DB object has been closed");
Jesus Ceac5a11fa2008-07-23 11:38:42 +00003551 if (t) {
3552 PyErr_SetObject(DBError, t);
3553 Py_DECREF(t);
3554 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003555 return -1;
3556 }
3557
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003558 MYDB_BEGIN_ALLOW_THREADS;
Jesus Cea6557aac2010-03-22 14:22:26 +00003559 err = self->db->stat(self->db, /*txnid*/ NULL, &sp, 0);
Jesus Cea6557aac2010-03-22 14:22:26 +00003560 MYDB_END_ALLOW_THREADS;
Gregory P. Smith3c228b12006-06-05 23:59:37 +00003561
3562 /* All the stat structures have matching fields upto the ndata field,
3563 so we can use any of them for the type cast */
3564 size = ((DB_BTREE_STAT*)sp)->bt_ndata;
3565
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003566 if (err)
3567 return -1;
3568
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003569 free(sp);
3570 return size;
3571}
3572
3573
3574PyObject* DB_subscript(DBObject* self, PyObject* keyobj)
3575{
3576 int err;
3577 PyObject* retval;
3578 DBT key;
3579 DBT data;
3580
3581 CHECK_DB_NOT_CLOSED(self);
3582 if (!make_key_dbt(self, keyobj, &key, NULL))
3583 return NULL;
3584
3585 CLEAR_DBT(data);
3586 if (CHECK_DBFLAG(self, DB_THREAD)) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00003587 /* Tell Berkeley DB to malloc the return value (thread safe) */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003588 data.flags = DB_DBT_MALLOC;
3589 }
3590 MYDB_BEGIN_ALLOW_THREADS;
3591 err = self->db->get(self->db, NULL, &key, &data, 0);
3592 MYDB_END_ALLOW_THREADS;
3593 if (err == DB_NOTFOUND || err == DB_KEYEMPTY) {
3594 PyErr_SetObject(PyExc_KeyError, keyobj);
3595 retval = NULL;
3596 }
3597 else if (makeDBError(err)) {
3598 retval = NULL;
3599 }
3600 else {
Jesus Ceaef9764f2008-05-13 18:45:46 +00003601 retval = Build_PyString(data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003602 FREE_DBT(data);
3603 }
3604
3605 FREE_DBT(key);
3606 return retval;
3607}
3608
3609
3610static int
3611DB_ass_sub(DBObject* self, PyObject* keyobj, PyObject* dataobj)
3612{
3613 DBT key, data;
3614 int retval;
3615 int flags = 0;
3616
3617 if (self->db == NULL) {
Thomas Woutersb3153832006-03-08 01:47:19 +00003618 PyObject *t = Py_BuildValue("(is)", 0, "DB object has been closed");
Jesus Ceac5a11fa2008-07-23 11:38:42 +00003619 if (t) {
3620 PyErr_SetObject(DBError, t);
3621 Py_DECREF(t);
3622 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003623 return -1;
3624 }
3625
3626 if (!make_key_dbt(self, keyobj, &key, NULL))
3627 return -1;
3628
3629 if (dataobj != NULL) {
3630 if (!make_dbt(dataobj, &data))
3631 retval = -1;
3632 else {
3633 if (self->setflags & (DB_DUP|DB_DUPSORT))
Barry Warsaw9a0d7792002-12-30 20:53:52 +00003634 /* dictionaries shouldn't have duplicate keys */
3635 flags = DB_NOOVERWRITE;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003636 retval = _DB_put(self, NULL, &key, &data, flags);
3637
3638 if ((retval == -1) && (self->setflags & (DB_DUP|DB_DUPSORT))) {
Barry Warsaw9a0d7792002-12-30 20:53:52 +00003639 /* try deleting any old record that matches and then PUT it
3640 * again... */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003641 _DB_delete(self, NULL, &key, 0);
3642 PyErr_Clear();
3643 retval = _DB_put(self, NULL, &key, &data, flags);
3644 }
3645 }
3646 }
3647 else {
3648 /* dataobj == NULL, so delete the key */
3649 retval = _DB_delete(self, NULL, &key, 0);
3650 }
3651 FREE_DBT(key);
3652 return retval;
3653}
3654
3655
3656static PyObject*
Jesus Cea6557aac2010-03-22 14:22:26 +00003657_DB_has_key(DBObject* self, PyObject* keyobj, PyObject* txnobj)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003658{
3659 int err;
Jesus Cea6557aac2010-03-22 14:22:26 +00003660 DBT key;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003661 DB_TXN *txn = NULL;
Jesus Cea4907d272008-08-31 14:00:51 +00003662
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003663 CHECK_DB_NOT_CLOSED(self);
3664 if (!make_key_dbt(self, keyobj, &key, NULL))
3665 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00003666 if (!checkTxnObj(txnobj, &txn)) {
3667 FREE_DBT(key);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003668 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00003669 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003670
Jesus Cea6557aac2010-03-22 14:22:26 +00003671#if (DBVER < 46)
Gregory P. Smith8b7e9172004-12-13 09:51:23 +00003672 /* This causes DB_BUFFER_SMALL to be returned when the db has the key because
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003673 it has a record but can't allocate a buffer for the data. This saves
3674 having to deal with data we won't be using.
3675 */
Jesus Cea6557aac2010-03-22 14:22:26 +00003676 {
3677 DBT data ;
3678 CLEAR_DBT(data);
3679 data.flags = DB_DBT_USERMEM;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003680
Jesus Cea6557aac2010-03-22 14:22:26 +00003681 MYDB_BEGIN_ALLOW_THREADS;
3682 err = self->db->get(self->db, txn, &key, &data, 0);
3683 MYDB_END_ALLOW_THREADS;
3684 }
3685#else
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003686 MYDB_BEGIN_ALLOW_THREADS;
Jesus Cea6557aac2010-03-22 14:22:26 +00003687 err = self->db->exists(self->db, txn, &key, 0);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003688 MYDB_END_ALLOW_THREADS;
Jesus Cea6557aac2010-03-22 14:22:26 +00003689#endif
3690
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003691 FREE_DBT(key);
Gregory P. Smithe9477062005-06-04 06:46:59 +00003692
Jesus Cea6557aac2010-03-22 14:22:26 +00003693 /*
3694 ** DB_BUFFER_SMALL is only used if we use "get".
3695 ** We can drop it when we only use "exists",
3696 ** when we drop suport for Berkeley DB < 4.6.
3697 */
Gregory P. Smithe9477062005-06-04 06:46:59 +00003698 if (err == DB_BUFFER_SMALL || err == 0) {
Jesus Cea6557aac2010-03-22 14:22:26 +00003699 Py_INCREF(Py_True);
3700 return Py_True;
Gregory P. Smithe9477062005-06-04 06:46:59 +00003701 } else if (err == DB_NOTFOUND || err == DB_KEYEMPTY) {
Jesus Cea6557aac2010-03-22 14:22:26 +00003702 Py_INCREF(Py_False);
3703 return Py_False;
Gregory P. Smithe9477062005-06-04 06:46:59 +00003704 }
3705
3706 makeDBError(err);
3707 return NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003708}
3709
Jesus Cea6557aac2010-03-22 14:22:26 +00003710static PyObject*
3711DB_has_key(DBObject* self, PyObject* args, PyObject* kwargs)
3712{
3713 PyObject* keyobj;
3714 PyObject* txnobj = NULL;
3715 static char* kwnames[] = {"key","txn", NULL};
3716
3717 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O:has_key", kwnames,
3718 &keyobj, &txnobj))
3719 return NULL;
3720
3721 return _DB_has_key(self, keyobj, txnobj);
3722}
3723
3724
3725static int DB_contains(DBObject* self, PyObject* keyobj)
3726{
3727 PyObject* result;
3728 int result2 = 0;
3729
3730 result = _DB_has_key(self, keyobj, NULL) ;
3731 if (result == NULL) {
3732 return -1; /* Propague exception */
3733 }
3734 if (result != Py_False) {
3735 result2 = 1;
3736 }
3737
3738 Py_DECREF(result);
3739 return result2;
3740}
3741
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003742
3743#define _KEYS_LIST 1
3744#define _VALUES_LIST 2
3745#define _ITEMS_LIST 3
3746
3747static PyObject*
3748_DB_make_list(DBObject* self, DB_TXN* txn, int type)
3749{
3750 int err, dbtype;
3751 DBT key;
3752 DBT data;
3753 DBC *cursor;
3754 PyObject* list;
3755 PyObject* item = NULL;
3756
3757 CHECK_DB_NOT_CLOSED(self);
3758 CLEAR_DBT(key);
3759 CLEAR_DBT(data);
3760
3761 dbtype = _DB_get_type(self);
3762 if (dbtype == -1)
3763 return NULL;
3764
3765 list = PyList_New(0);
Thomas Woutersb3153832006-03-08 01:47:19 +00003766 if (list == NULL)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003767 return NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003768
3769 /* get a cursor */
3770 MYDB_BEGIN_ALLOW_THREADS;
Gregory P. Smith442c9fc2004-09-04 01:36:59 +00003771 err = self->db->cursor(self->db, txn, &cursor, 0);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003772 MYDB_END_ALLOW_THREADS;
Thomas Woutersb3153832006-03-08 01:47:19 +00003773 if (makeDBError(err)) {
3774 Py_DECREF(list);
3775 return NULL;
3776 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003777
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003778 while (1) { /* use the cursor to traverse the DB, collecting items */
3779 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00003780 err = _DBC_get(cursor, &key, &data, DB_NEXT);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003781 MYDB_END_ALLOW_THREADS;
3782
3783 if (err) {
3784 /* for any error, break out of the loop */
3785 break;
3786 }
3787
3788 switch (type) {
3789 case _KEYS_LIST:
3790 switch(dbtype) {
3791 case DB_BTREE:
3792 case DB_HASH:
3793 default:
Jesus Ceaef9764f2008-05-13 18:45:46 +00003794 item = Build_PyString(key.data, key.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003795 break;
3796 case DB_RECNO:
3797 case DB_QUEUE:
Jesus Ceac5a11fa2008-07-23 11:38:42 +00003798 item = NUMBER_FromLong(*((db_recno_t*)key.data));
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003799 break;
3800 }
3801 break;
3802
3803 case _VALUES_LIST:
Jesus Ceaef9764f2008-05-13 18:45:46 +00003804 item = Build_PyString(data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003805 break;
3806
3807 case _ITEMS_LIST:
3808 switch(dbtype) {
3809 case DB_BTREE:
3810 case DB_HASH:
3811 default:
Jesus Ceaef9764f2008-05-13 18:45:46 +00003812 item = BuildValue_SS(key.data, key.size, data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003813 break;
3814 case DB_RECNO:
3815 case DB_QUEUE:
Jesus Ceaef9764f2008-05-13 18:45:46 +00003816 item = BuildValue_IS(*((db_recno_t*)key.data), data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003817 break;
3818 }
3819 break;
Thomas Woutersb3153832006-03-08 01:47:19 +00003820 default:
3821 PyErr_Format(PyExc_ValueError, "Unknown key type 0x%x", type);
3822 item = NULL;
3823 break;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003824 }
3825 if (item == NULL) {
3826 Py_DECREF(list);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003827 list = NULL;
3828 goto done;
3829 }
Jesus Ceac5a11fa2008-07-23 11:38:42 +00003830 if (PyList_Append(list, item)) {
3831 Py_DECREF(list);
3832 Py_DECREF(item);
3833 list = NULL;
3834 goto done;
3835 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003836 Py_DECREF(item);
3837 }
3838
Gregory P. Smithe9477062005-06-04 06:46:59 +00003839 /* DB_NOTFOUND || DB_KEYEMPTY is okay, it means we got to the end */
3840 if (err != DB_NOTFOUND && err != DB_KEYEMPTY && makeDBError(err)) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003841 Py_DECREF(list);
3842 list = NULL;
3843 }
3844
3845 done:
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003846 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00003847 _DBC_close(cursor);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003848 MYDB_END_ALLOW_THREADS;
3849 return list;
3850}
3851
3852
3853static PyObject*
3854DB_keys(DBObject* self, PyObject* args)
3855{
3856 PyObject* txnobj = NULL;
3857 DB_TXN *txn = NULL;
3858
Georg Brandl96a8c392006-05-29 21:04:52 +00003859 if (!PyArg_UnpackTuple(args, "keys", 0, 1, &txnobj))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003860 return NULL;
3861 if (!checkTxnObj(txnobj, &txn))
3862 return NULL;
3863 return _DB_make_list(self, txn, _KEYS_LIST);
3864}
3865
3866
3867static PyObject*
3868DB_items(DBObject* self, PyObject* args)
3869{
3870 PyObject* txnobj = NULL;
3871 DB_TXN *txn = NULL;
3872
Georg Brandl96a8c392006-05-29 21:04:52 +00003873 if (!PyArg_UnpackTuple(args, "items", 0, 1, &txnobj))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003874 return NULL;
3875 if (!checkTxnObj(txnobj, &txn))
3876 return NULL;
3877 return _DB_make_list(self, txn, _ITEMS_LIST);
3878}
3879
3880
3881static PyObject*
3882DB_values(DBObject* self, PyObject* args)
3883{
3884 PyObject* txnobj = NULL;
3885 DB_TXN *txn = NULL;
3886
Georg Brandl96a8c392006-05-29 21:04:52 +00003887 if (!PyArg_UnpackTuple(args, "values", 0, 1, &txnobj))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003888 return NULL;
3889 if (!checkTxnObj(txnobj, &txn))
3890 return NULL;
3891 return _DB_make_list(self, txn, _VALUES_LIST);
3892}
3893
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003894/* --------------------------------------------------------------------- */
Jesus Cea6557aac2010-03-22 14:22:26 +00003895/* DBLogCursor methods */
3896
3897
3898static PyObject*
3899DBLogCursor_close_internal(DBLogCursorObject* self)
3900{
3901 int err = 0;
3902
3903 if (self->logc != NULL) {
3904 EXTRACT_FROM_DOUBLE_LINKED_LIST(self);
3905
3906 MYDB_BEGIN_ALLOW_THREADS;
3907 err = self->logc->close(self->logc, 0);
3908 MYDB_END_ALLOW_THREADS;
3909 self->logc = NULL;
3910 }
3911 RETURN_IF_ERR();
3912 RETURN_NONE();
3913}
3914
3915static PyObject*
3916DBLogCursor_close(DBLogCursorObject* self)
3917{
3918 return DBLogCursor_close_internal(self);
3919}
3920
3921
3922static PyObject*
3923_DBLogCursor_get(DBLogCursorObject* self, int flag, DB_LSN *lsn2)
3924{
3925 int err;
3926 DBT data;
3927 DB_LSN lsn = {0, 0};
3928 PyObject *dummy, *retval;
3929
3930 CLEAR_DBT(data);
3931 data.flags = DB_DBT_MALLOC; /* Berkeley DB must do the malloc */
3932
3933 CHECK_LOGCURSOR_NOT_CLOSED(self);
3934
3935 if (lsn2)
3936 lsn = *lsn2;
3937
3938 MYDB_BEGIN_ALLOW_THREADS;
3939 err = self->logc->get(self->logc, &lsn, &data, flag);
3940 MYDB_END_ALLOW_THREADS;
3941
3942 if (err == DB_NOTFOUND) {
3943 Py_INCREF(Py_None);
3944 retval = Py_None;
3945 }
3946 else if (makeDBError(err)) {
3947 retval = NULL;
3948 }
3949 else {
3950 retval = dummy = BuildValue_S(data.data, data.size);
3951 if (dummy) {
3952 retval = Py_BuildValue("(ii)O", lsn.file, lsn.offset, dummy);
3953 Py_DECREF(dummy);
3954 }
3955 }
3956
3957 FREE_DBT(data);
3958 return retval;
3959}
3960
3961static PyObject*
3962DBLogCursor_current(DBLogCursorObject* self)
3963{
3964 return _DBLogCursor_get(self, DB_CURRENT, NULL);
3965}
3966
3967static PyObject*
3968DBLogCursor_first(DBLogCursorObject* self)
3969{
3970 return _DBLogCursor_get(self, DB_FIRST, NULL);
3971}
3972
3973static PyObject*
3974DBLogCursor_last(DBLogCursorObject* self)
3975{
3976 return _DBLogCursor_get(self, DB_LAST, NULL);
3977}
3978
3979static PyObject*
3980DBLogCursor_next(DBLogCursorObject* self)
3981{
3982 return _DBLogCursor_get(self, DB_NEXT, NULL);
3983}
3984
3985static PyObject*
3986DBLogCursor_prev(DBLogCursorObject* self)
3987{
3988 return _DBLogCursor_get(self, DB_PREV, NULL);
3989}
3990
3991static PyObject*
3992DBLogCursor_set(DBLogCursorObject* self, PyObject* args)
3993{
3994 DB_LSN lsn;
3995
3996 if (!PyArg_ParseTuple(args, "(ii):set", &lsn.file, &lsn.offset))
3997 return NULL;
3998
3999 return _DBLogCursor_get(self, DB_SET, &lsn);
4000}
4001
4002
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07004003/* --------------------------------------------------------------------- */
4004/* DBSite methods */
4005
4006
4007#if (DBVER >= 52)
4008static PyObject*
4009DBSite_close_internal(DBSiteObject* self)
4010{
4011 int err = 0;
4012
4013 if (self->site != NULL) {
4014 EXTRACT_FROM_DOUBLE_LINKED_LIST(self);
4015
4016 MYDB_BEGIN_ALLOW_THREADS;
4017 err = self->site->close(self->site);
4018 MYDB_END_ALLOW_THREADS;
4019 self->site = NULL;
4020 }
4021 RETURN_IF_ERR();
4022 RETURN_NONE();
4023}
4024
4025static PyObject*
4026DBSite_close(DBSiteObject* self)
4027{
4028 return DBSite_close_internal(self);
4029}
4030
4031static PyObject*
4032DBSite_remove(DBSiteObject* self)
4033{
4034 int err = 0;
4035
4036 CHECK_SITE_NOT_CLOSED(self);
4037
4038 MYDB_BEGIN_ALLOW_THREADS;
4039 err = self->site->remove(self->site);
4040 MYDB_END_ALLOW_THREADS;
4041
4042 RETURN_IF_ERR();
4043 RETURN_NONE();
4044}
4045
4046static PyObject*
4047DBSite_get_eid(DBSiteObject* self)
4048{
4049 int err = 0;
4050 int eid;
4051
4052 CHECK_SITE_NOT_CLOSED(self);
4053
4054 MYDB_BEGIN_ALLOW_THREADS;
4055 err = self->site->get_eid(self->site, &eid);
4056 MYDB_END_ALLOW_THREADS;
4057
4058 RETURN_IF_ERR();
4059 return NUMBER_FromLong(eid);
4060}
4061
4062static PyObject*
4063DBSite_get_address(DBSiteObject* self)
4064{
4065 int err = 0;
4066 const char *host;
4067 u_int port;
4068
4069 CHECK_SITE_NOT_CLOSED(self);
4070
4071 MYDB_BEGIN_ALLOW_THREADS;
4072 err = self->site->get_address(self->site, &host, &port);
4073 MYDB_END_ALLOW_THREADS;
4074
4075 RETURN_IF_ERR();
4076
4077 return Py_BuildValue("(sI)", host, port);
4078}
4079
4080static PyObject*
4081DBSite_get_config(DBSiteObject* self, PyObject* args, PyObject* kwargs)
4082{
4083 int err = 0;
4084 u_int32_t which, value;
4085 static char* kwnames[] = { "which", NULL };
4086
4087 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i:get_config", kwnames,
4088 &which))
4089 return NULL;
4090
4091 CHECK_SITE_NOT_CLOSED(self);
4092
4093 MYDB_BEGIN_ALLOW_THREADS;
4094 err = self->site->get_config(self->site, which, &value);
4095 MYDB_END_ALLOW_THREADS;
4096
4097 RETURN_IF_ERR();
4098
4099 if (value) {
4100 Py_INCREF(Py_True);
4101 return Py_True;
4102 } else {
4103 Py_INCREF(Py_False);
4104 return Py_False;
4105 }
4106}
4107
4108static PyObject*
4109DBSite_set_config(DBSiteObject* self, PyObject* args, PyObject* kwargs)
4110{
4111 int err = 0;
4112 u_int32_t which, value;
4113 PyObject *valueO;
4114 static char* kwnames[] = { "which", "value", NULL };
4115
4116 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "iO:set_config", kwnames,
4117 &which, &valueO))
4118 return NULL;
4119
4120 CHECK_SITE_NOT_CLOSED(self);
4121
4122 value = PyObject_IsTrue(valueO);
4123
4124 MYDB_BEGIN_ALLOW_THREADS;
4125 err = self->site->set_config(self->site, which, value);
4126 MYDB_END_ALLOW_THREADS;
4127
4128 RETURN_IF_ERR();
4129 RETURN_NONE();
4130}
4131#endif
4132
Jesus Cea6557aac2010-03-22 14:22:26 +00004133
4134/* --------------------------------------------------------------------- */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004135/* DBCursor methods */
4136
4137
4138static PyObject*
Jesus Ceaef9764f2008-05-13 18:45:46 +00004139DBC_close_internal(DBCursorObject* self)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004140{
4141 int err = 0;
4142
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004143 if (self->dbc != NULL) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00004144 EXTRACT_FROM_DOUBLE_LINKED_LIST(self);
4145 if (self->txn) {
4146 EXTRACT_FROM_DOUBLE_LINKED_LIST_TXN(self);
4147 self->txn=NULL;
4148 }
4149
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004150 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004151 err = _DBC_close(self->dbc);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004152 MYDB_END_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004153 self->dbc = NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004154 }
4155 RETURN_IF_ERR();
4156 RETURN_NONE();
4157}
4158
Jesus Ceaef9764f2008-05-13 18:45:46 +00004159static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00004160DBC_close(DBCursorObject* self)
Jesus Ceaef9764f2008-05-13 18:45:46 +00004161{
Jesus Ceaef9764f2008-05-13 18:45:46 +00004162 return DBC_close_internal(self);
4163}
4164
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004165
4166static PyObject*
4167DBC_count(DBCursorObject* self, PyObject* args)
4168{
4169 int err = 0;
4170 db_recno_t count;
4171 int flags = 0;
4172
4173 if (!PyArg_ParseTuple(args, "|i:count", &flags))
4174 return NULL;
4175
4176 CHECK_CURSOR_NOT_CLOSED(self);
4177
4178 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004179 err = _DBC_count(self->dbc, &count, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004180 MYDB_END_ALLOW_THREADS;
4181 RETURN_IF_ERR();
4182
Jesus Ceac5a11fa2008-07-23 11:38:42 +00004183 return NUMBER_FromLong(count);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004184}
4185
4186
4187static PyObject*
4188DBC_current(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4189{
4190 return _DBCursor_get(self,DB_CURRENT,args,kwargs,"|iii:current");
4191}
4192
4193
4194static PyObject*
4195DBC_delete(DBCursorObject* self, PyObject* args)
4196{
4197 int err, flags=0;
4198
4199 if (!PyArg_ParseTuple(args, "|i:delete", &flags))
4200 return NULL;
4201
4202 CHECK_CURSOR_NOT_CLOSED(self);
4203
4204 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004205 err = _DBC_del(self->dbc, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004206 MYDB_END_ALLOW_THREADS;
4207 RETURN_IF_ERR();
4208
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004209 RETURN_NONE();
4210}
4211
4212
4213static PyObject*
4214DBC_dup(DBCursorObject* self, PyObject* args)
4215{
4216 int err, flags =0;
4217 DBC* dbc = NULL;
4218
4219 if (!PyArg_ParseTuple(args, "|i:dup", &flags))
4220 return NULL;
4221
4222 CHECK_CURSOR_NOT_CLOSED(self);
4223
4224 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004225 err = _DBC_dup(self->dbc, &dbc, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004226 MYDB_END_ALLOW_THREADS;
4227 RETURN_IF_ERR();
4228
Jesus Ceaef9764f2008-05-13 18:45:46 +00004229 return (PyObject*) newDBCursorObject(dbc, self->txn, self->mydb);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004230}
4231
4232static PyObject*
4233DBC_first(DBCursorObject* self, PyObject* args, PyObject* kwargs)
4234{
4235 return _DBCursor_get(self,DB_FIRST,args,kwargs,"|iii:first");
4236}
4237
4238
4239static PyObject*
4240DBC_get(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4241{
Martin v. Löwisb2c7aff2002-11-23 11:26:07 +00004242 int err, flags=0;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004243 PyObject* keyobj = NULL;
4244 PyObject* dataobj = NULL;
4245 PyObject* retval = NULL;
4246 int dlen = -1;
4247 int doff = -1;
4248 DBT key, data;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00004249 static char* kwnames[] = { "key","data", "flags", "dlen", "doff",
Jeremy Hyltonaf68c872005-12-10 18:50:16 +00004250 NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004251
4252 CLEAR_DBT(key);
4253 CLEAR_DBT(data);
4254 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|ii:get", &kwnames[2],
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004255 &flags, &dlen, &doff))
Barry Warsaw9a0d7792002-12-30 20:53:52 +00004256 {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004257 PyErr_Clear();
Barry Warsaw9a0d7792002-12-30 20:53:52 +00004258 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Oi|ii:get",
Jesus Cea4907d272008-08-31 14:00:51 +00004259 &kwnames[1],
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004260 &keyobj, &flags, &dlen, &doff))
Barry Warsaw9a0d7792002-12-30 20:53:52 +00004261 {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004262 PyErr_Clear();
Barry Warsaw9a0d7792002-12-30 20:53:52 +00004263 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OOi|ii:get",
4264 kwnames, &keyobj, &dataobj,
4265 &flags, &dlen, &doff))
4266 {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004267 return NULL;
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004268 }
4269 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004270 }
4271
4272 CHECK_CURSOR_NOT_CLOSED(self);
4273
4274 if (keyobj && !make_key_dbt(self->mydb, keyobj, &key, NULL))
4275 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004276 if ( (dataobj && !make_dbt(dataobj, &data)) ||
4277 (!add_partial_dbt(&data, dlen, doff)) )
4278 {
Jesus Ceaef9764f2008-05-13 18:45:46 +00004279 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004280 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004281 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004282
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004283 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004284 err = _DBC_get(self->dbc, &key, &data, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004285 MYDB_END_ALLOW_THREADS;
4286
Gregory P. Smithe9477062005-06-04 06:46:59 +00004287 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004288 && self->mydb->moduleFlags.getReturnsNone) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004289 Py_INCREF(Py_None);
4290 retval = Py_None;
4291 }
4292 else if (makeDBError(err)) {
4293 retval = NULL;
4294 }
4295 else {
4296 switch (_DB_get_type(self->mydb)) {
4297 case -1:
4298 retval = NULL;
4299 break;
4300 case DB_BTREE:
4301 case DB_HASH:
4302 default:
Jesus Ceaef9764f2008-05-13 18:45:46 +00004303 retval = BuildValue_SS(key.data, key.size, data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004304 break;
4305 case DB_RECNO:
4306 case DB_QUEUE:
Jesus Ceaef9764f2008-05-13 18:45:46 +00004307 retval = BuildValue_IS(*((db_recno_t*)key.data), data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004308 break;
4309 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004310 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00004311 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004312 return retval;
4313}
4314
Gregory P. Smith19699a92004-06-28 04:06:49 +00004315static PyObject*
4316DBC_pget(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4317{
4318 int err, flags=0;
4319 PyObject* keyobj = NULL;
4320 PyObject* dataobj = NULL;
4321 PyObject* retval = NULL;
4322 int dlen = -1;
4323 int doff = -1;
4324 DBT key, pkey, data;
Gregory P. Smith372b5832006-06-05 18:48:21 +00004325 static char* kwnames_keyOnly[] = { "key", "flags", "dlen", "doff", NULL };
4326 static char* kwnames[] = { "key", "data", "flags", "dlen", "doff", NULL };
Gregory P. Smith19699a92004-06-28 04:06:49 +00004327
4328 CLEAR_DBT(key);
4329 CLEAR_DBT(data);
4330 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|ii:pget", &kwnames[2],
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004331 &flags, &dlen, &doff))
Gregory P. Smith19699a92004-06-28 04:06:49 +00004332 {
4333 PyErr_Clear();
4334 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Oi|ii:pget",
Jesus Cea6557aac2010-03-22 14:22:26 +00004335 kwnames_keyOnly,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004336 &keyobj, &flags, &dlen, &doff))
Gregory P. Smith19699a92004-06-28 04:06:49 +00004337 {
4338 PyErr_Clear();
4339 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OOi|ii:pget",
4340 kwnames, &keyobj, &dataobj,
4341 &flags, &dlen, &doff))
4342 {
4343 return NULL;
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004344 }
4345 }
Gregory P. Smith19699a92004-06-28 04:06:49 +00004346 }
4347
4348 CHECK_CURSOR_NOT_CLOSED(self);
4349
4350 if (keyobj && !make_key_dbt(self->mydb, keyobj, &key, NULL))
4351 return NULL;
4352 if ( (dataobj && !make_dbt(dataobj, &data)) ||
4353 (!add_partial_dbt(&data, dlen, doff)) ) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00004354 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Gregory P. Smith19699a92004-06-28 04:06:49 +00004355 return NULL;
4356 }
4357
Gregory P. Smith19699a92004-06-28 04:06:49 +00004358 CLEAR_DBT(pkey);
4359 pkey.flags = DB_DBT_MALLOC;
4360
4361 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004362 err = _DBC_pget(self->dbc, &key, &pkey, &data, flags);
Gregory P. Smith19699a92004-06-28 04:06:49 +00004363 MYDB_END_ALLOW_THREADS;
4364
Gregory P. Smithe9477062005-06-04 06:46:59 +00004365 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004366 && self->mydb->moduleFlags.getReturnsNone) {
Gregory P. Smith19699a92004-06-28 04:06:49 +00004367 Py_INCREF(Py_None);
4368 retval = Py_None;
4369 }
4370 else if (makeDBError(err)) {
4371 retval = NULL;
4372 }
4373 else {
4374 PyObject *pkeyObj;
4375 PyObject *dataObj;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004376 dataObj = Build_PyString(data.data, data.size);
Gregory P. Smith19699a92004-06-28 04:06:49 +00004377
4378 if (self->mydb->primaryDBType == DB_RECNO ||
4379 self->mydb->primaryDBType == DB_QUEUE)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00004380 pkeyObj = NUMBER_FromLong(*(int *)pkey.data);
Gregory P. Smith19699a92004-06-28 04:06:49 +00004381 else
Jesus Ceaef9764f2008-05-13 18:45:46 +00004382 pkeyObj = Build_PyString(pkey.data, pkey.size);
Gregory P. Smith19699a92004-06-28 04:06:49 +00004383
Gregory P. Smith4e414d82006-01-24 19:55:02 +00004384 if (key.data && key.size) /* return key, pkey and data */
Gregory P. Smith19699a92004-06-28 04:06:49 +00004385 {
4386 PyObject *keyObj;
4387 int type = _DB_get_type(self->mydb);
4388 if (type == DB_RECNO || type == DB_QUEUE)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00004389 keyObj = NUMBER_FromLong(*(int *)key.data);
Gregory P. Smith19699a92004-06-28 04:06:49 +00004390 else
Jesus Ceaef9764f2008-05-13 18:45:46 +00004391 keyObj = Build_PyString(key.data, key.size);
Gregory P. Smith4e414d82006-01-24 19:55:02 +00004392 retval = PyTuple_Pack(3, keyObj, pkeyObj, dataObj);
Thomas Woutersb3153832006-03-08 01:47:19 +00004393 Py_DECREF(keyObj);
Jesus Ceaef9764f2008-05-13 18:45:46 +00004394 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Gregory P. Smith19699a92004-06-28 04:06:49 +00004395 }
4396 else /* return just the pkey and data */
4397 {
Gregory P. Smith4e414d82006-01-24 19:55:02 +00004398 retval = PyTuple_Pack(2, pkeyObj, dataObj);
Gregory P. Smith19699a92004-06-28 04:06:49 +00004399 }
Thomas Woutersb3153832006-03-08 01:47:19 +00004400 Py_DECREF(dataObj);
4401 Py_DECREF(pkeyObj);
Gregory P. Smith19699a92004-06-28 04:06:49 +00004402 FREE_DBT(pkey);
Gregory P. Smith19699a92004-06-28 04:06:49 +00004403 }
4404 /* the only time REALLOC should be set is if we used an integer
4405 * key that make_key_dbt malloc'd for us. always free these. */
Jesus Ceaef9764f2008-05-13 18:45:46 +00004406 if (key.flags & DB_DBT_REALLOC) { /* 'make_key_dbt' could do a 'malloc' */
Gregory P. Smith19699a92004-06-28 04:06:49 +00004407 FREE_DBT(key);
4408 }
4409 return retval;
4410}
4411
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004412
4413static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00004414DBC_get_recno(DBCursorObject* self)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004415{
4416 int err;
4417 db_recno_t recno;
4418 DBT key;
4419 DBT data;
4420
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004421 CHECK_CURSOR_NOT_CLOSED(self);
4422
4423 CLEAR_DBT(key);
4424 CLEAR_DBT(data);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004425
4426 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004427 err = _DBC_get(self->dbc, &key, &data, DB_GET_RECNO);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004428 MYDB_END_ALLOW_THREADS;
4429 RETURN_IF_ERR();
4430
4431 recno = *((db_recno_t*)data.data);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00004432 return NUMBER_FromLong(recno);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004433}
4434
4435
4436static PyObject*
4437DBC_last(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4438{
4439 return _DBCursor_get(self,DB_LAST,args,kwargs,"|iii:last");
4440}
4441
4442
4443static PyObject*
4444DBC_next(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4445{
4446 return _DBCursor_get(self,DB_NEXT,args,kwargs,"|iii:next");
4447}
4448
4449
4450static PyObject*
4451DBC_prev(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4452{
4453 return _DBCursor_get(self,DB_PREV,args,kwargs,"|iii:prev");
4454}
4455
4456
4457static PyObject*
4458DBC_put(DBCursorObject* self, PyObject* args, PyObject* kwargs)
4459{
4460 int err, flags = 0;
4461 PyObject* keyobj, *dataobj;
4462 DBT key, data;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00004463 static char* kwnames[] = { "key", "data", "flags", "dlen", "doff",
Jeremy Hyltonaf68c872005-12-10 18:50:16 +00004464 NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004465 int dlen = -1;
4466 int doff = -1;
4467
4468 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|iii:put", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004469 &keyobj, &dataobj, &flags, &dlen, &doff))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004470 return NULL;
4471
4472 CHECK_CURSOR_NOT_CLOSED(self);
4473
4474 if (!make_key_dbt(self->mydb, keyobj, &key, NULL))
4475 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004476 if (!make_dbt(dataobj, &data) ||
4477 !add_partial_dbt(&data, dlen, doff) )
4478 {
Jesus Ceaef9764f2008-05-13 18:45:46 +00004479 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004480 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004481 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004482
4483 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004484 err = _DBC_put(self->dbc, &key, &data, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004485 MYDB_END_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004486 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004487 RETURN_IF_ERR();
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004488 RETURN_NONE();
4489}
4490
4491
4492static PyObject*
4493DBC_set(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4494{
4495 int err, flags = 0;
4496 DBT key, data;
4497 PyObject* retval, *keyobj;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00004498 static char* kwnames[] = { "key", "flags", "dlen", "doff", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004499 int dlen = -1;
4500 int doff = -1;
4501
4502 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|iii:set", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004503 &keyobj, &flags, &dlen, &doff))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004504 return NULL;
4505
4506 CHECK_CURSOR_NOT_CLOSED(self);
4507
4508 if (!make_key_dbt(self->mydb, keyobj, &key, NULL))
4509 return NULL;
4510
4511 CLEAR_DBT(data);
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004512 if (!add_partial_dbt(&data, dlen, doff)) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00004513 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004514 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004515 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004516
4517 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004518 err = _DBC_get(self->dbc, &key, &data, flags|DB_SET);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004519 MYDB_END_ALLOW_THREADS;
Gregory P. Smithe9477062005-06-04 06:46:59 +00004520 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004521 && self->mydb->moduleFlags.cursorSetReturnsNone) {
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004522 Py_INCREF(Py_None);
4523 retval = Py_None;
4524 }
4525 else if (makeDBError(err)) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004526 retval = NULL;
4527 }
4528 else {
4529 switch (_DB_get_type(self->mydb)) {
4530 case -1:
4531 retval = NULL;
4532 break;
4533 case DB_BTREE:
4534 case DB_HASH:
4535 default:
Jesus Ceaef9764f2008-05-13 18:45:46 +00004536 retval = BuildValue_SS(key.data, key.size, data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004537 break;
4538 case DB_RECNO:
4539 case DB_QUEUE:
Jesus Ceaef9764f2008-05-13 18:45:46 +00004540 retval = BuildValue_IS(*((db_recno_t*)key.data), data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004541 break;
4542 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00004543 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004544 }
Gregory P. Smith19699a92004-06-28 04:06:49 +00004545 /* the only time REALLOC should be set is if we used an integer
4546 * key that make_key_dbt malloc'd for us. always free these. */
4547 if (key.flags & DB_DBT_REALLOC) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00004548 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Gregory P. Smith19699a92004-06-28 04:06:49 +00004549 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004550
4551 return retval;
4552}
4553
4554
4555static PyObject*
4556DBC_set_range(DBCursorObject* self, PyObject* args, PyObject* kwargs)
4557{
4558 int err, flags = 0;
4559 DBT key, data;
4560 PyObject* retval, *keyobj;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00004561 static char* kwnames[] = { "key", "flags", "dlen", "doff", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004562 int dlen = -1;
4563 int doff = -1;
4564
4565 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|iii:set_range", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004566 &keyobj, &flags, &dlen, &doff))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004567 return NULL;
4568
4569 CHECK_CURSOR_NOT_CLOSED(self);
4570
4571 if (!make_key_dbt(self->mydb, keyobj, &key, NULL))
4572 return NULL;
4573
4574 CLEAR_DBT(data);
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004575 if (!add_partial_dbt(&data, dlen, doff)) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00004576 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004577 return NULL;
4578 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004579 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004580 err = _DBC_get(self->dbc, &key, &data, flags|DB_SET_RANGE);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004581 MYDB_END_ALLOW_THREADS;
Gregory P. Smithe9477062005-06-04 06:46:59 +00004582 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004583 && self->mydb->moduleFlags.cursorSetReturnsNone) {
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004584 Py_INCREF(Py_None);
4585 retval = Py_None;
4586 }
4587 else if (makeDBError(err)) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004588 retval = NULL;
4589 }
4590 else {
4591 switch (_DB_get_type(self->mydb)) {
4592 case -1:
4593 retval = NULL;
4594 break;
4595 case DB_BTREE:
4596 case DB_HASH:
4597 default:
Jesus Ceaef9764f2008-05-13 18:45:46 +00004598 retval = BuildValue_SS(key.data, key.size, data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004599 break;
4600 case DB_RECNO:
4601 case DB_QUEUE:
Jesus Ceaef9764f2008-05-13 18:45:46 +00004602 retval = BuildValue_IS(*((db_recno_t*)key.data), data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004603 break;
4604 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00004605 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004606 }
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004607 /* the only time REALLOC should be set is if we used an integer
Gregory P. Smith19699a92004-06-28 04:06:49 +00004608 * key that make_key_dbt malloc'd for us. always free these. */
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004609 if (key.flags & DB_DBT_REALLOC) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00004610 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004611 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004612
4613 return retval;
4614}
4615
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004616static PyObject*
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004617_DBC_get_set_both(DBCursorObject* self, PyObject* keyobj, PyObject* dataobj,
4618 int flags, unsigned int returnsNone)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004619{
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004620 int err;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004621 DBT key, data;
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004622 PyObject* retval;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004623
Gregory P. Smith7441e652003-11-03 21:35:31 +00004624 /* the caller did this: CHECK_CURSOR_NOT_CLOSED(self); */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004625 if (!make_key_dbt(self->mydb, keyobj, &key, NULL))
4626 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004627 if (!make_dbt(dataobj, &data)) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00004628 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004629 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004630 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004631
4632 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004633 err = _DBC_get(self->dbc, &key, &data, flags|DB_GET_BOTH);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004634 MYDB_END_ALLOW_THREADS;
Gregory P. Smithe9477062005-06-04 06:46:59 +00004635 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY) && returnsNone) {
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004636 Py_INCREF(Py_None);
4637 retval = Py_None;
4638 }
4639 else if (makeDBError(err)) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004640 retval = NULL;
4641 }
4642 else {
4643 switch (_DB_get_type(self->mydb)) {
4644 case -1:
4645 retval = NULL;
4646 break;
4647 case DB_BTREE:
4648 case DB_HASH:
4649 default:
Jesus Ceaef9764f2008-05-13 18:45:46 +00004650 retval = BuildValue_SS(key.data, key.size, data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004651 break;
4652 case DB_RECNO:
4653 case DB_QUEUE:
Jesus Ceaef9764f2008-05-13 18:45:46 +00004654 retval = BuildValue_IS(*((db_recno_t*)key.data), data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004655 break;
4656 }
4657 }
4658
Jesus Ceaef9764f2008-05-13 18:45:46 +00004659 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004660 return retval;
4661}
4662
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004663static PyObject*
4664DBC_get_both(DBCursorObject* self, PyObject* args)
4665{
4666 int flags=0;
4667 PyObject *keyobj, *dataobj;
4668
4669 if (!PyArg_ParseTuple(args, "OO|i:get_both", &keyobj, &dataobj, &flags))
4670 return NULL;
4671
Gregory P. Smith7441e652003-11-03 21:35:31 +00004672 /* if the cursor is closed, self->mydb may be invalid */
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004673 CHECK_CURSOR_NOT_CLOSED(self);
4674
4675 return _DBC_get_set_both(self, keyobj, dataobj, flags,
4676 self->mydb->moduleFlags.getReturnsNone);
4677}
4678
Gregory P. Smithbe0db8b2003-10-01 06:48:51 +00004679/* Return size of entry */
4680static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00004681DBC_get_current_size(DBCursorObject* self)
Gregory P. Smithbe0db8b2003-10-01 06:48:51 +00004682{
4683 int err, flags=DB_CURRENT;
4684 PyObject* retval = NULL;
4685 DBT key, data;
4686
Gregory P. Smithbe0db8b2003-10-01 06:48:51 +00004687 CHECK_CURSOR_NOT_CLOSED(self);
4688 CLEAR_DBT(key);
4689 CLEAR_DBT(data);
4690
Gregory P. Smith8b7e9172004-12-13 09:51:23 +00004691 /* We don't allocate any memory, forcing a DB_BUFFER_SMALL error and thus
Gregory P. Smithbe0db8b2003-10-01 06:48:51 +00004692 getting the record size. */
4693 data.flags = DB_DBT_USERMEM;
4694 data.ulen = 0;
4695 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004696 err = _DBC_get(self->dbc, &key, &data, flags);
Gregory P. Smithbe0db8b2003-10-01 06:48:51 +00004697 MYDB_END_ALLOW_THREADS;
Gregory P. Smith8b7e9172004-12-13 09:51:23 +00004698 if (err == DB_BUFFER_SMALL || !err) {
4699 /* DB_BUFFER_SMALL means positive size, !err means zero length value */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00004700 retval = NUMBER_FromLong((long)data.size);
Gregory P. Smithbe0db8b2003-10-01 06:48:51 +00004701 err = 0;
4702 }
4703
Gregory P. Smithbe0db8b2003-10-01 06:48:51 +00004704 RETURN_IF_ERR();
4705 return retval;
4706}
4707
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004708static PyObject*
4709DBC_set_both(DBCursorObject* self, PyObject* args)
4710{
4711 int flags=0;
4712 PyObject *keyobj, *dataobj;
4713
4714 if (!PyArg_ParseTuple(args, "OO|i:set_both", &keyobj, &dataobj, &flags))
4715 return NULL;
4716
Gregory P. Smith7441e652003-11-03 21:35:31 +00004717 /* if the cursor is closed, self->mydb may be invalid */
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004718 CHECK_CURSOR_NOT_CLOSED(self);
4719
4720 return _DBC_get_set_both(self, keyobj, dataobj, flags,
4721 self->mydb->moduleFlags.cursorSetReturnsNone);
4722}
4723
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004724
4725static PyObject*
4726DBC_set_recno(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4727{
4728 int err, irecno, flags=0;
4729 db_recno_t recno;
4730 DBT key, data;
4731 PyObject* retval;
4732 int dlen = -1;
4733 int doff = -1;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00004734 static char* kwnames[] = { "recno","flags", "dlen", "doff", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004735
4736 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|iii:set_recno", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004737 &irecno, &flags, &dlen, &doff))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004738 return NULL;
4739
4740 CHECK_CURSOR_NOT_CLOSED(self);
4741
4742 CLEAR_DBT(key);
4743 recno = (db_recno_t) irecno;
Barry Warsaw9a0d7792002-12-30 20:53:52 +00004744 /* use allocated space so DB will be able to realloc room for the real
4745 * key */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004746 key.data = malloc(sizeof(db_recno_t));
4747 if (key.data == NULL) {
4748 PyErr_SetString(PyExc_MemoryError, "Key memory allocation failed");
4749 return NULL;
4750 }
4751 key.size = sizeof(db_recno_t);
4752 key.ulen = key.size;
4753 memcpy(key.data, &recno, sizeof(db_recno_t));
4754 key.flags = DB_DBT_REALLOC;
4755
4756 CLEAR_DBT(data);
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004757 if (!add_partial_dbt(&data, dlen, doff)) {
4758 FREE_DBT(key);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004759 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004760 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004761
4762 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004763 err = _DBC_get(self->dbc, &key, &data, flags|DB_SET_RECNO);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004764 MYDB_END_ALLOW_THREADS;
Gregory P. Smithe9477062005-06-04 06:46:59 +00004765 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004766 && self->mydb->moduleFlags.cursorSetReturnsNone) {
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004767 Py_INCREF(Py_None);
4768 retval = Py_None;
4769 }
4770 else if (makeDBError(err)) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004771 retval = NULL;
4772 }
4773 else { /* Can only be used for BTrees, so no need to return int key */
Jesus Ceaef9764f2008-05-13 18:45:46 +00004774 retval = BuildValue_SS(key.data, key.size, data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004775 }
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004776 FREE_DBT(key);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004777
4778 return retval;
4779}
4780
4781
4782static PyObject*
4783DBC_consume(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4784{
4785 return _DBCursor_get(self,DB_CONSUME,args,kwargs,"|iii:consume");
4786}
4787
4788
4789static PyObject*
4790DBC_next_dup(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4791{
4792 return _DBCursor_get(self,DB_NEXT_DUP,args,kwargs,"|iii:next_dup");
4793}
4794
4795
4796static PyObject*
4797DBC_next_nodup(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4798{
4799 return _DBCursor_get(self,DB_NEXT_NODUP,args,kwargs,"|iii:next_nodup");
4800}
4801
Jesus Cea6557aac2010-03-22 14:22:26 +00004802#if (DBVER >= 46)
4803static PyObject*
4804DBC_prev_dup(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4805{
4806 return _DBCursor_get(self,DB_PREV_DUP,args,kwargs,"|iii:prev_dup");
4807}
4808#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004809
4810static PyObject*
4811DBC_prev_nodup(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4812{
4813 return _DBCursor_get(self,DB_PREV_NODUP,args,kwargs,"|iii:prev_nodup");
4814}
4815
4816
4817static PyObject*
4818DBC_join_item(DBCursorObject* self, PyObject* args)
4819{
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004820 int err, flags=0;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004821 DBT key, data;
4822 PyObject* retval;
4823
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004824 if (!PyArg_ParseTuple(args, "|i:join_item", &flags))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004825 return NULL;
4826
4827 CHECK_CURSOR_NOT_CLOSED(self);
4828
4829 CLEAR_DBT(key);
4830 CLEAR_DBT(data);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004831
4832 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004833 err = _DBC_get(self->dbc, &key, &data, flags | DB_JOIN_ITEM);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004834 MYDB_END_ALLOW_THREADS;
Gregory P. Smithe9477062005-06-04 06:46:59 +00004835 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004836 && self->mydb->moduleFlags.getReturnsNone) {
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004837 Py_INCREF(Py_None);
4838 retval = Py_None;
4839 }
4840 else if (makeDBError(err)) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004841 retval = NULL;
4842 }
4843 else {
Jesus Ceaef9764f2008-05-13 18:45:46 +00004844 retval = BuildValue_S(key.data, key.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004845 }
4846
4847 return retval;
4848}
4849
4850
Jesus Cea6557aac2010-03-22 14:22:26 +00004851#if (DBVER >= 46)
4852static PyObject*
4853DBC_set_priority(DBCursorObject* self, PyObject* args, PyObject* kwargs)
4854{
4855 int err, priority;
4856 static char* kwnames[] = { "priority", NULL };
4857
4858 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i:set_priority", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004859 &priority))
Jesus Cea6557aac2010-03-22 14:22:26 +00004860 return NULL;
4861
4862 CHECK_CURSOR_NOT_CLOSED(self);
4863
4864 MYDB_BEGIN_ALLOW_THREADS;
4865 err = self->dbc->set_priority(self->dbc, priority);
4866 MYDB_END_ALLOW_THREADS;
4867 RETURN_IF_ERR();
4868 RETURN_NONE();
4869}
4870
4871
4872static PyObject*
4873DBC_get_priority(DBCursorObject* self)
4874{
4875 int err;
4876 DB_CACHE_PRIORITY priority;
4877
4878 CHECK_CURSOR_NOT_CLOSED(self);
4879
4880 MYDB_BEGIN_ALLOW_THREADS;
4881 err = self->dbc->get_priority(self->dbc, &priority);
4882 MYDB_END_ALLOW_THREADS;
4883 RETURN_IF_ERR();
4884 return NUMBER_FromLong(priority);
4885}
4886#endif
4887
4888
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004889
4890/* --------------------------------------------------------------------- */
4891/* DBEnv methods */
4892
4893
4894static PyObject*
Jesus Ceaef9764f2008-05-13 18:45:46 +00004895DBEnv_close_internal(DBEnvObject* self, int flags)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004896{
Jesus Ceaef9764f2008-05-13 18:45:46 +00004897 PyObject *dummy;
4898 int err;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004899
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004900 if (!self->closed) { /* Don't close more than once */
Jesus Ceaef9764f2008-05-13 18:45:46 +00004901 while(self->children_txns) {
Jesus Cea6557aac2010-03-22 14:22:26 +00004902 dummy = DBTxn_abort_discard_internal(self->children_txns, 0);
4903 Py_XDECREF(dummy);
Jesus Ceaef9764f2008-05-13 18:45:46 +00004904 }
4905 while(self->children_dbs) {
Jesus Cea6557aac2010-03-22 14:22:26 +00004906 dummy = DB_close_internal(self->children_dbs, 0, 0);
4907 Py_XDECREF(dummy);
4908 }
4909 while(self->children_logcursors) {
4910 dummy = DBLogCursor_close_internal(self->children_logcursors);
4911 Py_XDECREF(dummy);
Jesus Ceaef9764f2008-05-13 18:45:46 +00004912 }
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07004913#if (DBVER >= 52)
4914 while(self->children_sites) {
4915 dummy = DBSite_close_internal(self->children_sites);
4916 Py_XDECREF(dummy);
4917 }
4918#endif
Jesus Ceaac25fab2008-09-03 17:50:32 +00004919 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00004920
Jesus Ceaac25fab2008-09-03 17:50:32 +00004921 self->closed = 1;
4922 if (self->db_env) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004923 MYDB_BEGIN_ALLOW_THREADS;
4924 err = self->db_env->close(self->db_env, flags);
4925 MYDB_END_ALLOW_THREADS;
4926 /* after calling DBEnv->close, regardless of error, this DBEnv
Jesus Ceaef9764f2008-05-13 18:45:46 +00004927 * may not be accessed again (Berkeley DB docs). */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004928 self->db_env = NULL;
4929 RETURN_IF_ERR();
4930 }
4931 RETURN_NONE();
4932}
4933
Jesus Ceaef9764f2008-05-13 18:45:46 +00004934static PyObject*
4935DBEnv_close(DBEnvObject* self, PyObject* args)
4936{
4937 int flags = 0;
4938
4939 if (!PyArg_ParseTuple(args, "|i:close", &flags))
4940 return NULL;
Jesus Cea5cd5f122008-09-23 18:54:08 +00004941 return DBEnv_close_internal(self, flags);
Jesus Ceaef9764f2008-05-13 18:45:46 +00004942}
4943
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004944
4945static PyObject*
4946DBEnv_open(DBEnvObject* self, PyObject* args)
4947{
4948 int err, flags=0, mode=0660;
4949 char *db_home;
4950
4951 if (!PyArg_ParseTuple(args, "z|ii:open", &db_home, &flags, &mode))
4952 return NULL;
4953
4954 CHECK_ENV_NOT_CLOSED(self);
4955
4956 MYDB_BEGIN_ALLOW_THREADS;
4957 err = self->db_env->open(self->db_env, db_home, flags, mode);
4958 MYDB_END_ALLOW_THREADS;
4959 RETURN_IF_ERR();
4960 self->closed = 0;
4961 self->flags = flags;
4962 RETURN_NONE();
4963}
4964
4965
4966static PyObject*
Jesus Cea6557aac2010-03-22 14:22:26 +00004967DBEnv_memp_stat(DBEnvObject* self, PyObject* args, PyObject *kwargs)
4968{
4969 int err;
4970 DB_MPOOL_STAT *gsp;
4971 DB_MPOOL_FSTAT **fsp, **fsp2;
4972 PyObject* d = NULL, *d2, *d3, *r;
4973 u_int32_t flags = 0;
4974 static char* kwnames[] = { "flags", NULL };
4975
4976 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:memp_stat",
4977 kwnames, &flags))
4978 return NULL;
4979
4980 CHECK_ENV_NOT_CLOSED(self);
4981
4982 MYDB_BEGIN_ALLOW_THREADS;
4983 err = self->db_env->memp_stat(self->db_env, &gsp, &fsp, flags);
4984 MYDB_END_ALLOW_THREADS;
4985 RETURN_IF_ERR();
4986
4987 /* Turn the stat structure into a dictionary */
4988 d = PyDict_New();
4989 if (d == NULL) {
4990 if (gsp)
4991 free(gsp);
4992 return NULL;
4993 }
4994
4995#define MAKE_ENTRY(name) _addIntToDict(d, #name, gsp->st_##name)
4996
4997 MAKE_ENTRY(gbytes);
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07004998 MAKE_ENTRY(bytes);
Jesus Cea6557aac2010-03-22 14:22:26 +00004999 MAKE_ENTRY(ncache);
5000#if (DBVER >= 46)
5001 MAKE_ENTRY(max_ncache);
5002#endif
5003 MAKE_ENTRY(regsize);
Jesus Cea6557aac2010-03-22 14:22:26 +00005004 MAKE_ENTRY(mmapsize);
5005 MAKE_ENTRY(maxopenfd);
5006 MAKE_ENTRY(maxwrite);
5007 MAKE_ENTRY(maxwrite_sleep);
Jesus Cea6557aac2010-03-22 14:22:26 +00005008 MAKE_ENTRY(map);
5009 MAKE_ENTRY(cache_hit);
5010 MAKE_ENTRY(cache_miss);
5011 MAKE_ENTRY(page_create);
5012 MAKE_ENTRY(page_in);
5013 MAKE_ENTRY(page_out);
5014 MAKE_ENTRY(ro_evict);
5015 MAKE_ENTRY(rw_evict);
5016 MAKE_ENTRY(page_trickle);
5017 MAKE_ENTRY(pages);
5018 MAKE_ENTRY(page_clean);
5019 MAKE_ENTRY(page_dirty);
5020 MAKE_ENTRY(hash_buckets);
5021 MAKE_ENTRY(hash_searches);
5022 MAKE_ENTRY(hash_longest);
5023 MAKE_ENTRY(hash_examined);
5024 MAKE_ENTRY(hash_nowait);
5025 MAKE_ENTRY(hash_wait);
5026#if (DBVER >= 45)
5027 MAKE_ENTRY(hash_max_nowait);
5028#endif
5029 MAKE_ENTRY(hash_max_wait);
5030 MAKE_ENTRY(region_wait);
5031 MAKE_ENTRY(region_nowait);
5032#if (DBVER >= 45)
5033 MAKE_ENTRY(mvcc_frozen);
5034 MAKE_ENTRY(mvcc_thawed);
5035 MAKE_ENTRY(mvcc_freed);
5036#endif
5037 MAKE_ENTRY(alloc);
5038 MAKE_ENTRY(alloc_buckets);
5039 MAKE_ENTRY(alloc_max_buckets);
5040 MAKE_ENTRY(alloc_pages);
5041 MAKE_ENTRY(alloc_max_pages);
5042#if (DBVER >= 45)
5043 MAKE_ENTRY(io_wait);
5044#endif
5045#if (DBVER >= 48)
5046 MAKE_ENTRY(sync_interrupted);
5047#endif
5048
5049#undef MAKE_ENTRY
5050 free(gsp);
5051
5052 d2 = PyDict_New();
5053 if (d2 == NULL) {
5054 Py_DECREF(d);
5055 if (fsp)
5056 free(fsp);
5057 return NULL;
5058 }
5059#define MAKE_ENTRY(name) _addIntToDict(d3, #name, (*fsp2)->st_##name)
5060 for(fsp2=fsp;*fsp2; fsp2++) {
5061 d3 = PyDict_New();
5062 if (d3 == NULL) {
5063 Py_DECREF(d);
5064 Py_DECREF(d2);
5065 if (fsp)
5066 free(fsp);
5067 return NULL;
5068 }
5069 MAKE_ENTRY(pagesize);
5070 MAKE_ENTRY(cache_hit);
5071 MAKE_ENTRY(cache_miss);
5072 MAKE_ENTRY(map);
5073 MAKE_ENTRY(page_create);
5074 MAKE_ENTRY(page_in);
5075 MAKE_ENTRY(page_out);
5076 if(PyDict_SetItemString(d2, (*fsp2)->file_name, d3)) {
5077 Py_DECREF(d);
5078 Py_DECREF(d2);
5079 Py_DECREF(d3);
5080 if (fsp)
5081 free(fsp);
5082 return NULL;
5083 }
5084 Py_DECREF(d3);
5085 }
5086
5087#undef MAKE_ENTRY
5088 free(fsp);
5089
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07005090 r = PyTuple_Pack(2, d, d2);
Jesus Cea6557aac2010-03-22 14:22:26 +00005091 Py_DECREF(d);
5092 Py_DECREF(d2);
5093 return r;
5094}
5095
Jesus Cea6557aac2010-03-22 14:22:26 +00005096static PyObject*
5097DBEnv_memp_stat_print(DBEnvObject* self, PyObject* args, PyObject *kwargs)
5098{
5099 int err;
5100 int flags=0;
5101 static char* kwnames[] = { "flags", NULL };
5102
5103 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:memp_stat_print",
5104 kwnames, &flags))
5105 {
5106 return NULL;
5107 }
5108 CHECK_ENV_NOT_CLOSED(self);
5109 MYDB_BEGIN_ALLOW_THREADS;
5110 err = self->db_env->memp_stat_print(self->db_env, flags);
5111 MYDB_END_ALLOW_THREADS;
5112 RETURN_IF_ERR();
5113 RETURN_NONE();
5114}
Jesus Cea6557aac2010-03-22 14:22:26 +00005115
5116
5117static PyObject*
5118DBEnv_memp_trickle(DBEnvObject* self, PyObject* args)
5119{
5120 int err, percent, nwrotep;
5121
5122 if (!PyArg_ParseTuple(args, "i:memp_trickle", &percent))
5123 return NULL;
5124 CHECK_ENV_NOT_CLOSED(self);
5125 MYDB_BEGIN_ALLOW_THREADS;
5126 err = self->db_env->memp_trickle(self->db_env, percent, &nwrotep);
5127 MYDB_END_ALLOW_THREADS;
5128 RETURN_IF_ERR();
5129 return NUMBER_FromLong(nwrotep);
5130}
5131
5132static PyObject*
5133DBEnv_memp_sync(DBEnvObject* self, PyObject* args)
5134{
5135 int err;
5136 DB_LSN lsn = {0, 0};
5137 DB_LSN *lsn_p = NULL;
5138
5139 if (!PyArg_ParseTuple(args, "|(ii):memp_sync", &lsn.file, &lsn.offset))
5140 return NULL;
5141 if ((lsn.file!=0) || (lsn.offset!=0)) {
5142 lsn_p = &lsn;
5143 }
5144 CHECK_ENV_NOT_CLOSED(self);
5145 MYDB_BEGIN_ALLOW_THREADS;
5146 err = self->db_env->memp_sync(self->db_env, lsn_p);
5147 MYDB_END_ALLOW_THREADS;
5148 RETURN_IF_ERR();
5149 RETURN_NONE();
5150}
5151
5152static PyObject*
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005153DBEnv_remove(DBEnvObject* self, PyObject* args)
5154{
5155 int err, flags=0;
5156 char *db_home;
5157
5158 if (!PyArg_ParseTuple(args, "s|i:remove", &db_home, &flags))
5159 return NULL;
5160 CHECK_ENV_NOT_CLOSED(self);
5161 MYDB_BEGIN_ALLOW_THREADS;
5162 err = self->db_env->remove(self->db_env, db_home, flags);
5163 MYDB_END_ALLOW_THREADS;
5164 RETURN_IF_ERR();
5165 RETURN_NONE();
5166}
5167
Barry Warsaw9a0d7792002-12-30 20:53:52 +00005168static PyObject*
5169DBEnv_dbremove(DBEnvObject* self, PyObject* args, PyObject* kwargs)
5170{
5171 int err;
5172 u_int32_t flags=0;
5173 char *file = NULL;
5174 char *database = NULL;
5175 PyObject *txnobj = NULL;
5176 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00005177 static char* kwnames[] = { "file", "database", "txn", "flags",
Jeremy Hyltonaf68c872005-12-10 18:50:16 +00005178 NULL };
Barry Warsaw9a0d7792002-12-30 20:53:52 +00005179
Gregory P. Smith641cddf2006-07-28 01:35:25 +00005180 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|zOi:dbremove", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00005181 &file, &database, &txnobj, &flags)) {
5182 return NULL;
Barry Warsaw9a0d7792002-12-30 20:53:52 +00005183 }
5184 if (!checkTxnObj(txnobj, &txn)) {
5185 return NULL;
5186 }
5187 CHECK_ENV_NOT_CLOSED(self);
5188 MYDB_BEGIN_ALLOW_THREADS;
5189 err = self->db_env->dbremove(self->db_env, txn, file, database, flags);
5190 MYDB_END_ALLOW_THREADS;
5191 RETURN_IF_ERR();
5192 RETURN_NONE();
5193}
5194
5195static PyObject*
5196DBEnv_dbrename(DBEnvObject* self, PyObject* args, PyObject* kwargs)
5197{
5198 int err;
5199 u_int32_t flags=0;
5200 char *file = NULL;
5201 char *database = NULL;
5202 char *newname = NULL;
5203 PyObject *txnobj = NULL;
5204 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00005205 static char* kwnames[] = { "file", "database", "newname", "txn",
Jeremy Hyltonaf68c872005-12-10 18:50:16 +00005206 "flags", NULL };
Barry Warsaw9a0d7792002-12-30 20:53:52 +00005207
Gregory P. Smith641cddf2006-07-28 01:35:25 +00005208 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "szs|Oi:dbrename", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00005209 &file, &database, &newname, &txnobj, &flags)) {
5210 return NULL;
Barry Warsaw9a0d7792002-12-30 20:53:52 +00005211 }
5212 if (!checkTxnObj(txnobj, &txn)) {
5213 return NULL;
5214 }
5215 CHECK_ENV_NOT_CLOSED(self);
5216 MYDB_BEGIN_ALLOW_THREADS;
5217 err = self->db_env->dbrename(self->db_env, txn, file, database, newname,
5218 flags);
5219 MYDB_END_ALLOW_THREADS;
5220 RETURN_IF_ERR();
5221 RETURN_NONE();
5222}
5223
Jesus Cea6557aac2010-03-22 14:22:26 +00005224
5225
Barry Warsaw9a0d7792002-12-30 20:53:52 +00005226static PyObject*
5227DBEnv_set_encrypt(DBEnvObject* self, PyObject* args, PyObject* kwargs)
5228{
5229 int err;
5230 u_int32_t flags=0;
5231 char *passwd = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00005232 static char* kwnames[] = { "passwd", "flags", NULL };
Barry Warsaw9a0d7792002-12-30 20:53:52 +00005233
5234 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|i:set_encrypt", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00005235 &passwd, &flags)) {
5236 return NULL;
Barry Warsaw9a0d7792002-12-30 20:53:52 +00005237 }
5238
5239 MYDB_BEGIN_ALLOW_THREADS;
5240 err = self->db_env->set_encrypt(self->db_env, passwd, flags);
5241 MYDB_END_ALLOW_THREADS;
5242
5243 RETURN_IF_ERR();
5244 RETURN_NONE();
5245}
Jesus Cea6557aac2010-03-22 14:22:26 +00005246
Jesus Cea6557aac2010-03-22 14:22:26 +00005247static PyObject*
5248DBEnv_get_encrypt_flags(DBEnvObject* self)
5249{
5250 int err;
5251 u_int32_t flags;
5252
5253 CHECK_ENV_NOT_CLOSED(self);
5254
5255 MYDB_BEGIN_ALLOW_THREADS;
5256 err = self->db_env->get_encrypt_flags(self->db_env, &flags);
5257 MYDB_END_ALLOW_THREADS;
5258
5259 RETURN_IF_ERR();
5260
5261 return NUMBER_FromLong(flags);
5262}
5263
5264static PyObject*
5265DBEnv_get_timeout(DBEnvObject* self, PyObject* args, PyObject* kwargs)
5266{
5267 int err;
5268 int flag;
5269 u_int32_t timeout;
5270 static char* kwnames[] = {"flag", NULL };
5271
5272 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i:get_timeout", kwnames,
5273 &flag)) {
5274 return NULL;
5275 }
5276 CHECK_ENV_NOT_CLOSED(self);
5277
5278 MYDB_BEGIN_ALLOW_THREADS;
5279 err = self->db_env->get_timeout(self->db_env, &timeout, flag);
5280 MYDB_END_ALLOW_THREADS;
5281 RETURN_IF_ERR();
5282 return NUMBER_FromLong(timeout);
5283}
Jesus Cea6557aac2010-03-22 14:22:26 +00005284
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005285
Gregory P. Smithfe11d3e2003-03-27 17:23:29 +00005286static PyObject*
5287DBEnv_set_timeout(DBEnvObject* self, PyObject* args, PyObject* kwargs)
5288{
5289 int err;
5290 u_int32_t flags=0;
5291 u_int32_t timeout = 0;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00005292 static char* kwnames[] = { "timeout", "flags", NULL };
Gregory P. Smithfe11d3e2003-03-27 17:23:29 +00005293
5294 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ii:set_timeout", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00005295 &timeout, &flags)) {
5296 return NULL;
Gregory P. Smithfe11d3e2003-03-27 17:23:29 +00005297 }
5298
5299 MYDB_BEGIN_ALLOW_THREADS;
5300 err = self->db_env->set_timeout(self->db_env, (db_timeout_t)timeout, flags);
5301 MYDB_END_ALLOW_THREADS;
5302
5303 RETURN_IF_ERR();
5304 RETURN_NONE();
5305}
Gregory P. Smithfe11d3e2003-03-27 17:23:29 +00005306
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005307static PyObject*
Gregory P. Smith6676f6e2003-08-28 21:50:30 +00005308DBEnv_set_shm_key(DBEnvObject* self, PyObject* args)
5309{
5310 int err;
5311 long shm_key = 0;
5312
5313 if (!PyArg_ParseTuple(args, "l:set_shm_key", &shm_key))
5314 return NULL;
5315 CHECK_ENV_NOT_CLOSED(self);
5316
5317 err = self->db_env->set_shm_key(self->db_env, shm_key);
5318 RETURN_IF_ERR();
5319 RETURN_NONE();
5320}
5321
Jesus Cea6557aac2010-03-22 14:22:26 +00005322static PyObject*
5323DBEnv_get_shm_key(DBEnvObject* self)
5324{
5325 int err;
5326 long shm_key;
5327
5328 CHECK_ENV_NOT_CLOSED(self);
5329
5330 MYDB_BEGIN_ALLOW_THREADS;
5331 err = self->db_env->get_shm_key(self->db_env, &shm_key);
5332 MYDB_END_ALLOW_THREADS;
5333
5334 RETURN_IF_ERR();
5335
5336 return NUMBER_FromLong(shm_key);
5337}
Jesus Cea6557aac2010-03-22 14:22:26 +00005338
5339#if (DBVER >= 46)
5340static PyObject*
5341DBEnv_set_cache_max(DBEnvObject* self, PyObject* args)
5342{
5343 int err, gbytes, bytes;
5344
5345 if (!PyArg_ParseTuple(args, "ii:set_cache_max",
5346 &gbytes, &bytes))
5347 return NULL;
5348 CHECK_ENV_NOT_CLOSED(self);
5349
5350 MYDB_BEGIN_ALLOW_THREADS;
5351 err = self->db_env->set_cache_max(self->db_env, gbytes, bytes);
5352 MYDB_END_ALLOW_THREADS;
5353 RETURN_IF_ERR();
5354 RETURN_NONE();
5355}
5356
5357static PyObject*
5358DBEnv_get_cache_max(DBEnvObject* self)
5359{
5360 int err;
5361 u_int32_t gbytes, bytes;
5362
5363 CHECK_ENV_NOT_CLOSED(self);
5364
5365 MYDB_BEGIN_ALLOW_THREADS;
5366 err = self->db_env->get_cache_max(self->db_env, &gbytes, &bytes);
5367 MYDB_END_ALLOW_THREADS;
5368
5369 RETURN_IF_ERR();
5370
5371 return Py_BuildValue("(ii)", gbytes, bytes);
5372}
5373#endif
5374
5375#if (DBVER >= 46)
5376static PyObject*
5377DBEnv_set_thread_count(DBEnvObject* self, PyObject* args)
5378{
5379 int err;
5380 u_int32_t count;
5381
5382 if (!PyArg_ParseTuple(args, "i:set_thread_count", &count))
5383 return NULL;
5384 CHECK_ENV_NOT_CLOSED(self);
5385
5386 MYDB_BEGIN_ALLOW_THREADS;
5387 err = self->db_env->set_thread_count(self->db_env, count);
5388 MYDB_END_ALLOW_THREADS;
5389 RETURN_IF_ERR();
5390 RETURN_NONE();
5391}
5392
5393static PyObject*
5394DBEnv_get_thread_count(DBEnvObject* self)
5395{
5396 int err;
5397 u_int32_t count;
5398
5399 CHECK_ENV_NOT_CLOSED(self);
5400
5401 MYDB_BEGIN_ALLOW_THREADS;
5402 err = self->db_env->get_thread_count(self->db_env, &count);
5403 MYDB_END_ALLOW_THREADS;
5404 RETURN_IF_ERR();
5405 return NUMBER_FromLong(count);
5406}
5407#endif
5408
Gregory P. Smith6676f6e2003-08-28 21:50:30 +00005409static PyObject*
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005410DBEnv_set_cachesize(DBEnvObject* self, PyObject* args)
5411{
5412 int err, gbytes=0, bytes=0, ncache=0;
5413
5414 if (!PyArg_ParseTuple(args, "ii|i:set_cachesize",
5415 &gbytes, &bytes, &ncache))
5416 return NULL;
5417 CHECK_ENV_NOT_CLOSED(self);
5418
5419 MYDB_BEGIN_ALLOW_THREADS;
5420 err = self->db_env->set_cachesize(self->db_env, gbytes, bytes, ncache);
5421 MYDB_END_ALLOW_THREADS;
5422 RETURN_IF_ERR();
5423 RETURN_NONE();
5424}
5425
Jesus Cea6557aac2010-03-22 14:22:26 +00005426static PyObject*
5427DBEnv_get_cachesize(DBEnvObject* self)
5428{
5429 int err;
5430 u_int32_t gbytes, bytes;
5431 int ncache;
5432
5433 CHECK_ENV_NOT_CLOSED(self);
5434
5435 MYDB_BEGIN_ALLOW_THREADS;
5436 err = self->db_env->get_cachesize(self->db_env, &gbytes, &bytes, &ncache);
5437 MYDB_END_ALLOW_THREADS;
5438
5439 RETURN_IF_ERR();
5440
5441 return Py_BuildValue("(iii)", gbytes, bytes, ncache);
5442}
Jesus Cea6557aac2010-03-22 14:22:26 +00005443
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005444
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005445static PyObject*
5446DBEnv_set_flags(DBEnvObject* self, PyObject* args)
5447{
5448 int err, flags=0, onoff=0;
5449
5450 if (!PyArg_ParseTuple(args, "ii:set_flags",
5451 &flags, &onoff))
5452 return NULL;
5453 CHECK_ENV_NOT_CLOSED(self);
5454
5455 MYDB_BEGIN_ALLOW_THREADS;
5456 err = self->db_env->set_flags(self->db_env, flags, onoff);
5457 MYDB_END_ALLOW_THREADS;
5458 RETURN_IF_ERR();
5459 RETURN_NONE();
5460}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005461
Jesus Cea6557aac2010-03-22 14:22:26 +00005462static PyObject*
5463DBEnv_get_flags(DBEnvObject* self)
5464{
5465 int err;
5466 u_int32_t flags;
5467
5468 CHECK_ENV_NOT_CLOSED(self);
5469
5470 MYDB_BEGIN_ALLOW_THREADS;
5471 err = self->db_env->get_flags(self->db_env, &flags);
5472 MYDB_END_ALLOW_THREADS;
5473 RETURN_IF_ERR();
5474 return NUMBER_FromLong(flags);
5475}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005476
Jesus Ceaca3939c2008-05-22 15:27:38 +00005477#if (DBVER >= 47)
5478static PyObject*
5479DBEnv_log_set_config(DBEnvObject* self, PyObject* args)
5480{
5481 int err, flags, onoff;
5482
5483 if (!PyArg_ParseTuple(args, "ii:log_set_config",
5484 &flags, &onoff))
5485 return NULL;
5486 CHECK_ENV_NOT_CLOSED(self);
5487
5488 MYDB_BEGIN_ALLOW_THREADS;
5489 err = self->db_env->log_set_config(self->db_env, flags, onoff);
5490 MYDB_END_ALLOW_THREADS;
5491 RETURN_IF_ERR();
5492 RETURN_NONE();
5493}
Jesus Cea6557aac2010-03-22 14:22:26 +00005494
5495static PyObject*
5496DBEnv_log_get_config(DBEnvObject* self, PyObject* args)
5497{
5498 int err, flag, onoff;
5499
5500 if (!PyArg_ParseTuple(args, "i:log_get_config", &flag))
5501 return NULL;
5502 CHECK_ENV_NOT_CLOSED(self);
5503
5504 MYDB_BEGIN_ALLOW_THREADS;
5505 err = self->db_env->log_get_config(self->db_env, flag, &onoff);
5506 MYDB_END_ALLOW_THREADS;
5507 RETURN_IF_ERR();
5508 return PyBool_FromLong(onoff);
5509}
Jesus Ceaca3939c2008-05-22 15:27:38 +00005510#endif /* DBVER >= 47 */
5511
Jesus Cea6557aac2010-03-22 14:22:26 +00005512#if (DBVER >= 44)
5513static PyObject*
5514DBEnv_mutex_set_max(DBEnvObject* self, PyObject* args)
5515{
5516 int err;
5517 int value;
5518
5519 if (!PyArg_ParseTuple(args, "i:mutex_set_max", &value))
5520 return NULL;
5521
5522 CHECK_ENV_NOT_CLOSED(self);
5523
5524 MYDB_BEGIN_ALLOW_THREADS;
5525 err = self->db_env->mutex_set_max(self->db_env, value);
5526 MYDB_END_ALLOW_THREADS;
5527
5528 RETURN_IF_ERR();
5529 RETURN_NONE();
5530}
5531
5532static PyObject*
5533DBEnv_mutex_get_max(DBEnvObject* self)
5534{
5535 int err;
5536 u_int32_t value;
5537
5538 CHECK_ENV_NOT_CLOSED(self);
5539
5540 MYDB_BEGIN_ALLOW_THREADS;
5541 err = self->db_env->mutex_get_max(self->db_env, &value);
5542 MYDB_END_ALLOW_THREADS;
5543
5544 RETURN_IF_ERR();
5545
5546 return NUMBER_FromLong(value);
5547}
5548
5549static PyObject*
5550DBEnv_mutex_set_align(DBEnvObject* self, PyObject* args)
5551{
5552 int err;
5553 int align;
5554
5555 if (!PyArg_ParseTuple(args, "i:mutex_set_align", &align))
5556 return NULL;
5557
5558 CHECK_ENV_NOT_CLOSED(self);
5559
5560 MYDB_BEGIN_ALLOW_THREADS;
5561 err = self->db_env->mutex_set_align(self->db_env, align);
5562 MYDB_END_ALLOW_THREADS;
5563
5564 RETURN_IF_ERR();
5565 RETURN_NONE();
5566}
5567
5568static PyObject*
5569DBEnv_mutex_get_align(DBEnvObject* self)
5570{
5571 int err;
5572 u_int32_t align;
5573
5574 CHECK_ENV_NOT_CLOSED(self);
5575
5576 MYDB_BEGIN_ALLOW_THREADS;
5577 err = self->db_env->mutex_get_align(self->db_env, &align);
5578 MYDB_END_ALLOW_THREADS;
5579
5580 RETURN_IF_ERR();
5581
5582 return NUMBER_FromLong(align);
5583}
5584
5585static PyObject*
5586DBEnv_mutex_set_increment(DBEnvObject* self, PyObject* args)
5587{
5588 int err;
5589 int increment;
5590
5591 if (!PyArg_ParseTuple(args, "i:mutex_set_increment", &increment))
5592 return NULL;
5593
5594 CHECK_ENV_NOT_CLOSED(self);
5595
5596 MYDB_BEGIN_ALLOW_THREADS;
5597 err = self->db_env->mutex_set_increment(self->db_env, increment);
5598 MYDB_END_ALLOW_THREADS;
5599
5600 RETURN_IF_ERR();
5601 RETURN_NONE();
5602}
5603
5604static PyObject*
5605DBEnv_mutex_get_increment(DBEnvObject* self)
5606{
5607 int err;
5608 u_int32_t increment;
5609
5610 CHECK_ENV_NOT_CLOSED(self);
5611
5612 MYDB_BEGIN_ALLOW_THREADS;
5613 err = self->db_env->mutex_get_increment(self->db_env, &increment);
5614 MYDB_END_ALLOW_THREADS;
5615
5616 RETURN_IF_ERR();
5617
5618 return NUMBER_FromLong(increment);
5619}
5620
5621static PyObject*
5622DBEnv_mutex_set_tas_spins(DBEnvObject* self, PyObject* args)
5623{
5624 int err;
5625 int tas_spins;
5626
5627 if (!PyArg_ParseTuple(args, "i:mutex_set_tas_spins", &tas_spins))
5628 return NULL;
5629
5630 CHECK_ENV_NOT_CLOSED(self);
5631
5632 MYDB_BEGIN_ALLOW_THREADS;
5633 err = self->db_env->mutex_set_tas_spins(self->db_env, tas_spins);
5634 MYDB_END_ALLOW_THREADS;
5635
5636 RETURN_IF_ERR();
5637 RETURN_NONE();
5638}
5639
5640static PyObject*
5641DBEnv_mutex_get_tas_spins(DBEnvObject* self)
5642{
5643 int err;
5644 u_int32_t tas_spins;
5645
5646 CHECK_ENV_NOT_CLOSED(self);
5647
5648 MYDB_BEGIN_ALLOW_THREADS;
5649 err = self->db_env->mutex_get_tas_spins(self->db_env, &tas_spins);
5650 MYDB_END_ALLOW_THREADS;
5651
5652 RETURN_IF_ERR();
5653
5654 return NUMBER_FromLong(tas_spins);
5655}
5656#endif
Jesus Ceaca3939c2008-05-22 15:27:38 +00005657
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005658static PyObject*
5659DBEnv_set_data_dir(DBEnvObject* self, PyObject* args)
5660{
5661 int err;
5662 char *dir;
5663
5664 if (!PyArg_ParseTuple(args, "s:set_data_dir", &dir))
5665 return NULL;
5666 CHECK_ENV_NOT_CLOSED(self);
5667
5668 MYDB_BEGIN_ALLOW_THREADS;
5669 err = self->db_env->set_data_dir(self->db_env, dir);
5670 MYDB_END_ALLOW_THREADS;
5671 RETURN_IF_ERR();
5672 RETURN_NONE();
5673}
5674
Jesus Cea6557aac2010-03-22 14:22:26 +00005675static PyObject*
5676DBEnv_get_data_dirs(DBEnvObject* self)
5677{
5678 int err;
5679 PyObject *tuple;
5680 PyObject *item;
5681 const char **dirpp;
5682 int size, i;
5683
5684 CHECK_ENV_NOT_CLOSED(self);
5685
5686 MYDB_BEGIN_ALLOW_THREADS;
5687 err = self->db_env->get_data_dirs(self->db_env, &dirpp);
5688 MYDB_END_ALLOW_THREADS;
5689
5690 RETURN_IF_ERR();
5691
5692 /*
5693 ** Calculate size. Python C API
5694 ** actually allows for tuple resizing,
5695 ** but this is simple enough.
5696 */
5697 for (size=0; *(dirpp+size) ; size++);
5698
5699 tuple = PyTuple_New(size);
5700 if (!tuple)
5701 return NULL;
5702
5703 for (i=0; i<size; i++) {
5704 item = PyBytes_FromString (*(dirpp+i));
5705 if (item == NULL) {
5706 Py_DECREF(tuple);
5707 tuple = NULL;
5708 break;
5709 }
5710 PyTuple_SET_ITEM(tuple, i, item);
5711 }
5712 return tuple;
5713}
Jesus Cea6557aac2010-03-22 14:22:26 +00005714
5715#if (DBVER >= 44)
5716static PyObject*
5717DBEnv_set_lg_filemode(DBEnvObject* self, PyObject* args)
5718{
5719 int err, filemode;
5720
5721 if (!PyArg_ParseTuple(args, "i:set_lg_filemode", &filemode))
5722 return NULL;
5723 CHECK_ENV_NOT_CLOSED(self);
5724
5725 MYDB_BEGIN_ALLOW_THREADS;
5726 err = self->db_env->set_lg_filemode(self->db_env, filemode);
5727 MYDB_END_ALLOW_THREADS;
5728 RETURN_IF_ERR();
5729 RETURN_NONE();
5730}
5731
5732static PyObject*
5733DBEnv_get_lg_filemode(DBEnvObject* self)
5734{
5735 int err, filemode;
5736
5737 CHECK_ENV_NOT_CLOSED(self);
5738
5739 MYDB_BEGIN_ALLOW_THREADS;
5740 err = self->db_env->get_lg_filemode(self->db_env, &filemode);
5741 MYDB_END_ALLOW_THREADS;
5742 RETURN_IF_ERR();
5743 return NUMBER_FromLong(filemode);
5744}
5745#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005746
5747static PyObject*
5748DBEnv_set_lg_bsize(DBEnvObject* self, PyObject* args)
5749{
5750 int err, lg_bsize;
5751
5752 if (!PyArg_ParseTuple(args, "i:set_lg_bsize", &lg_bsize))
5753 return NULL;
5754 CHECK_ENV_NOT_CLOSED(self);
5755
5756 MYDB_BEGIN_ALLOW_THREADS;
5757 err = self->db_env->set_lg_bsize(self->db_env, lg_bsize);
5758 MYDB_END_ALLOW_THREADS;
5759 RETURN_IF_ERR();
5760 RETURN_NONE();
5761}
5762
Jesus Cea6557aac2010-03-22 14:22:26 +00005763static PyObject*
5764DBEnv_get_lg_bsize(DBEnvObject* self)
5765{
5766 int err;
5767 u_int32_t lg_bsize;
5768
5769 CHECK_ENV_NOT_CLOSED(self);
5770
5771 MYDB_BEGIN_ALLOW_THREADS;
5772 err = self->db_env->get_lg_bsize(self->db_env, &lg_bsize);
5773 MYDB_END_ALLOW_THREADS;
5774 RETURN_IF_ERR();
5775 return NUMBER_FromLong(lg_bsize);
5776}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005777
5778static PyObject*
5779DBEnv_set_lg_dir(DBEnvObject* self, PyObject* args)
5780{
5781 int err;
5782 char *dir;
5783
5784 if (!PyArg_ParseTuple(args, "s:set_lg_dir", &dir))
5785 return NULL;
5786 CHECK_ENV_NOT_CLOSED(self);
5787
5788 MYDB_BEGIN_ALLOW_THREADS;
5789 err = self->db_env->set_lg_dir(self->db_env, dir);
5790 MYDB_END_ALLOW_THREADS;
5791 RETURN_IF_ERR();
5792 RETURN_NONE();
5793}
5794
Jesus Cea6557aac2010-03-22 14:22:26 +00005795static PyObject*
5796DBEnv_get_lg_dir(DBEnvObject* self)
5797{
5798 int err;
5799 const char *dirp;
5800
5801 CHECK_ENV_NOT_CLOSED(self);
5802
5803 MYDB_BEGIN_ALLOW_THREADS;
5804 err = self->db_env->get_lg_dir(self->db_env, &dirp);
5805 MYDB_END_ALLOW_THREADS;
5806 RETURN_IF_ERR();
5807 return PyBytes_FromString(dirp);
5808}
Jesus Cea6557aac2010-03-22 14:22:26 +00005809
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005810static PyObject*
5811DBEnv_set_lg_max(DBEnvObject* self, PyObject* args)
5812{
5813 int err, lg_max;
5814
5815 if (!PyArg_ParseTuple(args, "i:set_lg_max", &lg_max))
5816 return NULL;
5817 CHECK_ENV_NOT_CLOSED(self);
5818
5819 MYDB_BEGIN_ALLOW_THREADS;
5820 err = self->db_env->set_lg_max(self->db_env, lg_max);
5821 MYDB_END_ALLOW_THREADS;
5822 RETURN_IF_ERR();
5823 RETURN_NONE();
5824}
5825
Jesus Ceaef9764f2008-05-13 18:45:46 +00005826static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00005827DBEnv_get_lg_max(DBEnvObject* self)
Jesus Ceaef9764f2008-05-13 18:45:46 +00005828{
5829 int err;
5830 u_int32_t lg_max;
5831
Jesus Ceaef9764f2008-05-13 18:45:46 +00005832 CHECK_ENV_NOT_CLOSED(self);
5833
5834 MYDB_BEGIN_ALLOW_THREADS;
5835 err = self->db_env->get_lg_max(self->db_env, &lg_max);
5836 MYDB_END_ALLOW_THREADS;
5837 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00005838 return NUMBER_FromLong(lg_max);
Jesus Ceaef9764f2008-05-13 18:45:46 +00005839}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005840
5841static PyObject*
Gregory P. Smithe9477062005-06-04 06:46:59 +00005842DBEnv_set_lg_regionmax(DBEnvObject* self, PyObject* args)
5843{
5844 int err, lg_max;
5845
5846 if (!PyArg_ParseTuple(args, "i:set_lg_regionmax", &lg_max))
5847 return NULL;
5848 CHECK_ENV_NOT_CLOSED(self);
5849
5850 MYDB_BEGIN_ALLOW_THREADS;
5851 err = self->db_env->set_lg_regionmax(self->db_env, lg_max);
5852 MYDB_END_ALLOW_THREADS;
5853 RETURN_IF_ERR();
5854 RETURN_NONE();
5855}
5856
Jesus Cea6557aac2010-03-22 14:22:26 +00005857static PyObject*
5858DBEnv_get_lg_regionmax(DBEnvObject* self)
5859{
5860 int err;
5861 u_int32_t lg_regionmax;
5862
5863 CHECK_ENV_NOT_CLOSED(self);
5864
5865 MYDB_BEGIN_ALLOW_THREADS;
5866 err = self->db_env->get_lg_regionmax(self->db_env, &lg_regionmax);
5867 MYDB_END_ALLOW_THREADS;
5868 RETURN_IF_ERR();
5869 return NUMBER_FromLong(lg_regionmax);
5870}
Jesus Cea6557aac2010-03-22 14:22:26 +00005871
5872#if (DBVER >= 47)
5873static PyObject*
5874DBEnv_set_lk_partitions(DBEnvObject* self, PyObject* args)
5875{
5876 int err, lk_partitions;
5877
5878 if (!PyArg_ParseTuple(args, "i:set_lk_partitions", &lk_partitions))
5879 return NULL;
5880 CHECK_ENV_NOT_CLOSED(self);
5881
5882 MYDB_BEGIN_ALLOW_THREADS;
5883 err = self->db_env->set_lk_partitions(self->db_env, lk_partitions);
5884 MYDB_END_ALLOW_THREADS;
5885 RETURN_IF_ERR();
5886 RETURN_NONE();
5887}
5888
5889static PyObject*
5890DBEnv_get_lk_partitions(DBEnvObject* self)
5891{
5892 int err;
5893 u_int32_t lk_partitions;
5894
5895 CHECK_ENV_NOT_CLOSED(self);
5896
5897 MYDB_BEGIN_ALLOW_THREADS;
5898 err = self->db_env->get_lk_partitions(self->db_env, &lk_partitions);
5899 MYDB_END_ALLOW_THREADS;
5900 RETURN_IF_ERR();
5901 return NUMBER_FromLong(lk_partitions);
5902}
5903#endif
Gregory P. Smithe9477062005-06-04 06:46:59 +00005904
5905static PyObject*
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005906DBEnv_set_lk_detect(DBEnvObject* self, PyObject* args)
5907{
5908 int err, lk_detect;
5909
5910 if (!PyArg_ParseTuple(args, "i:set_lk_detect", &lk_detect))
5911 return NULL;
5912 CHECK_ENV_NOT_CLOSED(self);
5913
5914 MYDB_BEGIN_ALLOW_THREADS;
5915 err = self->db_env->set_lk_detect(self->db_env, lk_detect);
5916 MYDB_END_ALLOW_THREADS;
5917 RETURN_IF_ERR();
5918 RETURN_NONE();
5919}
5920
Jesus Cea6557aac2010-03-22 14:22:26 +00005921static PyObject*
5922DBEnv_get_lk_detect(DBEnvObject* self)
5923{
5924 int err;
5925 u_int32_t lk_detect;
5926
5927 CHECK_ENV_NOT_CLOSED(self);
5928
5929 MYDB_BEGIN_ALLOW_THREADS;
5930 err = self->db_env->get_lk_detect(self->db_env, &lk_detect);
5931 MYDB_END_ALLOW_THREADS;
5932 RETURN_IF_ERR();
5933 return NUMBER_FromLong(lk_detect);
5934}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005935
Gregory P. Smith8b96a352007-01-05 01:59:42 +00005936#if (DBVER < 45)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005937static PyObject*
5938DBEnv_set_lk_max(DBEnvObject* self, PyObject* args)
5939{
5940 int err, max;
5941
5942 if (!PyArg_ParseTuple(args, "i:set_lk_max", &max))
5943 return NULL;
5944 CHECK_ENV_NOT_CLOSED(self);
5945
5946 MYDB_BEGIN_ALLOW_THREADS;
5947 err = self->db_env->set_lk_max(self->db_env, max);
5948 MYDB_END_ALLOW_THREADS;
5949 RETURN_IF_ERR();
5950 RETURN_NONE();
5951}
Gregory P. Smith8b96a352007-01-05 01:59:42 +00005952#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005953
5954
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005955
5956static PyObject*
5957DBEnv_set_lk_max_locks(DBEnvObject* self, PyObject* args)
5958{
5959 int err, max;
5960
5961 if (!PyArg_ParseTuple(args, "i:set_lk_max_locks", &max))
5962 return NULL;
5963 CHECK_ENV_NOT_CLOSED(self);
5964
5965 MYDB_BEGIN_ALLOW_THREADS;
5966 err = self->db_env->set_lk_max_locks(self->db_env, max);
5967 MYDB_END_ALLOW_THREADS;
5968 RETURN_IF_ERR();
5969 RETURN_NONE();
5970}
5971
Jesus Cea6557aac2010-03-22 14:22:26 +00005972static PyObject*
5973DBEnv_get_lk_max_locks(DBEnvObject* self)
5974{
5975 int err;
5976 u_int32_t lk_max;
5977
5978 CHECK_ENV_NOT_CLOSED(self);
5979
5980 MYDB_BEGIN_ALLOW_THREADS;
5981 err = self->db_env->get_lk_max_locks(self->db_env, &lk_max);
5982 MYDB_END_ALLOW_THREADS;
5983 RETURN_IF_ERR();
5984 return NUMBER_FromLong(lk_max);
5985}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005986
5987static PyObject*
5988DBEnv_set_lk_max_lockers(DBEnvObject* self, PyObject* args)
5989{
5990 int err, max;
5991
5992 if (!PyArg_ParseTuple(args, "i:set_lk_max_lockers", &max))
5993 return NULL;
5994 CHECK_ENV_NOT_CLOSED(self);
5995
5996 MYDB_BEGIN_ALLOW_THREADS;
5997 err = self->db_env->set_lk_max_lockers(self->db_env, max);
5998 MYDB_END_ALLOW_THREADS;
5999 RETURN_IF_ERR();
6000 RETURN_NONE();
6001}
6002
Jesus Cea6557aac2010-03-22 14:22:26 +00006003static PyObject*
6004DBEnv_get_lk_max_lockers(DBEnvObject* self)
6005{
6006 int err;
6007 u_int32_t lk_max;
6008
6009 CHECK_ENV_NOT_CLOSED(self);
6010
6011 MYDB_BEGIN_ALLOW_THREADS;
6012 err = self->db_env->get_lk_max_lockers(self->db_env, &lk_max);
6013 MYDB_END_ALLOW_THREADS;
6014 RETURN_IF_ERR();
6015 return NUMBER_FromLong(lk_max);
6016}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006017
6018static PyObject*
6019DBEnv_set_lk_max_objects(DBEnvObject* self, PyObject* args)
6020{
6021 int err, max;
6022
6023 if (!PyArg_ParseTuple(args, "i:set_lk_max_objects", &max))
6024 return NULL;
6025 CHECK_ENV_NOT_CLOSED(self);
6026
6027 MYDB_BEGIN_ALLOW_THREADS;
6028 err = self->db_env->set_lk_max_objects(self->db_env, max);
6029 MYDB_END_ALLOW_THREADS;
6030 RETURN_IF_ERR();
6031 RETURN_NONE();
6032}
6033
Jesus Cea6557aac2010-03-22 14:22:26 +00006034static PyObject*
6035DBEnv_get_lk_max_objects(DBEnvObject* self)
6036{
6037 int err;
6038 u_int32_t lk_max;
6039
6040 CHECK_ENV_NOT_CLOSED(self);
6041
6042 MYDB_BEGIN_ALLOW_THREADS;
6043 err = self->db_env->get_lk_max_objects(self->db_env, &lk_max);
6044 MYDB_END_ALLOW_THREADS;
6045 RETURN_IF_ERR();
6046 return NUMBER_FromLong(lk_max);
6047}
Jesus Cea6557aac2010-03-22 14:22:26 +00006048
Jesus Cea6557aac2010-03-22 14:22:26 +00006049static PyObject*
6050DBEnv_get_mp_mmapsize(DBEnvObject* self)
6051{
6052 int err;
6053 size_t mmapsize;
6054
6055 CHECK_ENV_NOT_CLOSED(self);
6056
6057 MYDB_BEGIN_ALLOW_THREADS;
6058 err = self->db_env->get_mp_mmapsize(self->db_env, &mmapsize);
6059 MYDB_END_ALLOW_THREADS;
6060 RETURN_IF_ERR();
6061 return NUMBER_FromLong(mmapsize);
6062}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006063
6064static PyObject*
6065DBEnv_set_mp_mmapsize(DBEnvObject* self, PyObject* args)
6066{
6067 int err, mp_mmapsize;
6068
6069 if (!PyArg_ParseTuple(args, "i:set_mp_mmapsize", &mp_mmapsize))
6070 return NULL;
6071 CHECK_ENV_NOT_CLOSED(self);
6072
6073 MYDB_BEGIN_ALLOW_THREADS;
6074 err = self->db_env->set_mp_mmapsize(self->db_env, mp_mmapsize);
6075 MYDB_END_ALLOW_THREADS;
6076 RETURN_IF_ERR();
6077 RETURN_NONE();
6078}
6079
6080
6081static PyObject*
6082DBEnv_set_tmp_dir(DBEnvObject* self, PyObject* args)
6083{
6084 int err;
6085 char *dir;
6086
6087 if (!PyArg_ParseTuple(args, "s:set_tmp_dir", &dir))
6088 return NULL;
6089 CHECK_ENV_NOT_CLOSED(self);
6090
6091 MYDB_BEGIN_ALLOW_THREADS;
6092 err = self->db_env->set_tmp_dir(self->db_env, dir);
6093 MYDB_END_ALLOW_THREADS;
6094 RETURN_IF_ERR();
6095 RETURN_NONE();
6096}
6097
Jesus Cea6557aac2010-03-22 14:22:26 +00006098static PyObject*
6099DBEnv_get_tmp_dir(DBEnvObject* self)
6100{
6101 int err;
6102 const char *dirpp;
6103
6104 CHECK_ENV_NOT_CLOSED(self);
6105
6106 MYDB_BEGIN_ALLOW_THREADS;
6107 err = self->db_env->get_tmp_dir(self->db_env, &dirpp);
6108 MYDB_END_ALLOW_THREADS;
6109
6110 RETURN_IF_ERR();
6111
6112 return PyBytes_FromString(dirpp);
6113}
Jesus Cea6557aac2010-03-22 14:22:26 +00006114
Jesus Ceaef9764f2008-05-13 18:45:46 +00006115static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00006116DBEnv_txn_recover(DBEnvObject* self)
Jesus Ceaef9764f2008-05-13 18:45:46 +00006117{
6118 int flags = DB_FIRST;
6119 int err, i;
6120 PyObject *list, *tuple, *gid;
6121 DBTxnObject *txn;
6122#define PREPLIST_LEN 16
6123 DB_PREPLIST preplist[PREPLIST_LEN];
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07006124#if (DBVER < 48) || (DBVER >= 52)
Jesus Ceaef9764f2008-05-13 18:45:46 +00006125 long retp;
Matthias Klose54cc5392010-03-15 12:46:18 +00006126#else
6127 u_int32_t retp;
6128#endif
Jesus Ceaef9764f2008-05-13 18:45:46 +00006129
Jesus Ceaef9764f2008-05-13 18:45:46 +00006130 CHECK_ENV_NOT_CLOSED(self);
6131
6132 list=PyList_New(0);
6133 if (!list)
6134 return NULL;
6135 while (!0) {
6136 MYDB_BEGIN_ALLOW_THREADS
6137 err=self->db_env->txn_recover(self->db_env,
6138 preplist, PREPLIST_LEN, &retp, flags);
6139#undef PREPLIST_LEN
6140 MYDB_END_ALLOW_THREADS
6141 if (err) {
6142 Py_DECREF(list);
6143 RETURN_IF_ERR();
6144 }
6145 if (!retp) break;
6146 flags=DB_NEXT; /* Prepare for next loop pass */
6147 for (i=0; i<retp; i++) {
Christian Heimes593daf52008-05-26 12:51:38 +00006148 gid=PyBytes_FromStringAndSize((char *)(preplist[i].gid),
Matthias Klose54cc5392010-03-15 12:46:18 +00006149 DB_GID_SIZE);
Jesus Ceaef9764f2008-05-13 18:45:46 +00006150 if (!gid) {
6151 Py_DECREF(list);
6152 return NULL;
6153 }
Jesus Cea6557aac2010-03-22 14:22:26 +00006154 txn=newDBTxnObject(self, NULL, preplist[i].txn, 0);
Jesus Ceaef9764f2008-05-13 18:45:46 +00006155 if (!txn) {
6156 Py_DECREF(list);
6157 Py_DECREF(gid);
6158 return NULL;
6159 }
6160 txn->flag_prepare=1; /* Recover state */
6161 tuple=PyTuple_New(2);
6162 if (!tuple) {
6163 Py_DECREF(list);
6164 Py_DECREF(gid);
6165 Py_DECREF(txn);
6166 return NULL;
6167 }
6168 if (PyTuple_SetItem(tuple, 0, gid)) {
6169 Py_DECREF(list);
6170 Py_DECREF(gid);
6171 Py_DECREF(txn);
6172 Py_DECREF(tuple);
6173 return NULL;
6174 }
6175 if (PyTuple_SetItem(tuple, 1, (PyObject *)txn)) {
6176 Py_DECREF(list);
6177 Py_DECREF(txn);
6178 Py_DECREF(tuple); /* This delete the "gid" also */
6179 return NULL;
6180 }
6181 if (PyList_Append(list, tuple)) {
6182 Py_DECREF(list);
6183 Py_DECREF(tuple);/* This delete the "gid" and the "txn" also */
6184 return NULL;
6185 }
6186 Py_DECREF(tuple);
6187 }
6188 }
6189 return list;
6190}
Jesus Ceaef9764f2008-05-13 18:45:46 +00006191
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006192static PyObject*
6193DBEnv_txn_begin(DBEnvObject* self, PyObject* args, PyObject* kwargs)
6194{
6195 int flags = 0;
6196 PyObject* txnobj = NULL;
6197 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00006198 static char* kwnames[] = { "parent", "flags", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006199
6200 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Oi:txn_begin", kwnames,
6201 &txnobj, &flags))
6202 return NULL;
6203
6204 if (!checkTxnObj(txnobj, &txn))
6205 return NULL;
6206 CHECK_ENV_NOT_CLOSED(self);
6207
Jesus Ceaef9764f2008-05-13 18:45:46 +00006208 return (PyObject*)newDBTxnObject(self, (DBTxnObject *)txnobj, NULL, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006209}
6210
6211
6212static PyObject*
6213DBEnv_txn_checkpoint(DBEnvObject* self, PyObject* args)
6214{
6215 int err, kbyte=0, min=0, flags=0;
6216
6217 if (!PyArg_ParseTuple(args, "|iii:txn_checkpoint", &kbyte, &min, &flags))
6218 return NULL;
6219 CHECK_ENV_NOT_CLOSED(self);
6220
6221 MYDB_BEGIN_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006222 err = self->db_env->txn_checkpoint(self->db_env, kbyte, min, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006223 MYDB_END_ALLOW_THREADS;
6224 RETURN_IF_ERR();
6225 RETURN_NONE();
6226}
6227
Jesus Cea6557aac2010-03-22 14:22:26 +00006228static PyObject*
6229DBEnv_get_tx_max(DBEnvObject* self)
6230{
6231 int err;
6232 u_int32_t max;
6233
6234 CHECK_ENV_NOT_CLOSED(self);
6235
6236 MYDB_BEGIN_ALLOW_THREADS;
6237 err = self->db_env->get_tx_max(self->db_env, &max);
6238 MYDB_END_ALLOW_THREADS;
6239 RETURN_IF_ERR();
6240 return PyLong_FromUnsignedLong(max);
6241}
Jesus Cea6557aac2010-03-22 14:22:26 +00006242
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006243static PyObject*
6244DBEnv_set_tx_max(DBEnvObject* self, PyObject* args)
6245{
6246 int err, max;
6247
6248 if (!PyArg_ParseTuple(args, "i:set_tx_max", &max))
6249 return NULL;
6250 CHECK_ENV_NOT_CLOSED(self);
6251
Jesus Cea6557aac2010-03-22 14:22:26 +00006252 MYDB_BEGIN_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006253 err = self->db_env->set_tx_max(self->db_env, max);
Jesus Cea6557aac2010-03-22 14:22:26 +00006254 MYDB_END_ALLOW_THREADS;
Gregory P. Smith8a474042006-01-27 07:05:40 +00006255 RETURN_IF_ERR();
6256 RETURN_NONE();
6257}
6258
Jesus Cea6557aac2010-03-22 14:22:26 +00006259static PyObject*
6260DBEnv_get_tx_timestamp(DBEnvObject* self)
6261{
6262 int err;
6263 time_t timestamp;
6264
6265 CHECK_ENV_NOT_CLOSED(self);
6266
6267 MYDB_BEGIN_ALLOW_THREADS;
6268 err = self->db_env->get_tx_timestamp(self->db_env, &timestamp);
6269 MYDB_END_ALLOW_THREADS;
6270 RETURN_IF_ERR();
6271 return NUMBER_FromLong(timestamp);
6272}
Jesus Cea6557aac2010-03-22 14:22:26 +00006273
Gregory P. Smith8a474042006-01-27 07:05:40 +00006274static PyObject*
6275DBEnv_set_tx_timestamp(DBEnvObject* self, PyObject* args)
6276{
6277 int err;
Thomas Wouters9d63cca2006-03-01 01:01:55 +00006278 long stamp;
6279 time_t timestamp;
Gregory P. Smith8a474042006-01-27 07:05:40 +00006280
Thomas Wouters9d63cca2006-03-01 01:01:55 +00006281 if (!PyArg_ParseTuple(args, "l:set_tx_timestamp", &stamp))
Gregory P. Smith8a474042006-01-27 07:05:40 +00006282 return NULL;
6283 CHECK_ENV_NOT_CLOSED(self);
Thomas Wouters9d63cca2006-03-01 01:01:55 +00006284 timestamp = (time_t)stamp;
Jesus Cea6557aac2010-03-22 14:22:26 +00006285 MYDB_BEGIN_ALLOW_THREADS;
Thomas Wouters9d63cca2006-03-01 01:01:55 +00006286 err = self->db_env->set_tx_timestamp(self->db_env, &timestamp);
Jesus Cea6557aac2010-03-22 14:22:26 +00006287 MYDB_END_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006288 RETURN_IF_ERR();
6289 RETURN_NONE();
6290}
6291
6292
6293static PyObject*
6294DBEnv_lock_detect(DBEnvObject* self, PyObject* args)
6295{
6296 int err, atype, flags=0;
6297 int aborted = 0;
6298
6299 if (!PyArg_ParseTuple(args, "i|i:lock_detect", &atype, &flags))
6300 return NULL;
6301 CHECK_ENV_NOT_CLOSED(self);
6302
6303 MYDB_BEGIN_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006304 err = self->db_env->lock_detect(self->db_env, flags, atype, &aborted);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006305 MYDB_END_ALLOW_THREADS;
6306 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00006307 return NUMBER_FromLong(aborted);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006308}
6309
6310
6311static PyObject*
6312DBEnv_lock_get(DBEnvObject* self, PyObject* args)
6313{
6314 int flags=0;
6315 int locker, lock_mode;
6316 DBT obj;
6317 PyObject* objobj;
6318
6319 if (!PyArg_ParseTuple(args, "iOi|i:lock_get", &locker, &objobj, &lock_mode, &flags))
6320 return NULL;
6321
6322
6323 if (!make_dbt(objobj, &obj))
6324 return NULL;
6325
6326 return (PyObject*)newDBLockObject(self, locker, &obj, lock_mode, flags);
6327}
6328
6329
6330static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00006331DBEnv_lock_id(DBEnvObject* self)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006332{
6333 int err;
6334 u_int32_t theID;
6335
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006336 CHECK_ENV_NOT_CLOSED(self);
6337 MYDB_BEGIN_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006338 err = self->db_env->lock_id(self->db_env, &theID);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006339 MYDB_END_ALLOW_THREADS;
6340 RETURN_IF_ERR();
6341
Jesus Ceac5a11fa2008-07-23 11:38:42 +00006342 return NUMBER_FromLong((long)theID);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006343}
6344
Gregory P. Smithac11e022007-11-05 02:56:31 +00006345static PyObject*
6346DBEnv_lock_id_free(DBEnvObject* self, PyObject* args)
6347{
6348 int err;
6349 u_int32_t theID;
6350
6351 if (!PyArg_ParseTuple(args, "I:lock_id_free", &theID))
6352 return NULL;
6353
6354 CHECK_ENV_NOT_CLOSED(self);
6355 MYDB_BEGIN_ALLOW_THREADS;
6356 err = self->db_env->lock_id_free(self->db_env, theID);
6357 MYDB_END_ALLOW_THREADS;
6358 RETURN_IF_ERR();
6359 RETURN_NONE();
6360}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006361
6362static PyObject*
6363DBEnv_lock_put(DBEnvObject* self, PyObject* args)
6364{
6365 int err;
6366 DBLockObject* dblockobj;
6367
6368 if (!PyArg_ParseTuple(args, "O!:lock_put", &DBLock_Type, &dblockobj))
6369 return NULL;
6370
6371 CHECK_ENV_NOT_CLOSED(self);
6372 MYDB_BEGIN_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006373 err = self->db_env->lock_put(self->db_env, &dblockobj->lock);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006374 MYDB_END_ALLOW_THREADS;
6375 RETURN_IF_ERR();
6376 RETURN_NONE();
6377}
6378
Gregory P. Smithdb8a8072006-06-05 01:56:15 +00006379#if (DBVER >= 44)
6380static PyObject*
Jesus Cea6557aac2010-03-22 14:22:26 +00006381DBEnv_fileid_reset(DBEnvObject* self, PyObject* args, PyObject* kwargs)
6382{
6383 int err;
6384 char *file;
6385 u_int32_t flags = 0;
6386 static char* kwnames[] = { "file", "flags", NULL};
6387
6388 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "z|i:fileid_reset", kwnames,
6389 &file, &flags))
6390 return NULL;
6391 CHECK_ENV_NOT_CLOSED(self);
6392
6393 MYDB_BEGIN_ALLOW_THREADS;
6394 err = self->db_env->fileid_reset(self->db_env, file, flags);
6395 MYDB_END_ALLOW_THREADS;
6396 RETURN_IF_ERR();
6397 RETURN_NONE();
6398}
6399
6400static PyObject*
Gregory P. Smithdb8a8072006-06-05 01:56:15 +00006401DBEnv_lsn_reset(DBEnvObject* self, PyObject* args, PyObject* kwargs)
6402{
6403 int err;
6404 char *file;
6405 u_int32_t flags = 0;
6406 static char* kwnames[] = { "file", "flags", NULL};
6407
6408 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "z|i:lsn_reset", kwnames,
6409 &file, &flags))
6410 return NULL;
6411 CHECK_ENV_NOT_CLOSED(self);
6412
6413 MYDB_BEGIN_ALLOW_THREADS;
6414 err = self->db_env->lsn_reset(self->db_env, file, flags);
6415 MYDB_END_ALLOW_THREADS;
6416 RETURN_IF_ERR();
6417 RETURN_NONE();
6418}
6419#endif /* DBVER >= 4.4 */
6420
Jesus Cea6557aac2010-03-22 14:22:26 +00006421
Jesus Cea6557aac2010-03-22 14:22:26 +00006422static PyObject*
6423DBEnv_stat_print(DBEnvObject* self, PyObject* args, PyObject *kwargs)
6424{
6425 int err;
6426 int flags=0;
6427 static char* kwnames[] = { "flags", NULL };
6428
6429 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:stat_print",
6430 kwnames, &flags))
6431 {
6432 return NULL;
6433 }
6434 CHECK_ENV_NOT_CLOSED(self);
6435 MYDB_BEGIN_ALLOW_THREADS;
6436 err = self->db_env->stat_print(self->db_env, flags);
6437 MYDB_END_ALLOW_THREADS;
6438 RETURN_IF_ERR();
6439 RETURN_NONE();
6440}
Jesus Cea6557aac2010-03-22 14:22:26 +00006441
6442
Gregory P. Smith76a82e82006-06-05 01:39:52 +00006443static PyObject*
6444DBEnv_log_stat(DBEnvObject* self, PyObject* args)
6445{
6446 int err;
6447 DB_LOG_STAT* statp = NULL;
6448 PyObject* d = NULL;
6449 u_int32_t flags = 0;
6450
6451 if (!PyArg_ParseTuple(args, "|i:log_stat", &flags))
6452 return NULL;
6453 CHECK_ENV_NOT_CLOSED(self);
6454
6455 MYDB_BEGIN_ALLOW_THREADS;
6456 err = self->db_env->log_stat(self->db_env, &statp, flags);
6457 MYDB_END_ALLOW_THREADS;
6458 RETURN_IF_ERR();
6459
6460 /* Turn the stat structure into a dictionary */
6461 d = PyDict_New();
6462 if (d == NULL) {
6463 if (statp)
6464 free(statp);
6465 return NULL;
6466 }
6467
6468#define MAKE_ENTRY(name) _addIntToDict(d, #name, statp->st_##name)
6469
6470 MAKE_ENTRY(magic);
6471 MAKE_ENTRY(version);
6472 MAKE_ENTRY(mode);
6473 MAKE_ENTRY(lg_bsize);
6474#if (DBVER >= 44)
6475 MAKE_ENTRY(lg_size);
6476 MAKE_ENTRY(record);
6477#endif
Gregory P. Smith76a82e82006-06-05 01:39:52 +00006478 MAKE_ENTRY(w_mbytes);
6479 MAKE_ENTRY(w_bytes);
6480 MAKE_ENTRY(wc_mbytes);
6481 MAKE_ENTRY(wc_bytes);
6482 MAKE_ENTRY(wcount);
6483 MAKE_ENTRY(wcount_fill);
6484#if (DBVER >= 44)
6485 MAKE_ENTRY(rcount);
6486#endif
6487 MAKE_ENTRY(scount);
6488 MAKE_ENTRY(cur_file);
6489 MAKE_ENTRY(cur_offset);
6490 MAKE_ENTRY(disk_file);
6491 MAKE_ENTRY(disk_offset);
6492 MAKE_ENTRY(maxcommitperflush);
6493 MAKE_ENTRY(mincommitperflush);
6494 MAKE_ENTRY(regsize);
6495 MAKE_ENTRY(region_wait);
6496 MAKE_ENTRY(region_nowait);
6497
6498#undef MAKE_ENTRY
6499 free(statp);
6500 return d;
6501} /* DBEnv_log_stat */
Gregory P. Smith76a82e82006-06-05 01:39:52 +00006502
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006503
Jesus Cea6557aac2010-03-22 14:22:26 +00006504static PyObject*
6505DBEnv_log_stat_print(DBEnvObject* self, PyObject* args, PyObject *kwargs)
6506{
6507 int err;
6508 int flags=0;
6509 static char* kwnames[] = { "flags", NULL };
6510
6511 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:log_stat_print",
6512 kwnames, &flags))
6513 {
6514 return NULL;
6515 }
6516 CHECK_ENV_NOT_CLOSED(self);
6517 MYDB_BEGIN_ALLOW_THREADS;
6518 err = self->db_env->log_stat_print(self->db_env, flags);
6519 MYDB_END_ALLOW_THREADS;
6520 RETURN_IF_ERR();
6521 RETURN_NONE();
6522}
Jesus Cea6557aac2010-03-22 14:22:26 +00006523
6524
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006525static PyObject*
6526DBEnv_lock_stat(DBEnvObject* self, PyObject* args)
6527{
6528 int err;
6529 DB_LOCK_STAT* sp;
6530 PyObject* d = NULL;
Martin v. Löwisb2c7aff2002-11-23 11:26:07 +00006531 u_int32_t flags = 0;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006532
6533 if (!PyArg_ParseTuple(args, "|i:lock_stat", &flags))
6534 return NULL;
6535 CHECK_ENV_NOT_CLOSED(self);
6536
6537 MYDB_BEGIN_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006538 err = self->db_env->lock_stat(self->db_env, &sp, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006539 MYDB_END_ALLOW_THREADS;
6540 RETURN_IF_ERR();
6541
6542 /* Turn the stat structure into a dictionary */
6543 d = PyDict_New();
6544 if (d == NULL) {
6545 free(sp);
6546 return NULL;
6547 }
6548
6549#define MAKE_ENTRY(name) _addIntToDict(d, #name, sp->st_##name)
6550
Jesus Ceaef9764f2008-05-13 18:45:46 +00006551 MAKE_ENTRY(id);
6552 MAKE_ENTRY(cur_maxid);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006553 MAKE_ENTRY(nmodes);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006554 MAKE_ENTRY(maxlocks);
6555 MAKE_ENTRY(maxlockers);
6556 MAKE_ENTRY(maxobjects);
6557 MAKE_ENTRY(nlocks);
6558 MAKE_ENTRY(maxnlocks);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006559 MAKE_ENTRY(nlockers);
6560 MAKE_ENTRY(maxnlockers);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006561 MAKE_ENTRY(nobjects);
6562 MAKE_ENTRY(maxnobjects);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006563 MAKE_ENTRY(nrequests);
6564 MAKE_ENTRY(nreleases);
Jesus Ceaef9764f2008-05-13 18:45:46 +00006565#if (DBVER >= 44)
6566 MAKE_ENTRY(nupgrade);
6567 MAKE_ENTRY(ndowngrade);
6568#endif
Gregory P. Smith29602d22006-01-24 09:46:48 +00006569#if (DBVER < 44)
6570 MAKE_ENTRY(nnowaits); /* these were renamed in 4.4 */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006571 MAKE_ENTRY(nconflicts);
Gregory P. Smith29602d22006-01-24 09:46:48 +00006572#else
6573 MAKE_ENTRY(lock_nowait);
6574 MAKE_ENTRY(lock_wait);
6575#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006576 MAKE_ENTRY(ndeadlocks);
Jesus Ceaef9764f2008-05-13 18:45:46 +00006577 MAKE_ENTRY(locktimeout);
6578 MAKE_ENTRY(txntimeout);
Jesus Ceaef9764f2008-05-13 18:45:46 +00006579 MAKE_ENTRY(nlocktimeouts);
6580 MAKE_ENTRY(ntxntimeouts);
Jesus Ceaef9764f2008-05-13 18:45:46 +00006581#if (DBVER >= 46)
6582 MAKE_ENTRY(objs_wait);
6583 MAKE_ENTRY(objs_nowait);
6584 MAKE_ENTRY(lockers_wait);
6585 MAKE_ENTRY(lockers_nowait);
Jesus Ceaca3939c2008-05-22 15:27:38 +00006586#if (DBVER >= 47)
6587 MAKE_ENTRY(lock_wait);
6588 MAKE_ENTRY(lock_nowait);
6589#else
Jesus Ceaef9764f2008-05-13 18:45:46 +00006590 MAKE_ENTRY(locks_wait);
6591 MAKE_ENTRY(locks_nowait);
Jesus Ceaca3939c2008-05-22 15:27:38 +00006592#endif
Jesus Ceaef9764f2008-05-13 18:45:46 +00006593 MAKE_ENTRY(hash_len);
6594#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006595 MAKE_ENTRY(regsize);
6596 MAKE_ENTRY(region_wait);
6597 MAKE_ENTRY(region_nowait);
6598
6599#undef MAKE_ENTRY
6600 free(sp);
6601 return d;
6602}
6603
Jesus Cea6557aac2010-03-22 14:22:26 +00006604static PyObject*
6605DBEnv_lock_stat_print(DBEnvObject* self, PyObject* args, PyObject *kwargs)
6606{
6607 int err;
6608 int flags=0;
6609 static char* kwnames[] = { "flags", NULL };
6610
6611 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:lock_stat_print",
6612 kwnames, &flags))
6613 {
6614 return NULL;
6615 }
6616 CHECK_ENV_NOT_CLOSED(self);
6617 MYDB_BEGIN_ALLOW_THREADS;
6618 err = self->db_env->lock_stat_print(self->db_env, flags);
6619 MYDB_END_ALLOW_THREADS;
6620 RETURN_IF_ERR();
6621 RETURN_NONE();
6622}
Jesus Cea6557aac2010-03-22 14:22:26 +00006623
6624
6625static PyObject*
6626DBEnv_log_cursor(DBEnvObject* self)
6627{
6628 int err;
6629 DB_LOGC* dblogc;
6630
6631 CHECK_ENV_NOT_CLOSED(self);
6632
6633 MYDB_BEGIN_ALLOW_THREADS;
6634 err = self->db_env->log_cursor(self->db_env, &dblogc, 0);
6635 MYDB_END_ALLOW_THREADS;
6636 RETURN_IF_ERR();
6637 return (PyObject*) newDBLogCursorObject(dblogc, self);
6638}
6639
6640
Jesus Ceaef9764f2008-05-13 18:45:46 +00006641static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00006642DBEnv_log_flush(DBEnvObject* self)
Jesus Ceaef9764f2008-05-13 18:45:46 +00006643{
6644 int err;
6645
Jesus Ceaef9764f2008-05-13 18:45:46 +00006646 CHECK_ENV_NOT_CLOSED(self);
6647
6648 MYDB_BEGIN_ALLOW_THREADS
6649 err = self->db_env->log_flush(self->db_env, NULL);
6650 MYDB_END_ALLOW_THREADS
6651
6652 RETURN_IF_ERR();
6653 RETURN_NONE();
6654}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006655
6656static PyObject*
Jesus Cea6557aac2010-03-22 14:22:26 +00006657DBEnv_log_file(DBEnvObject* self, PyObject* args)
6658{
6659 int err;
6660 DB_LSN lsn = {0, 0};
6661 int size = 20;
6662 char *name = NULL;
6663 PyObject *retval;
6664
6665 if (!PyArg_ParseTuple(args, "(ii):log_file", &lsn.file, &lsn.offset))
6666 return NULL;
6667
6668 CHECK_ENV_NOT_CLOSED(self);
6669
6670 do {
6671 name = malloc(size);
6672 if (!name) {
6673 PyErr_NoMemory();
6674 return NULL;
6675 }
6676 MYDB_BEGIN_ALLOW_THREADS;
6677 err = self->db_env->log_file(self->db_env, &lsn, name, size);
6678 MYDB_END_ALLOW_THREADS;
6679 if (err == EINVAL) {
6680 free(name);
6681 size *= 2;
6682 } else if (err) {
6683 free(name);
6684 RETURN_IF_ERR();
6685 assert(0); /* Unreachable... supposely */
6686 return NULL;
6687 }
6688/*
6689** If the final buffer we try is too small, we will
6690** get this exception:
6691** DBInvalidArgError:
6692** (22, 'Invalid argument -- DB_ENV->log_file: name buffer is too short')
6693*/
6694 } while ((err == EINVAL) && (size<(1<<17)));
6695
6696 RETURN_IF_ERR(); /* Maybe the size is not the problem */
6697
6698 retval = Py_BuildValue("s", name);
6699 free(name);
6700 return retval;
6701}
6702
6703
6704#if (DBVER >= 44)
6705static PyObject*
6706DBEnv_log_printf(DBEnvObject* self, PyObject* args, PyObject *kwargs)
6707{
6708 int err;
6709 char *string;
6710 PyObject *txnobj = NULL;
6711 DB_TXN *txn = NULL;
6712 static char* kwnames[] = {"string", "txn", NULL };
6713
6714 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|O:log_printf", kwnames,
6715 &string, &txnobj))
6716 return NULL;
6717
6718 CHECK_ENV_NOT_CLOSED(self);
6719
6720 if (!checkTxnObj(txnobj, &txn))
6721 return NULL;
6722
6723 /*
6724 ** Do not use the format string directly, to avoid attacks.
6725 */
6726 MYDB_BEGIN_ALLOW_THREADS;
6727 err = self->db_env->log_printf(self->db_env, txn, "%s", string);
6728 MYDB_END_ALLOW_THREADS;
6729
6730 RETURN_IF_ERR();
6731 RETURN_NONE();
6732}
6733#endif
6734
6735
6736static PyObject*
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006737DBEnv_log_archive(DBEnvObject* self, PyObject* args)
6738{
6739 int flags=0;
6740 int err;
Gregory P. Smith3dd20022006-06-05 00:31:01 +00006741 char **log_list = NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006742 PyObject* list;
6743 PyObject* item = NULL;
6744
6745 if (!PyArg_ParseTuple(args, "|i:log_archive", &flags))
6746 return NULL;
6747
6748 CHECK_ENV_NOT_CLOSED(self);
6749 MYDB_BEGIN_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006750 err = self->db_env->log_archive(self->db_env, &log_list, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006751 MYDB_END_ALLOW_THREADS;
6752 RETURN_IF_ERR();
6753
Gregory P. Smithbad47452006-06-05 00:33:35 +00006754 list = PyList_New(0);
6755 if (list == NULL) {
6756 if (log_list)
6757 free(log_list);
6758 return NULL;
6759 }
6760
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006761 if (log_list) {
Gregory P. Smith3dd20022006-06-05 00:31:01 +00006762 char **log_list_start;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006763 for (log_list_start = log_list; *log_list != NULL; ++log_list) {
Christian Heimes593daf52008-05-26 12:51:38 +00006764 item = PyBytes_FromString (*log_list);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006765 if (item == NULL) {
6766 Py_DECREF(list);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006767 list = NULL;
6768 break;
6769 }
Jesus Ceac5a11fa2008-07-23 11:38:42 +00006770 if (PyList_Append(list, item)) {
6771 Py_DECREF(list);
6772 list = NULL;
6773 Py_DECREF(item);
6774 break;
6775 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006776 Py_DECREF(item);
6777 }
6778 free(log_list_start);
6779 }
6780 return list;
6781}
6782
6783
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07006784#if (DBVER >= 52)
6785static PyObject*
6786DBEnv_repmgr_site(DBEnvObject* self, PyObject* args, PyObject *kwargs)
6787{
6788 int err;
6789 DB_SITE* site;
6790 char *host;
6791 u_int port;
6792 static char* kwnames[] = {"host", "port", NULL};
6793
6794 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "si:repmgr_site", kwnames,
6795 &host, &port))
6796 return NULL;
6797
6798 CHECK_ENV_NOT_CLOSED(self);
6799
6800 MYDB_BEGIN_ALLOW_THREADS;
6801 err = self->db_env->repmgr_site(self->db_env, host, port, &site, 0);
6802 MYDB_END_ALLOW_THREADS;
6803 RETURN_IF_ERR();
6804 return (PyObject*) newDBSiteObject(site, self);
6805}
6806
6807static PyObject*
6808DBEnv_repmgr_site_by_eid(DBEnvObject* self, PyObject* args, PyObject *kwargs)
6809{
6810 int err;
6811 DB_SITE* site;
6812 int eid;
6813 static char* kwnames[] = {"eid", NULL};
6814
6815 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i:repmgr_site_by_eid",
6816 kwnames, &eid))
6817 return NULL;
6818
6819 CHECK_ENV_NOT_CLOSED(self);
6820
6821 MYDB_BEGIN_ALLOW_THREADS;
6822 err = self->db_env->repmgr_site_by_eid(self->db_env, eid, &site);
6823 MYDB_END_ALLOW_THREADS;
6824 RETURN_IF_ERR();
6825 return (PyObject*) newDBSiteObject(site, self);
6826}
6827#endif
6828
6829
Jesus Cea6557aac2010-03-22 14:22:26 +00006830#if (DBVER >= 44)
6831static PyObject*
6832DBEnv_mutex_stat(DBEnvObject* self, PyObject* args)
6833{
6834 int err;
6835 DB_MUTEX_STAT* statp = NULL;
6836 PyObject* d = NULL;
6837 u_int32_t flags = 0;
6838
6839 if (!PyArg_ParseTuple(args, "|i:mutex_stat", &flags))
6840 return NULL;
6841 CHECK_ENV_NOT_CLOSED(self);
6842
6843 MYDB_BEGIN_ALLOW_THREADS;
6844 err = self->db_env->mutex_stat(self->db_env, &statp, flags);
6845 MYDB_END_ALLOW_THREADS;
6846 RETURN_IF_ERR();
6847
6848 /* Turn the stat structure into a dictionary */
6849 d = PyDict_New();
6850 if (d == NULL) {
6851 if (statp)
6852 free(statp);
6853 return NULL;
6854 }
6855
6856#define MAKE_ENTRY(name) _addIntToDict(d, #name, statp->st_##name)
6857
6858 MAKE_ENTRY(mutex_align);
6859 MAKE_ENTRY(mutex_tas_spins);
6860 MAKE_ENTRY(mutex_cnt);
6861 MAKE_ENTRY(mutex_free);
6862 MAKE_ENTRY(mutex_inuse);
6863 MAKE_ENTRY(mutex_inuse_max);
6864 MAKE_ENTRY(regsize);
6865 MAKE_ENTRY(region_wait);
6866 MAKE_ENTRY(region_nowait);
6867
6868#undef MAKE_ENTRY
6869 free(statp);
6870 return d;
6871}
6872#endif
6873
6874
6875#if (DBVER >= 44)
6876static PyObject*
6877DBEnv_mutex_stat_print(DBEnvObject* self, PyObject* args, PyObject *kwargs)
6878{
6879 int err;
6880 int flags=0;
6881 static char* kwnames[] = { "flags", NULL };
6882
6883 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:mutex_stat_print",
6884 kwnames, &flags))
6885 {
6886 return NULL;
6887 }
6888 CHECK_ENV_NOT_CLOSED(self);
6889 MYDB_BEGIN_ALLOW_THREADS;
6890 err = self->db_env->mutex_stat_print(self->db_env, flags);
6891 MYDB_END_ALLOW_THREADS;
6892 RETURN_IF_ERR();
6893 RETURN_NONE();
6894}
6895#endif
6896
6897
Jesus Cea6557aac2010-03-22 14:22:26 +00006898static PyObject*
6899DBEnv_txn_stat_print(DBEnvObject* self, PyObject* args, PyObject *kwargs)
6900{
6901 int err;
6902 int flags=0;
6903 static char* kwnames[] = { "flags", NULL };
6904
6905 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:stat_print",
6906 kwnames, &flags))
6907 {
6908 return NULL;
6909 }
6910
6911 CHECK_ENV_NOT_CLOSED(self);
6912
6913 MYDB_BEGIN_ALLOW_THREADS;
6914 err = self->db_env->txn_stat_print(self->db_env, flags);
6915 MYDB_END_ALLOW_THREADS;
6916 RETURN_IF_ERR();
6917 RETURN_NONE();
6918}
Jesus Cea6557aac2010-03-22 14:22:26 +00006919
6920
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006921static PyObject*
6922DBEnv_txn_stat(DBEnvObject* self, PyObject* args)
6923{
6924 int err;
6925 DB_TXN_STAT* sp;
6926 PyObject* d = NULL;
Martin v. Löwisb2c7aff2002-11-23 11:26:07 +00006927 u_int32_t flags=0;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006928
6929 if (!PyArg_ParseTuple(args, "|i:txn_stat", &flags))
6930 return NULL;
6931 CHECK_ENV_NOT_CLOSED(self);
6932
6933 MYDB_BEGIN_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006934 err = self->db_env->txn_stat(self->db_env, &sp, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006935 MYDB_END_ALLOW_THREADS;
6936 RETURN_IF_ERR();
6937
6938 /* Turn the stat structure into a dictionary */
6939 d = PyDict_New();
6940 if (d == NULL) {
6941 free(sp);
6942 return NULL;
6943 }
6944
Jesus Ceaef9764f2008-05-13 18:45:46 +00006945#define MAKE_ENTRY(name) _addIntToDict(d, #name, sp->st_##name)
6946#define MAKE_TIME_T_ENTRY(name) _addTimeTToDict(d, #name, sp->st_##name)
6947#define MAKE_DB_LSN_ENTRY(name) _addDB_lsnToDict(d, #name, sp->st_##name)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006948
Jesus Ceaef9764f2008-05-13 18:45:46 +00006949 MAKE_DB_LSN_ENTRY(last_ckp);
Kristján Valur Jónssonbd77c032007-04-26 15:24:54 +00006950 MAKE_TIME_T_ENTRY(time_ckp);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006951 MAKE_ENTRY(last_txnid);
6952 MAKE_ENTRY(maxtxns);
6953 MAKE_ENTRY(nactive);
6954 MAKE_ENTRY(maxnactive);
Jesus Ceaef9764f2008-05-13 18:45:46 +00006955#if (DBVER >= 45)
6956 MAKE_ENTRY(nsnapshot);
6957 MAKE_ENTRY(maxnsnapshot);
6958#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006959 MAKE_ENTRY(nbegins);
6960 MAKE_ENTRY(naborts);
6961 MAKE_ENTRY(ncommits);
Jesus Ceaef9764f2008-05-13 18:45:46 +00006962 MAKE_ENTRY(nrestores);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006963 MAKE_ENTRY(regsize);
6964 MAKE_ENTRY(region_wait);
6965 MAKE_ENTRY(region_nowait);
6966
Jesus Ceaef9764f2008-05-13 18:45:46 +00006967#undef MAKE_DB_LSN_ENTRY
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006968#undef MAKE_ENTRY
Kristján Valur Jónssonbd77c032007-04-26 15:24:54 +00006969#undef MAKE_TIME_T_ENTRY
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006970 free(sp);
6971 return d;
6972}
6973
6974
6975static PyObject*
6976DBEnv_set_get_returns_none(DBEnvObject* self, PyObject* args)
6977{
6978 int flags=0;
Gregory P. Smith455d46f2003-07-09 04:45:59 +00006979 int oldValue=0;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006980
6981 if (!PyArg_ParseTuple(args,"i:set_get_returns_none", &flags))
6982 return NULL;
6983 CHECK_ENV_NOT_CLOSED(self);
6984
Gregory P. Smith455d46f2003-07-09 04:45:59 +00006985 if (self->moduleFlags.getReturnsNone)
6986 ++oldValue;
6987 if (self->moduleFlags.cursorSetReturnsNone)
6988 ++oldValue;
6989 self->moduleFlags.getReturnsNone = (flags >= 1);
6990 self->moduleFlags.cursorSetReturnsNone = (flags >= 2);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00006991 return NUMBER_FromLong(oldValue);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006992}
6993
Jesus Ceac5a11fa2008-07-23 11:38:42 +00006994static PyObject*
6995DBEnv_get_private(DBEnvObject* self)
6996{
6997 /* We can give out the private field even if dbenv is closed */
Jesus Cea4907d272008-08-31 14:00:51 +00006998 Py_INCREF(self->private_obj);
6999 return self->private_obj;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007000}
7001
7002static PyObject*
Jesus Cea4907d272008-08-31 14:00:51 +00007003DBEnv_set_private(DBEnvObject* self, PyObject* private_obj)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007004{
7005 /* We can set the private field even if dbenv is closed */
Jesus Cea4907d272008-08-31 14:00:51 +00007006 Py_DECREF(self->private_obj);
7007 Py_INCREF(private_obj);
7008 self->private_obj = private_obj;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007009 RETURN_NONE();
7010}
7011
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07007012#if (DBVER >= 47)
7013static PyObject*
7014DBEnv_set_intermediate_dir_mode(DBEnvObject* self, PyObject* args)
7015{
7016 int err;
7017 const char *mode;
7018
7019 if (!PyArg_ParseTuple(args,"s:set_intermediate_dir_mode", &mode))
7020 return NULL;
7021
7022 CHECK_ENV_NOT_CLOSED(self);
7023
7024 MYDB_BEGIN_ALLOW_THREADS;
7025 err = self->db_env->set_intermediate_dir_mode(self->db_env, mode);
7026 MYDB_END_ALLOW_THREADS;
7027 RETURN_IF_ERR();
7028 RETURN_NONE();
7029}
7030
7031static PyObject*
7032DBEnv_get_intermediate_dir_mode(DBEnvObject* self)
7033{
7034 int err;
7035 const char *mode;
7036
7037 CHECK_ENV_NOT_CLOSED(self);
7038
7039 MYDB_BEGIN_ALLOW_THREADS;
7040 err = self->db_env->get_intermediate_dir_mode(self->db_env, &mode);
7041 MYDB_END_ALLOW_THREADS;
7042 RETURN_IF_ERR();
7043 return Py_BuildValue("s", mode);
7044}
7045#endif
7046
7047#if (DBVER < 47)
7048static PyObject*
7049DBEnv_set_intermediate_dir(DBEnvObject* self, PyObject* args)
7050{
7051 int err;
7052 int mode;
7053 u_int32_t flags;
7054
7055 if (!PyArg_ParseTuple(args, "iI:set_intermediate_dir", &mode, &flags))
7056 return NULL;
7057
7058 CHECK_ENV_NOT_CLOSED(self);
7059
7060 MYDB_BEGIN_ALLOW_THREADS;
7061 err = self->db_env->set_intermediate_dir(self->db_env, mode, flags);
7062 MYDB_END_ALLOW_THREADS;
7063 RETURN_IF_ERR();
7064 RETURN_NONE();
7065}
7066#endif
7067
7068static PyObject*
7069DBEnv_get_open_flags(DBEnvObject* self)
7070{
7071 int err;
7072 unsigned int flags;
7073
7074 CHECK_ENV_NOT_CLOSED(self);
7075
7076 MYDB_BEGIN_ALLOW_THREADS;
7077 err = self->db_env->get_open_flags(self->db_env, &flags);
7078 MYDB_END_ALLOW_THREADS;
7079 RETURN_IF_ERR();
7080 return NUMBER_FromLong(flags);
7081}
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007082
Matthias Klose54cc5392010-03-15 12:46:18 +00007083#if (DBVER < 48)
Jesus Ceaef9764f2008-05-13 18:45:46 +00007084static PyObject*
Jesus Ceaca3939c2008-05-22 15:27:38 +00007085DBEnv_set_rpc_server(DBEnvObject* self, PyObject* args, PyObject* kwargs)
7086{
7087 int err;
7088 char *host;
7089 long cl_timeout=0, sv_timeout=0;
7090
7091 static char* kwnames[] = { "host", "cl_timeout", "sv_timeout", NULL};
7092
7093 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|ll:set_rpc_server", kwnames,
7094 &host, &cl_timeout, &sv_timeout))
7095 return NULL;
7096 CHECK_ENV_NOT_CLOSED(self);
7097
7098 MYDB_BEGIN_ALLOW_THREADS;
7099 err = self->db_env->set_rpc_server(self->db_env, NULL, host, cl_timeout,
7100 sv_timeout, 0);
7101 MYDB_END_ALLOW_THREADS;
7102 RETURN_IF_ERR();
7103 RETURN_NONE();
7104}
Matthias Klose54cc5392010-03-15 12:46:18 +00007105#endif
Jesus Ceaca3939c2008-05-22 15:27:38 +00007106
Jesus Cea6557aac2010-03-22 14:22:26 +00007107static PyObject*
7108DBEnv_set_mp_max_openfd(DBEnvObject* self, PyObject* args)
7109{
7110 int err;
7111 int maxopenfd;
7112
7113 if (!PyArg_ParseTuple(args, "i:set_mp_max_openfd", &maxopenfd)) {
7114 return NULL;
7115 }
7116 CHECK_ENV_NOT_CLOSED(self);
7117 MYDB_BEGIN_ALLOW_THREADS;
7118 err = self->db_env->set_mp_max_openfd(self->db_env, maxopenfd);
7119 MYDB_END_ALLOW_THREADS;
7120 RETURN_IF_ERR();
7121 RETURN_NONE();
7122}
7123
7124static PyObject*
7125DBEnv_get_mp_max_openfd(DBEnvObject* self)
7126{
7127 int err;
7128 int maxopenfd;
7129
7130 CHECK_ENV_NOT_CLOSED(self);
7131
7132 MYDB_BEGIN_ALLOW_THREADS;
7133 err = self->db_env->get_mp_max_openfd(self->db_env, &maxopenfd);
7134 MYDB_END_ALLOW_THREADS;
7135 RETURN_IF_ERR();
7136 return NUMBER_FromLong(maxopenfd);
7137}
7138
7139
7140static PyObject*
7141DBEnv_set_mp_max_write(DBEnvObject* self, PyObject* args)
7142{
7143 int err;
7144 int maxwrite, maxwrite_sleep;
7145
7146 if (!PyArg_ParseTuple(args, "ii:set_mp_max_write", &maxwrite,
7147 &maxwrite_sleep)) {
7148 return NULL;
7149 }
7150 CHECK_ENV_NOT_CLOSED(self);
7151 MYDB_BEGIN_ALLOW_THREADS;
7152 err = self->db_env->set_mp_max_write(self->db_env, maxwrite,
7153 maxwrite_sleep);
7154 MYDB_END_ALLOW_THREADS;
7155 RETURN_IF_ERR();
7156 RETURN_NONE();
7157}
7158
7159static PyObject*
7160DBEnv_get_mp_max_write(DBEnvObject* self)
7161{
7162 int err;
7163 int maxwrite;
7164#if (DBVER >= 46)
7165 db_timeout_t maxwrite_sleep;
7166#else
7167 int maxwrite_sleep;
7168#endif
7169
7170 CHECK_ENV_NOT_CLOSED(self);
7171
7172 MYDB_BEGIN_ALLOW_THREADS;
7173 err = self->db_env->get_mp_max_write(self->db_env, &maxwrite,
7174 &maxwrite_sleep);
7175 MYDB_END_ALLOW_THREADS;
7176 RETURN_IF_ERR();
7177
7178 return Py_BuildValue("(ii)", maxwrite, (int)maxwrite_sleep);
7179}
Jesus Cea6557aac2010-03-22 14:22:26 +00007180
7181
Jesus Ceaca3939c2008-05-22 15:27:38 +00007182static PyObject*
Jesus Ceaef9764f2008-05-13 18:45:46 +00007183DBEnv_set_verbose(DBEnvObject* self, PyObject* args)
7184{
7185 int err;
7186 int which, onoff;
7187
7188 if (!PyArg_ParseTuple(args, "ii:set_verbose", &which, &onoff)) {
7189 return NULL;
7190 }
7191 CHECK_ENV_NOT_CLOSED(self);
7192 MYDB_BEGIN_ALLOW_THREADS;
7193 err = self->db_env->set_verbose(self->db_env, which, onoff);
7194 MYDB_END_ALLOW_THREADS;
7195 RETURN_IF_ERR();
7196 RETURN_NONE();
7197}
7198
Jesus Ceaef9764f2008-05-13 18:45:46 +00007199static PyObject*
7200DBEnv_get_verbose(DBEnvObject* self, PyObject* args)
7201{
7202 int err;
7203 int which;
7204 int verbose;
7205
7206 if (!PyArg_ParseTuple(args, "i:get_verbose", &which)) {
7207 return NULL;
7208 }
7209 CHECK_ENV_NOT_CLOSED(self);
7210 MYDB_BEGIN_ALLOW_THREADS;
7211 err = self->db_env->get_verbose(self->db_env, which, &verbose);
7212 MYDB_END_ALLOW_THREADS;
7213 RETURN_IF_ERR();
7214 return PyBool_FromLong(verbose);
7215}
Jesus Ceaef9764f2008-05-13 18:45:46 +00007216
7217#if (DBVER >= 45)
7218static void
7219_dbenv_event_notifyCallback(DB_ENV* db_env, u_int32_t event, void *event_info)
7220{
7221 DBEnvObject *dbenv;
7222 PyObject* callback;
7223 PyObject* args;
7224 PyObject* result = NULL;
7225
7226 MYDB_BEGIN_BLOCK_THREADS;
7227 dbenv = (DBEnvObject *)db_env->app_private;
7228 callback = dbenv->event_notifyCallback;
7229 if (callback) {
7230 if (event == DB_EVENT_REP_NEWMASTER) {
7231 args = Py_BuildValue("(Oii)", dbenv, event, *((int *)event_info));
7232 } else {
7233 args = Py_BuildValue("(OiO)", dbenv, event, Py_None);
7234 }
7235 if (args) {
7236 result = PyEval_CallObject(callback, args);
7237 }
7238 if ((!args) || (!result)) {
7239 PyErr_Print();
7240 }
7241 Py_XDECREF(args);
7242 Py_XDECREF(result);
7243 }
7244 MYDB_END_BLOCK_THREADS;
7245}
7246#endif
7247
7248#if (DBVER >= 45)
7249static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007250DBEnv_set_event_notify(DBEnvObject* self, PyObject* notifyFunc)
Jesus Ceaef9764f2008-05-13 18:45:46 +00007251{
7252 int err;
Jesus Ceaef9764f2008-05-13 18:45:46 +00007253
7254 CHECK_ENV_NOT_CLOSED(self);
7255
7256 if (!PyCallable_Check(notifyFunc)) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00007257 makeTypeError("Callable", notifyFunc);
7258 return NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00007259 }
7260
7261 Py_XDECREF(self->event_notifyCallback);
7262 Py_INCREF(notifyFunc);
7263 self->event_notifyCallback = notifyFunc;
7264
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007265 /* This is to workaround a problem with un-initialized threads (see
7266 comment in DB_associate) */
7267#ifdef WITH_THREAD
7268 PyEval_InitThreads();
7269#endif
7270
Jesus Ceaef9764f2008-05-13 18:45:46 +00007271 MYDB_BEGIN_ALLOW_THREADS;
7272 err = self->db_env->set_event_notify(self->db_env, _dbenv_event_notifyCallback);
7273 MYDB_END_ALLOW_THREADS;
7274
7275 if (err) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00007276 Py_DECREF(notifyFunc);
7277 self->event_notifyCallback = NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00007278 }
7279
7280 RETURN_IF_ERR();
7281 RETURN_NONE();
7282}
7283#endif
7284
7285
7286/* --------------------------------------------------------------------- */
7287/* REPLICATION METHODS: Base Replication */
7288
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007289
7290static PyObject*
7291DBEnv_rep_process_message(DBEnvObject* self, PyObject* args)
7292{
7293 int err;
7294 PyObject *control_py, *rec_py;
7295 DBT control, rec;
7296 int envid;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007297 DB_LSN lsn;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007298
7299 if (!PyArg_ParseTuple(args, "OOi:rep_process_message", &control_py,
7300 &rec_py, &envid))
7301 return NULL;
7302 CHECK_ENV_NOT_CLOSED(self);
7303
7304 if (!make_dbt(control_py, &control))
7305 return NULL;
7306 if (!make_dbt(rec_py, &rec))
7307 return NULL;
7308
7309 MYDB_BEGIN_ALLOW_THREADS;
7310#if (DBVER >= 46)
7311 err = self->db_env->rep_process_message(self->db_env, &control, &rec,
7312 envid, &lsn);
7313#else
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007314 err = self->db_env->rep_process_message(self->db_env, &control, &rec,
7315 &envid, &lsn);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007316#endif
7317 MYDB_END_ALLOW_THREADS;
7318 switch (err) {
7319 case DB_REP_NEWMASTER :
7320 return Py_BuildValue("(iO)", envid, Py_None);
7321 break;
7322
7323 case DB_REP_DUPMASTER :
7324 case DB_REP_HOLDELECTION :
7325#if (DBVER >= 44)
7326 case DB_REP_IGNORE :
7327 case DB_REP_JOIN_FAILURE :
7328#endif
7329 return Py_BuildValue("(iO)", err, Py_None);
7330 break;
7331 case DB_REP_NEWSITE :
Jesus Cea4907d272008-08-31 14:00:51 +00007332 {
7333 PyObject *tmp, *r;
7334
7335 if (!(tmp = PyBytes_FromStringAndSize(rec.data, rec.size))) {
7336 return NULL;
7337 }
7338
7339 r = Py_BuildValue("(iO)", err, tmp);
7340 Py_DECREF(tmp);
7341 return r;
7342 break;
7343 }
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007344 case DB_REP_NOTPERM :
7345 case DB_REP_ISPERM :
7346 return Py_BuildValue("(i(ll))", err, lsn.file, lsn.offset);
7347 break;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007348 }
7349 RETURN_IF_ERR();
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07007350 return PyTuple_Pack(2, Py_None, Py_None);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007351}
7352
7353static int
7354_DBEnv_rep_transportCallback(DB_ENV* db_env, const DBT* control, const DBT* rec,
7355 const DB_LSN *lsn, int envid, u_int32_t flags)
7356{
7357 DBEnvObject *dbenv;
7358 PyObject* rep_transport;
7359 PyObject* args;
Jesus Cea4907d272008-08-31 14:00:51 +00007360 PyObject *a, *b;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007361 PyObject* result = NULL;
7362 int ret=0;
7363
7364 MYDB_BEGIN_BLOCK_THREADS;
7365 dbenv = (DBEnvObject *)db_env->app_private;
7366 rep_transport = dbenv->rep_transport;
7367
Jesus Cea4907d272008-08-31 14:00:51 +00007368 /*
7369 ** The errors in 'a' or 'b' are detected in "Py_BuildValue".
7370 */
7371 a = PyBytes_FromStringAndSize(control->data, control->size);
7372 b = PyBytes_FromStringAndSize(rec->data, rec->size);
7373
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007374 args = Py_BuildValue(
Jesus Cea4907d272008-08-31 14:00:51 +00007375 "(OOO(ll)iI)",
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007376 dbenv,
Jesus Cea4907d272008-08-31 14:00:51 +00007377 a, b,
7378 lsn->file, lsn->offset, envid, flags);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007379 if (args) {
7380 result = PyEval_CallObject(rep_transport, args);
7381 }
7382
7383 if ((!args) || (!result)) {
7384 PyErr_Print();
7385 ret = -1;
7386 }
Jesus Cea4907d272008-08-31 14:00:51 +00007387 Py_XDECREF(a);
7388 Py_XDECREF(b);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007389 Py_XDECREF(args);
7390 Py_XDECREF(result);
7391 MYDB_END_BLOCK_THREADS;
7392 return ret;
7393}
7394
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007395static PyObject*
7396DBEnv_rep_set_transport(DBEnvObject* self, PyObject* args)
7397{
7398 int err;
7399 int envid;
7400 PyObject *rep_transport;
7401
7402 if (!PyArg_ParseTuple(args, "iO:rep_set_transport", &envid, &rep_transport))
7403 return NULL;
7404 CHECK_ENV_NOT_CLOSED(self);
7405 if (!PyCallable_Check(rep_transport)) {
7406 makeTypeError("Callable", rep_transport);
7407 return NULL;
7408 }
7409
7410 MYDB_BEGIN_ALLOW_THREADS;
7411#if (DBVER >=45)
7412 err = self->db_env->rep_set_transport(self->db_env, envid,
7413 &_DBEnv_rep_transportCallback);
7414#else
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007415 err = self->db_env->set_rep_transport(self->db_env, envid,
7416 &_DBEnv_rep_transportCallback);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007417#endif
7418 MYDB_END_ALLOW_THREADS;
7419 RETURN_IF_ERR();
7420
7421 Py_DECREF(self->rep_transport);
7422 Py_INCREF(rep_transport);
7423 self->rep_transport = rep_transport;
7424 RETURN_NONE();
7425}
7426
7427#if (DBVER >= 47)
7428static PyObject*
7429DBEnv_rep_set_request(DBEnvObject* self, PyObject* args)
7430{
7431 int err;
7432 unsigned int minimum, maximum;
7433
7434 if (!PyArg_ParseTuple(args,"II:rep_set_request", &minimum, &maximum))
7435 return NULL;
7436 CHECK_ENV_NOT_CLOSED(self);
7437
7438 MYDB_BEGIN_ALLOW_THREADS;
7439 err = self->db_env->rep_set_request(self->db_env, minimum, maximum);
7440 MYDB_END_ALLOW_THREADS;
7441 RETURN_IF_ERR();
7442 RETURN_NONE();
7443}
7444
7445static PyObject*
7446DBEnv_rep_get_request(DBEnvObject* self)
7447{
7448 int err;
7449 u_int32_t minimum, maximum;
7450
7451 CHECK_ENV_NOT_CLOSED(self);
7452 MYDB_BEGIN_ALLOW_THREADS;
7453 err = self->db_env->rep_get_request(self->db_env, &minimum, &maximum);
7454 MYDB_END_ALLOW_THREADS;
7455 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007456 return Py_BuildValue("II", minimum, maximum);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007457}
7458#endif
7459
7460#if (DBVER >= 45)
7461static PyObject*
7462DBEnv_rep_set_limit(DBEnvObject* self, PyObject* args)
7463{
7464 int err;
7465 int limit;
7466
7467 if (!PyArg_ParseTuple(args,"i:rep_set_limit", &limit))
7468 return NULL;
7469 CHECK_ENV_NOT_CLOSED(self);
7470
7471 MYDB_BEGIN_ALLOW_THREADS;
7472 err = self->db_env->rep_set_limit(self->db_env, 0, limit);
7473 MYDB_END_ALLOW_THREADS;
7474 RETURN_IF_ERR();
7475 RETURN_NONE();
7476}
7477
7478static PyObject*
7479DBEnv_rep_get_limit(DBEnvObject* self)
7480{
7481 int err;
7482 u_int32_t gbytes, bytes;
7483
7484 CHECK_ENV_NOT_CLOSED(self);
7485 MYDB_BEGIN_ALLOW_THREADS;
7486 err = self->db_env->rep_get_limit(self->db_env, &gbytes, &bytes);
7487 MYDB_END_ALLOW_THREADS;
7488 RETURN_IF_ERR();
7489 return NUMBER_FromLong(bytes);
7490}
7491#endif
7492
7493#if (DBVER >= 44)
7494static PyObject*
7495DBEnv_rep_set_config(DBEnvObject* self, PyObject* args)
7496{
7497 int err;
7498 int which;
7499 int onoff;
7500
7501 if (!PyArg_ParseTuple(args,"ii:rep_set_config", &which, &onoff))
7502 return NULL;
7503 CHECK_ENV_NOT_CLOSED(self);
7504
7505 MYDB_BEGIN_ALLOW_THREADS;
7506 err = self->db_env->rep_set_config(self->db_env, which, onoff);
7507 MYDB_END_ALLOW_THREADS;
7508 RETURN_IF_ERR();
7509 RETURN_NONE();
7510}
7511
7512static PyObject*
7513DBEnv_rep_get_config(DBEnvObject* self, PyObject* args)
7514{
7515 int err;
7516 int which;
7517 int onoff;
7518
7519 if (!PyArg_ParseTuple(args, "i:rep_get_config", &which)) {
7520 return NULL;
7521 }
7522 CHECK_ENV_NOT_CLOSED(self);
7523 MYDB_BEGIN_ALLOW_THREADS;
7524 err = self->db_env->rep_get_config(self->db_env, which, &onoff);
7525 MYDB_END_ALLOW_THREADS;
7526 RETURN_IF_ERR();
7527 return PyBool_FromLong(onoff);
7528}
7529#endif
7530
7531#if (DBVER >= 46)
7532static PyObject*
7533DBEnv_rep_elect(DBEnvObject* self, PyObject* args)
7534{
7535 int err;
7536 u_int32_t nsites, nvotes;
7537
7538 if (!PyArg_ParseTuple(args, "II:rep_elect", &nsites, &nvotes)) {
7539 return NULL;
7540 }
7541 CHECK_ENV_NOT_CLOSED(self);
7542 MYDB_BEGIN_ALLOW_THREADS;
Jesus Cea2ab4a912012-01-16 23:57:34 +01007543 err = self->db_env->rep_elect(self->db_env, nsites, nvotes, 0);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007544 MYDB_END_ALLOW_THREADS;
7545 RETURN_IF_ERR();
7546 RETURN_NONE();
7547}
7548#endif
7549
7550static PyObject*
7551DBEnv_rep_start(DBEnvObject* self, PyObject* args, PyObject* kwargs)
7552{
7553 int err;
7554 PyObject *cdata_py = Py_None;
7555 DBT cdata;
7556 int flags;
7557 static char* kwnames[] = {"flags","cdata", NULL};
7558
7559 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
7560 "i|O:rep_start", kwnames, &flags, &cdata_py))
7561 {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00007562 return NULL;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007563 }
7564 CHECK_ENV_NOT_CLOSED(self);
7565
7566 if (!make_dbt(cdata_py, &cdata))
7567 return NULL;
7568
7569 MYDB_BEGIN_ALLOW_THREADS;
7570 err = self->db_env->rep_start(self->db_env, cdata.size ? &cdata : NULL,
7571 flags);
7572 MYDB_END_ALLOW_THREADS;
7573 RETURN_IF_ERR();
7574 RETURN_NONE();
7575}
7576
7577#if (DBVER >= 44)
7578static PyObject*
7579DBEnv_rep_sync(DBEnvObject* self)
7580{
7581 int err;
7582
7583 CHECK_ENV_NOT_CLOSED(self);
7584 MYDB_BEGIN_ALLOW_THREADS;
7585 err = self->db_env->rep_sync(self->db_env, 0);
7586 MYDB_END_ALLOW_THREADS;
7587 RETURN_IF_ERR();
7588 RETURN_NONE();
7589}
7590#endif
7591
7592
Jesus Ceaef9764f2008-05-13 18:45:46 +00007593#if (DBVER >= 45)
7594static PyObject*
7595DBEnv_rep_set_nsites(DBEnvObject* self, PyObject* args)
7596{
7597 int err;
7598 int nsites;
7599
7600 if (!PyArg_ParseTuple(args, "i:rep_set_nsites", &nsites)) {
7601 return NULL;
7602 }
7603 CHECK_ENV_NOT_CLOSED(self);
7604 MYDB_BEGIN_ALLOW_THREADS;
7605 err = self->db_env->rep_set_nsites(self->db_env, nsites);
7606 MYDB_END_ALLOW_THREADS;
7607 RETURN_IF_ERR();
7608 RETURN_NONE();
7609}
7610
7611static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007612DBEnv_rep_get_nsites(DBEnvObject* self)
Jesus Ceaef9764f2008-05-13 18:45:46 +00007613{
7614 int err;
Jesus Ceaca3939c2008-05-22 15:27:38 +00007615#if (DBVER >= 47)
7616 u_int32_t nsites;
7617#else
Jesus Ceaef9764f2008-05-13 18:45:46 +00007618 int nsites;
Jesus Ceaca3939c2008-05-22 15:27:38 +00007619#endif
Jesus Ceaef9764f2008-05-13 18:45:46 +00007620
Jesus Ceaef9764f2008-05-13 18:45:46 +00007621 CHECK_ENV_NOT_CLOSED(self);
7622 MYDB_BEGIN_ALLOW_THREADS;
7623 err = self->db_env->rep_get_nsites(self->db_env, &nsites);
7624 MYDB_END_ALLOW_THREADS;
7625 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007626 return NUMBER_FromLong(nsites);
Jesus Ceaef9764f2008-05-13 18:45:46 +00007627}
7628
7629static PyObject*
7630DBEnv_rep_set_priority(DBEnvObject* self, PyObject* args)
7631{
7632 int err;
7633 int priority;
7634
7635 if (!PyArg_ParseTuple(args, "i:rep_set_priority", &priority)) {
7636 return NULL;
7637 }
7638 CHECK_ENV_NOT_CLOSED(self);
7639 MYDB_BEGIN_ALLOW_THREADS;
7640 err = self->db_env->rep_set_priority(self->db_env, priority);
7641 MYDB_END_ALLOW_THREADS;
7642 RETURN_IF_ERR();
7643 RETURN_NONE();
7644}
7645
7646static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007647DBEnv_rep_get_priority(DBEnvObject* self)
Jesus Ceaef9764f2008-05-13 18:45:46 +00007648{
7649 int err;
Jesus Ceaca3939c2008-05-22 15:27:38 +00007650#if (DBVER >= 47)
7651 u_int32_t priority;
7652#else
Jesus Ceaef9764f2008-05-13 18:45:46 +00007653 int priority;
Jesus Ceaca3939c2008-05-22 15:27:38 +00007654#endif
Jesus Ceaef9764f2008-05-13 18:45:46 +00007655
Jesus Ceaef9764f2008-05-13 18:45:46 +00007656 CHECK_ENV_NOT_CLOSED(self);
7657 MYDB_BEGIN_ALLOW_THREADS;
7658 err = self->db_env->rep_get_priority(self->db_env, &priority);
7659 MYDB_END_ALLOW_THREADS;
7660 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007661 return NUMBER_FromLong(priority);
Jesus Ceaef9764f2008-05-13 18:45:46 +00007662}
7663
7664static PyObject*
7665DBEnv_rep_set_timeout(DBEnvObject* self, PyObject* args)
7666{
7667 int err;
7668 int which, timeout;
7669
7670 if (!PyArg_ParseTuple(args, "ii:rep_set_timeout", &which, &timeout)) {
7671 return NULL;
7672 }
7673 CHECK_ENV_NOT_CLOSED(self);
7674 MYDB_BEGIN_ALLOW_THREADS;
7675 err = self->db_env->rep_set_timeout(self->db_env, which, timeout);
7676 MYDB_END_ALLOW_THREADS;
7677 RETURN_IF_ERR();
7678 RETURN_NONE();
7679}
7680
7681static PyObject*
7682DBEnv_rep_get_timeout(DBEnvObject* self, PyObject* args)
7683{
7684 int err;
7685 int which;
7686 u_int32_t timeout;
7687
7688 if (!PyArg_ParseTuple(args, "i:rep_get_timeout", &which)) {
7689 return NULL;
7690 }
7691 CHECK_ENV_NOT_CLOSED(self);
7692 MYDB_BEGIN_ALLOW_THREADS;
7693 err = self->db_env->rep_get_timeout(self->db_env, which, &timeout);
7694 MYDB_END_ALLOW_THREADS;
7695 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007696 return NUMBER_FromLong(timeout);
Jesus Ceaef9764f2008-05-13 18:45:46 +00007697}
7698#endif
7699
Jesus Cea6557aac2010-03-22 14:22:26 +00007700
7701#if (DBVER >= 47)
7702static PyObject*
7703DBEnv_rep_set_clockskew(DBEnvObject* self, PyObject* args)
7704{
7705 int err;
7706 unsigned int fast, slow;
7707
Jesus Cea6557aac2010-03-22 14:22:26 +00007708 if (!PyArg_ParseTuple(args,"II:rep_set_clockskew", &fast, &slow))
7709 return NULL;
Jesus Cea6557aac2010-03-22 14:22:26 +00007710
7711 CHECK_ENV_NOT_CLOSED(self);
7712
7713 MYDB_BEGIN_ALLOW_THREADS;
7714 err = self->db_env->rep_set_clockskew(self->db_env, fast, slow);
7715 MYDB_END_ALLOW_THREADS;
7716 RETURN_IF_ERR();
7717 RETURN_NONE();
7718}
7719
7720static PyObject*
7721DBEnv_rep_get_clockskew(DBEnvObject* self)
7722{
7723 int err;
7724 unsigned int fast, slow;
7725
7726 CHECK_ENV_NOT_CLOSED(self);
7727 MYDB_BEGIN_ALLOW_THREADS;
7728 err = self->db_env->rep_get_clockskew(self->db_env, &fast, &slow);
7729 MYDB_END_ALLOW_THREADS;
7730 RETURN_IF_ERR();
Jesus Cea6557aac2010-03-22 14:22:26 +00007731 return Py_BuildValue("(II)", fast, slow);
Jesus Cea6557aac2010-03-22 14:22:26 +00007732}
7733#endif
7734
Jesus Cea6557aac2010-03-22 14:22:26 +00007735static PyObject*
7736DBEnv_rep_stat_print(DBEnvObject* self, PyObject* args, PyObject *kwargs)
7737{
7738 int err;
7739 int flags=0;
7740 static char* kwnames[] = { "flags", NULL };
7741
7742 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:rep_stat_print",
7743 kwnames, &flags))
7744 {
7745 return NULL;
7746 }
7747 CHECK_ENV_NOT_CLOSED(self);
7748 MYDB_BEGIN_ALLOW_THREADS;
7749 err = self->db_env->rep_stat_print(self->db_env, flags);
7750 MYDB_END_ALLOW_THREADS;
7751 RETURN_IF_ERR();
7752 RETURN_NONE();
7753}
Jesus Cea6557aac2010-03-22 14:22:26 +00007754
7755static PyObject*
7756DBEnv_rep_stat(DBEnvObject* self, PyObject* args, PyObject *kwargs)
7757{
7758 int err;
7759 int flags=0;
7760 DB_REP_STAT *statp;
7761 PyObject *stats;
7762 static char* kwnames[] = { "flags", NULL };
7763
7764 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:rep_stat",
7765 kwnames, &flags))
7766 {
7767 return NULL;
7768 }
7769 CHECK_ENV_NOT_CLOSED(self);
7770 MYDB_BEGIN_ALLOW_THREADS;
7771 err = self->db_env->rep_stat(self->db_env, &statp, flags);
7772 MYDB_END_ALLOW_THREADS;
7773 RETURN_IF_ERR();
7774
7775 stats=PyDict_New();
7776 if (stats == NULL) {
7777 free(statp);
7778 return NULL;
7779 }
7780
7781#define MAKE_ENTRY(name) _addIntToDict(stats, #name, statp->st_##name)
7782#define MAKE_DB_LSN_ENTRY(name) _addDB_lsnToDict(stats , #name, statp->st_##name)
7783
7784#if (DBVER >= 44)
7785 MAKE_ENTRY(bulk_fills);
7786 MAKE_ENTRY(bulk_overflows);
7787 MAKE_ENTRY(bulk_records);
7788 MAKE_ENTRY(bulk_transfers);
7789 MAKE_ENTRY(client_rerequests);
7790 MAKE_ENTRY(client_svc_miss);
7791 MAKE_ENTRY(client_svc_req);
7792#endif
7793 MAKE_ENTRY(dupmasters);
Jesus Cea6557aac2010-03-22 14:22:26 +00007794 MAKE_ENTRY(egen);
7795 MAKE_ENTRY(election_nvotes);
7796 MAKE_ENTRY(startup_complete);
7797 MAKE_ENTRY(pg_duplicated);
7798 MAKE_ENTRY(pg_records);
7799 MAKE_ENTRY(pg_requested);
7800 MAKE_ENTRY(next_pg);
7801 MAKE_ENTRY(waiting_pg);
Jesus Cea6557aac2010-03-22 14:22:26 +00007802 MAKE_ENTRY(election_cur_winner);
7803 MAKE_ENTRY(election_gen);
7804 MAKE_DB_LSN_ENTRY(election_lsn);
7805 MAKE_ENTRY(election_nsites);
7806 MAKE_ENTRY(election_priority);
7807#if (DBVER >= 44)
7808 MAKE_ENTRY(election_sec);
7809 MAKE_ENTRY(election_usec);
7810#endif
7811 MAKE_ENTRY(election_status);
7812 MAKE_ENTRY(election_tiebreaker);
7813 MAKE_ENTRY(election_votes);
7814 MAKE_ENTRY(elections);
7815 MAKE_ENTRY(elections_won);
7816 MAKE_ENTRY(env_id);
7817 MAKE_ENTRY(env_priority);
7818 MAKE_ENTRY(gen);
7819 MAKE_ENTRY(log_duplicated);
7820 MAKE_ENTRY(log_queued);
7821 MAKE_ENTRY(log_queued_max);
7822 MAKE_ENTRY(log_queued_total);
7823 MAKE_ENTRY(log_records);
7824 MAKE_ENTRY(log_requested);
7825 MAKE_ENTRY(master);
7826 MAKE_ENTRY(master_changes);
7827#if (DBVER >= 47)
7828 MAKE_ENTRY(max_lease_sec);
7829 MAKE_ENTRY(max_lease_usec);
7830 MAKE_DB_LSN_ENTRY(max_perm_lsn);
7831#endif
7832 MAKE_ENTRY(msgs_badgen);
7833 MAKE_ENTRY(msgs_processed);
7834 MAKE_ENTRY(msgs_recover);
7835 MAKE_ENTRY(msgs_send_failures);
7836 MAKE_ENTRY(msgs_sent);
7837 MAKE_ENTRY(newsites);
7838 MAKE_DB_LSN_ENTRY(next_lsn);
7839 MAKE_ENTRY(nsites);
7840 MAKE_ENTRY(nthrottles);
7841 MAKE_ENTRY(outdated);
7842#if (DBVER >= 46)
7843 MAKE_ENTRY(startsync_delayed);
7844#endif
7845 MAKE_ENTRY(status);
7846 MAKE_ENTRY(txns_applied);
7847 MAKE_DB_LSN_ENTRY(waiting_lsn);
7848
7849#undef MAKE_DB_LSN_ENTRY
7850#undef MAKE_ENTRY
7851
7852 free(statp);
7853 return stats;
7854}
7855
Jesus Ceaef9764f2008-05-13 18:45:46 +00007856/* --------------------------------------------------------------------- */
7857/* REPLICATION METHODS: Replication Manager */
7858
7859#if (DBVER >= 45)
7860static PyObject*
7861DBEnv_repmgr_start(DBEnvObject* self, PyObject* args, PyObject*
7862 kwargs)
7863{
7864 int err;
7865 int nthreads, flags;
7866 static char* kwnames[] = {"nthreads","flags", NULL};
7867
7868 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
7869 "ii:repmgr_start", kwnames, &nthreads, &flags))
7870 {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00007871 return NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00007872 }
7873 CHECK_ENV_NOT_CLOSED(self);
7874 MYDB_BEGIN_ALLOW_THREADS;
7875 err = self->db_env->repmgr_start(self->db_env, nthreads, flags);
7876 MYDB_END_ALLOW_THREADS;
7877 RETURN_IF_ERR();
7878 RETURN_NONE();
7879}
7880
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07007881#if (DBVER < 52)
Jesus Ceaef9764f2008-05-13 18:45:46 +00007882static PyObject*
7883DBEnv_repmgr_set_local_site(DBEnvObject* self, PyObject* args, PyObject*
7884 kwargs)
7885{
7886 int err;
7887 char *host;
7888 int port;
7889 int flags = 0;
7890 static char* kwnames[] = {"host", "port", "flags", NULL};
7891
7892 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
7893 "si|i:repmgr_set_local_site", kwnames, &host, &port, &flags))
7894 {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00007895 return NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00007896 }
7897 CHECK_ENV_NOT_CLOSED(self);
7898 MYDB_BEGIN_ALLOW_THREADS;
7899 err = self->db_env->repmgr_set_local_site(self->db_env, host, port, flags);
7900 MYDB_END_ALLOW_THREADS;
7901 RETURN_IF_ERR();
7902 RETURN_NONE();
7903}
7904
7905static PyObject*
7906DBEnv_repmgr_add_remote_site(DBEnvObject* self, PyObject* args, PyObject*
7907 kwargs)
7908{
7909 int err;
7910 char *host;
7911 int port;
7912 int flags = 0;
7913 int eidp;
7914 static char* kwnames[] = {"host", "port", "flags", NULL};
7915
7916 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
7917 "si|i:repmgr_add_remote_site", kwnames, &host, &port, &flags))
7918 {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00007919 return NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00007920 }
7921 CHECK_ENV_NOT_CLOSED(self);
7922 MYDB_BEGIN_ALLOW_THREADS;
7923 err = self->db_env->repmgr_add_remote_site(self->db_env, host, port, &eidp, flags);
7924 MYDB_END_ALLOW_THREADS;
7925 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007926 return NUMBER_FromLong(eidp);
Jesus Ceaef9764f2008-05-13 18:45:46 +00007927}
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07007928#endif
Jesus Ceaef9764f2008-05-13 18:45:46 +00007929
7930static PyObject*
7931DBEnv_repmgr_set_ack_policy(DBEnvObject* self, PyObject* args)
7932{
7933 int err;
7934 int ack_policy;
7935
7936 if (!PyArg_ParseTuple(args, "i:repmgr_set_ack_policy", &ack_policy))
7937 {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00007938 return NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00007939 }
7940 CHECK_ENV_NOT_CLOSED(self);
7941 MYDB_BEGIN_ALLOW_THREADS;
7942 err = self->db_env->repmgr_set_ack_policy(self->db_env, ack_policy);
7943 MYDB_END_ALLOW_THREADS;
7944 RETURN_IF_ERR();
7945 RETURN_NONE();
7946}
7947
7948static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007949DBEnv_repmgr_get_ack_policy(DBEnvObject* self)
Jesus Ceaef9764f2008-05-13 18:45:46 +00007950{
7951 int err;
7952 int ack_policy;
7953
Jesus Ceaef9764f2008-05-13 18:45:46 +00007954 CHECK_ENV_NOT_CLOSED(self);
7955 MYDB_BEGIN_ALLOW_THREADS;
7956 err = self->db_env->repmgr_get_ack_policy(self->db_env, &ack_policy);
7957 MYDB_END_ALLOW_THREADS;
7958 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007959 return NUMBER_FromLong(ack_policy);
Jesus Ceaef9764f2008-05-13 18:45:46 +00007960}
7961
7962static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007963DBEnv_repmgr_site_list(DBEnvObject* self)
Jesus Ceaef9764f2008-05-13 18:45:46 +00007964{
7965 int err;
7966 unsigned int countp;
7967 DB_REPMGR_SITE *listp;
7968 PyObject *stats, *key, *tuple;
7969
Jesus Ceaef9764f2008-05-13 18:45:46 +00007970 CHECK_ENV_NOT_CLOSED(self);
7971 MYDB_BEGIN_ALLOW_THREADS;
7972 err = self->db_env->repmgr_site_list(self->db_env, &countp, &listp);
7973 MYDB_END_ALLOW_THREADS;
7974 RETURN_IF_ERR();
7975
7976 stats=PyDict_New();
7977 if (stats == NULL) {
7978 free(listp);
7979 return NULL;
7980 }
7981
7982 for(;countp--;) {
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007983 key=NUMBER_FromLong(listp[countp].eid);
Jesus Ceaef9764f2008-05-13 18:45:46 +00007984 if(!key) {
7985 Py_DECREF(stats);
7986 free(listp);
7987 return NULL;
7988 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00007989 tuple=Py_BuildValue("(sII)", listp[countp].host,
7990 listp[countp].port, listp[countp].status);
Jesus Ceaef9764f2008-05-13 18:45:46 +00007991 if(!tuple) {
7992 Py_DECREF(key);
7993 Py_DECREF(stats);
7994 free(listp);
7995 return NULL;
7996 }
7997 if(PyDict_SetItem(stats, key, tuple)) {
7998 Py_DECREF(key);
7999 Py_DECREF(tuple);
8000 Py_DECREF(stats);
8001 free(listp);
8002 return NULL;
8003 }
Florent Xiclunae7901c52010-03-01 20:45:01 +00008004 Py_DECREF(key);
8005 Py_DECREF(tuple);
Jesus Ceaef9764f2008-05-13 18:45:46 +00008006 }
8007 free(listp);
8008 return stats;
8009}
8010#endif
8011
8012#if (DBVER >= 46)
8013static PyObject*
8014DBEnv_repmgr_stat_print(DBEnvObject* self, PyObject* args, PyObject *kwargs)
8015{
8016 int err;
8017 int flags=0;
8018 static char* kwnames[] = { "flags", NULL };
8019
8020 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:repmgr_stat_print",
8021 kwnames, &flags))
8022 {
8023 return NULL;
8024 }
8025 CHECK_ENV_NOT_CLOSED(self);
8026 MYDB_BEGIN_ALLOW_THREADS;
8027 err = self->db_env->repmgr_stat_print(self->db_env, flags);
8028 MYDB_END_ALLOW_THREADS;
8029 RETURN_IF_ERR();
8030 RETURN_NONE();
8031}
8032
8033static PyObject*
8034DBEnv_repmgr_stat(DBEnvObject* self, PyObject* args, PyObject *kwargs)
8035{
8036 int err;
8037 int flags=0;
8038 DB_REPMGR_STAT *statp;
8039 PyObject *stats;
8040 static char* kwnames[] = { "flags", NULL };
8041
8042 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:repmgr_stat",
8043 kwnames, &flags))
8044 {
8045 return NULL;
8046 }
8047 CHECK_ENV_NOT_CLOSED(self);
8048 MYDB_BEGIN_ALLOW_THREADS;
8049 err = self->db_env->repmgr_stat(self->db_env, &statp, flags);
8050 MYDB_END_ALLOW_THREADS;
8051 RETURN_IF_ERR();
8052
8053 stats=PyDict_New();
8054 if (stats == NULL) {
8055 free(statp);
8056 return NULL;
8057 }
8058
8059#define MAKE_ENTRY(name) _addIntToDict(stats, #name, statp->st_##name)
8060
8061 MAKE_ENTRY(perm_failed);
8062 MAKE_ENTRY(msgs_queued);
8063 MAKE_ENTRY(msgs_dropped);
8064 MAKE_ENTRY(connection_drop);
8065 MAKE_ENTRY(connect_fail);
8066
8067#undef MAKE_ENTRY
8068
8069 free(statp);
8070 return stats;
8071}
8072#endif
8073
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008074
8075/* --------------------------------------------------------------------- */
8076/* DBTxn methods */
8077
8078
Jesus Ceaef9764f2008-05-13 18:45:46 +00008079static void _close_transaction_cursors(DBTxnObject* txn)
8080{
8081 PyObject *dummy;
8082
8083 while(txn->children_cursors) {
8084 PyErr_Warn(PyExc_RuntimeWarning,
8085 "Must close cursors before resolving a transaction.");
8086 dummy=DBC_close_internal(txn->children_cursors);
8087 Py_XDECREF(dummy);
8088 }
8089}
8090
8091static void _promote_transaction_dbs_and_sequences(DBTxnObject *txn)
8092{
8093 DBObject *db;
Jesus Ceaef9764f2008-05-13 18:45:46 +00008094 DBSequenceObject *dbs;
Jesus Ceaef9764f2008-05-13 18:45:46 +00008095
8096 while (txn->children_dbs) {
8097 db=txn->children_dbs;
8098 EXTRACT_FROM_DOUBLE_LINKED_LIST_TXN(db);
8099 if (txn->parent_txn) {
8100 INSERT_IN_DOUBLE_LINKED_LIST_TXN(txn->parent_txn->children_dbs,db);
8101 db->txn=txn->parent_txn;
8102 } else {
8103 /* The db is already linked to its environment,
8104 ** so nothing to do.
8105 */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00008106 db->txn=NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00008107 }
8108 }
8109
Jesus Ceaef9764f2008-05-13 18:45:46 +00008110 while (txn->children_sequences) {
8111 dbs=txn->children_sequences;
8112 EXTRACT_FROM_DOUBLE_LINKED_LIST_TXN(dbs);
8113 if (txn->parent_txn) {
8114 INSERT_IN_DOUBLE_LINKED_LIST_TXN(txn->parent_txn->children_sequences,dbs);
8115 dbs->txn=txn->parent_txn;
8116 } else {
8117 /* The sequence is already linked to its
8118 ** parent db. Nothing to do.
8119 */
8120 dbs->txn=NULL;
8121 }
8122 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00008123}
8124
8125
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008126static PyObject*
8127DBTxn_commit(DBTxnObject* self, PyObject* args)
8128{
8129 int flags=0, err;
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008130 DB_TXN *txn;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008131
8132 if (!PyArg_ParseTuple(args, "|i:commit", &flags))
8133 return NULL;
8134
Jesus Ceaef9764f2008-05-13 18:45:46 +00008135 _close_transaction_cursors(self);
8136
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008137 if (!self->txn) {
Thomas Woutersb3153832006-03-08 01:47:19 +00008138 PyObject *t = Py_BuildValue("(is)", 0, "DBTxn must not be used "
Jesus Ceaef9764f2008-05-13 18:45:46 +00008139 "after txn_commit, txn_abort "
8140 "or txn_discard");
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008141 if (t) {
8142 PyErr_SetObject(DBError, t);
8143 Py_DECREF(t);
8144 }
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008145 return NULL;
8146 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00008147 self->flag_prepare=0;
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008148 txn = self->txn;
8149 self->txn = NULL; /* this DB_TXN is no longer valid after this call */
Jesus Ceaef9764f2008-05-13 18:45:46 +00008150
8151 EXTRACT_FROM_DOUBLE_LINKED_LIST(self);
8152
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008153 MYDB_BEGIN_ALLOW_THREADS;
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008154 err = txn->commit(txn, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008155 MYDB_END_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00008156
8157 _promote_transaction_dbs_and_sequences(self);
8158
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008159 RETURN_IF_ERR();
8160 RETURN_NONE();
8161}
8162
8163static PyObject*
8164DBTxn_prepare(DBTxnObject* self, PyObject* args)
8165{
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008166 int err;
8167 char* gid=NULL;
8168 int gid_size=0;
8169
8170 if (!PyArg_ParseTuple(args, "s#:prepare", &gid, &gid_size))
8171 return NULL;
8172
Matthias Klose54cc5392010-03-15 12:46:18 +00008173 if (gid_size != DB_GID_SIZE) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008174 PyErr_SetString(PyExc_TypeError,
Matthias Klose54cc5392010-03-15 12:46:18 +00008175 "gid must be DB_GID_SIZE bytes long");
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008176 return NULL;
8177 }
8178
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008179 if (!self->txn) {
Thomas Woutersb3153832006-03-08 01:47:19 +00008180 PyObject *t = Py_BuildValue("(is)", 0,"DBTxn must not be used "
Jesus Ceaef9764f2008-05-13 18:45:46 +00008181 "after txn_commit, txn_abort "
8182 "or txn_discard");
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008183 if (t) {
8184 PyErr_SetObject(DBError, t);
8185 Py_DECREF(t);
8186 }
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008187 return NULL;
8188 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00008189 self->flag_prepare=1; /* Prepare state */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008190 MYDB_BEGIN_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008191 err = self->txn->prepare(self->txn, (u_int8_t*)gid);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008192 MYDB_END_ALLOW_THREADS;
8193 RETURN_IF_ERR();
8194 RETURN_NONE();
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008195}
8196
8197
8198static PyObject*
Jesus Ceaef9764f2008-05-13 18:45:46 +00008199DBTxn_abort_discard_internal(DBTxnObject* self, int discard)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008200{
Jesus Ceaef9764f2008-05-13 18:45:46 +00008201 PyObject *dummy;
8202 int err=0;
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008203 DB_TXN *txn;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008204
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008205 if (!self->txn) {
Thomas Woutersb3153832006-03-08 01:47:19 +00008206 PyObject *t = Py_BuildValue("(is)", 0, "DBTxn must not be used "
Jesus Ceaef9764f2008-05-13 18:45:46 +00008207 "after txn_commit, txn_abort "
8208 "or txn_discard");
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008209 if (t) {
8210 PyErr_SetObject(DBError, t);
8211 Py_DECREF(t);
8212 }
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008213 return NULL;
8214 }
8215 txn = self->txn;
8216 self->txn = NULL; /* this DB_TXN is no longer valid after this call */
Jesus Ceaef9764f2008-05-13 18:45:46 +00008217
8218 _close_transaction_cursors(self);
Jesus Ceaef9764f2008-05-13 18:45:46 +00008219 while (self->children_sequences) {
8220 dummy=DBSequence_close_internal(self->children_sequences,0,0);
8221 Py_XDECREF(dummy);
8222 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00008223 while (self->children_dbs) {
Jesus Cea5cd5f122008-09-23 18:54:08 +00008224 dummy=DB_close_internal(self->children_dbs, 0, 0);
Jesus Ceaef9764f2008-05-13 18:45:46 +00008225 Py_XDECREF(dummy);
8226 }
8227
8228 EXTRACT_FROM_DOUBLE_LINKED_LIST(self);
8229
8230 MYDB_BEGIN_ALLOW_THREADS;
8231 if (discard) {
8232 assert(!self->flag_prepare);
Jesus Ceaef9764f2008-05-13 18:45:46 +00008233 err = txn->discard(txn,0);
Jesus Ceaef9764f2008-05-13 18:45:46 +00008234 } else {
8235 /*
8236 ** If the transaction is in the "prepare" or "recover" state,
8237 ** we better do not implicitly abort it.
8238 */
8239 if (!self->flag_prepare) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00008240 err = txn->abort(txn);
Jesus Ceaef9764f2008-05-13 18:45:46 +00008241 }
8242 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008243 MYDB_END_ALLOW_THREADS;
8244 RETURN_IF_ERR();
8245 RETURN_NONE();
8246}
8247
Jesus Ceaef9764f2008-05-13 18:45:46 +00008248static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008249DBTxn_abort(DBTxnObject* self)
Jesus Ceaef9764f2008-05-13 18:45:46 +00008250{
Jesus Ceaef9764f2008-05-13 18:45:46 +00008251 self->flag_prepare=0;
8252 _close_transaction_cursors(self);
8253
8254 return DBTxn_abort_discard_internal(self,0);
8255}
8256
8257static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008258DBTxn_discard(DBTxnObject* self)
Jesus Ceaef9764f2008-05-13 18:45:46 +00008259{
Jesus Ceaef9764f2008-05-13 18:45:46 +00008260 self->flag_prepare=0;
8261 _close_transaction_cursors(self);
8262
8263 return DBTxn_abort_discard_internal(self,1);
8264}
8265
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008266
8267static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008268DBTxn_id(DBTxnObject* self)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008269{
8270 int id;
8271
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008272 if (!self->txn) {
Thomas Woutersb3153832006-03-08 01:47:19 +00008273 PyObject *t = Py_BuildValue("(is)", 0, "DBTxn must not be used "
Jesus Ceaef9764f2008-05-13 18:45:46 +00008274 "after txn_commit, txn_abort "
8275 "or txn_discard");
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008276 if (t) {
8277 PyErr_SetObject(DBError, t);
8278 Py_DECREF(t);
8279 }
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008280 return NULL;
8281 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008282 MYDB_BEGIN_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008283 id = self->txn->id(self->txn);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008284 MYDB_END_ALLOW_THREADS;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008285 return NUMBER_FromLong(id);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008286}
8287
Jesus Cea6557aac2010-03-22 14:22:26 +00008288
8289static PyObject*
8290DBTxn_set_timeout(DBTxnObject* self, PyObject* args, PyObject* kwargs)
8291{
8292 int err;
8293 u_int32_t flags=0;
8294 u_int32_t timeout = 0;
8295 static char* kwnames[] = { "timeout", "flags", NULL };
8296
8297 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ii:set_timeout", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00008298 &timeout, &flags)) {
8299 return NULL;
Jesus Cea6557aac2010-03-22 14:22:26 +00008300 }
8301
8302 MYDB_BEGIN_ALLOW_THREADS;
8303 err = self->txn->set_timeout(self->txn, (db_timeout_t)timeout, flags);
8304 MYDB_END_ALLOW_THREADS;
8305
8306 RETURN_IF_ERR();
8307 RETURN_NONE();
8308}
8309
8310
8311#if (DBVER >= 44)
8312static PyObject*
8313DBTxn_set_name(DBTxnObject* self, PyObject* args)
8314{
8315 int err;
8316 const char *name;
8317
8318 if (!PyArg_ParseTuple(args, "s:set_name", &name))
8319 return NULL;
8320
8321 MYDB_BEGIN_ALLOW_THREADS;
8322 err = self->txn->set_name(self->txn, name);
8323 MYDB_END_ALLOW_THREADS;
8324
8325 RETURN_IF_ERR();
8326 RETURN_NONE();
8327}
8328#endif
8329
8330
8331#if (DBVER >= 44)
8332static PyObject*
8333DBTxn_get_name(DBTxnObject* self)
8334{
8335 int err;
8336 const char *name;
8337
8338 MYDB_BEGIN_ALLOW_THREADS;
8339 err = self->txn->get_name(self->txn, &name);
8340 MYDB_END_ALLOW_THREADS;
8341
8342 RETURN_IF_ERR();
8343#if (PY_VERSION_HEX < 0x03000000)
8344 if (!name) {
8345 return PyString_FromString("");
8346 }
8347 return PyString_FromString(name);
8348#else
8349 if (!name) {
8350 return PyUnicode_FromString("");
8351 }
8352 return PyUnicode_FromString(name);
8353#endif
8354}
8355#endif
8356
8357
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008358/* --------------------------------------------------------------------- */
8359/* DBSequence methods */
8360
8361
8362static PyObject*
Jesus Ceaef9764f2008-05-13 18:45:46 +00008363DBSequence_close_internal(DBSequenceObject* self, int flags, int do_not_close)
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008364{
Jesus Ceaef9764f2008-05-13 18:45:46 +00008365 int err=0;
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008366
Jesus Ceaef9764f2008-05-13 18:45:46 +00008367 if (self->sequence!=NULL) {
8368 EXTRACT_FROM_DOUBLE_LINKED_LIST(self);
8369 if (self->txn) {
8370 EXTRACT_FROM_DOUBLE_LINKED_LIST_TXN(self);
8371 self->txn=NULL;
8372 }
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008373
Jesus Cea5cd5f122008-09-23 18:54:08 +00008374 /*
8375 ** "do_not_close" is used to dispose all related objects in the
8376 ** tree, without actually releasing the "root" object.
8377 ** This is done, for example, because function calls like
8378 ** "DBSequence.remove()" implicitly close the underlying handle. So
8379 ** the handle doesn't need to be closed, but related objects
8380 ** must be cleaned up.
8381 */
Jesus Ceaef9764f2008-05-13 18:45:46 +00008382 if (!do_not_close) {
8383 MYDB_BEGIN_ALLOW_THREADS
8384 err = self->sequence->close(self->sequence, flags);
8385 MYDB_END_ALLOW_THREADS
8386 }
8387 self->sequence = NULL;
8388
8389 RETURN_IF_ERR();
8390 }
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008391
8392 RETURN_NONE();
8393}
8394
8395static PyObject*
Jesus Ceaef9764f2008-05-13 18:45:46 +00008396DBSequence_close(DBSequenceObject* self, PyObject* args)
8397{
8398 int flags=0;
8399 if (!PyArg_ParseTuple(args,"|i:close", &flags))
8400 return NULL;
8401
8402 return DBSequence_close_internal(self,flags,0);
8403}
8404
8405static PyObject*
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008406DBSequence_get(DBSequenceObject* self, PyObject* args, PyObject* kwargs)
8407{
8408 int err, flags = 0;
8409 int delta = 1;
8410 db_seq_t value;
8411 PyObject *txnobj = NULL;
8412 DB_TXN *txn = NULL;
8413 static char* kwnames[] = {"delta", "txn", "flags", NULL };
8414 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|iOi:get", kwnames, &delta, &txnobj, &flags))
8415 return NULL;
8416 CHECK_SEQUENCE_NOT_CLOSED(self)
8417
8418 if (!checkTxnObj(txnobj, &txn))
8419 return NULL;
8420
8421 MYDB_BEGIN_ALLOW_THREADS
8422 err = self->sequence->get(self->sequence, txn, delta, &value, flags);
8423 MYDB_END_ALLOW_THREADS
8424
8425 RETURN_IF_ERR();
8426 return PyLong_FromLongLong(value);
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008427}
8428
8429static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008430DBSequence_get_dbp(DBSequenceObject* self)
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008431{
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008432 CHECK_SEQUENCE_NOT_CLOSED(self)
8433 Py_INCREF(self->mydb);
8434 return (PyObject* )self->mydb;
8435}
8436
8437static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008438DBSequence_get_key(DBSequenceObject* self)
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008439{
8440 int err;
8441 DBT key;
Neal Norwitz088beae2007-10-12 03:01:54 +00008442 PyObject *retval = NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00008443
Gregory P. Smithe70be5c2007-10-06 07:48:10 +00008444 key.flags = DB_DBT_MALLOC;
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008445 CHECK_SEQUENCE_NOT_CLOSED(self)
8446 MYDB_BEGIN_ALLOW_THREADS
8447 err = self->sequence->get_key(self->sequence, &key);
8448 MYDB_END_ALLOW_THREADS
8449
Gregory P. Smithe70be5c2007-10-06 07:48:10 +00008450 if (!err)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008451 retval = Build_PyString(key.data, key.size);
Gregory P. Smithe70be5c2007-10-06 07:48:10 +00008452
8453 FREE_DBT(key);
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008454 RETURN_IF_ERR();
8455
Gregory P. Smithe70be5c2007-10-06 07:48:10 +00008456 return retval;
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008457}
8458
8459static PyObject*
Jesus Cea6557aac2010-03-22 14:22:26 +00008460DBSequence_initial_value(DBSequenceObject* self, PyObject* args)
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008461{
8462 int err;
Jesus Ceaef9764f2008-05-13 18:45:46 +00008463 PY_LONG_LONG value;
8464 db_seq_t value2;
Jesus Cea6557aac2010-03-22 14:22:26 +00008465 if (!PyArg_ParseTuple(args,"L:initial_value", &value))
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008466 return NULL;
8467 CHECK_SEQUENCE_NOT_CLOSED(self)
8468
Jesus Ceaef9764f2008-05-13 18:45:46 +00008469 value2=value; /* If truncation, compiler should show a warning */
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008470 MYDB_BEGIN_ALLOW_THREADS
Jesus Ceaef9764f2008-05-13 18:45:46 +00008471 err = self->sequence->initial_value(self->sequence, value2);
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008472 MYDB_END_ALLOW_THREADS
8473
8474 RETURN_IF_ERR();
8475
8476 RETURN_NONE();
8477}
8478
8479static PyObject*
8480DBSequence_open(DBSequenceObject* self, PyObject* args, PyObject* kwargs)
8481{
8482 int err, flags = 0;
8483 PyObject* keyobj;
8484 PyObject *txnobj = NULL;
8485 DB_TXN *txn = NULL;
8486 DBT key;
8487
8488 static char* kwnames[] = {"key", "txn", "flags", NULL };
Neal Norwitzdd2a6bf2006-06-06 07:23:01 +00008489 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|Oi:open", kwnames, &keyobj, &txnobj, &flags))
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008490 return NULL;
8491
8492 if (!checkTxnObj(txnobj, &txn))
8493 return NULL;
8494
8495 if (!make_key_dbt(self->mydb, keyobj, &key, NULL))
8496 return NULL;
8497
8498 MYDB_BEGIN_ALLOW_THREADS
8499 err = self->sequence->open(self->sequence, txn, &key, flags);
8500 MYDB_END_ALLOW_THREADS
8501
Jesus Ceaac25fab2008-09-03 17:50:32 +00008502 FREE_DBT(key);
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008503 RETURN_IF_ERR();
8504
Jesus Ceaef9764f2008-05-13 18:45:46 +00008505 if (txn) {
8506 INSERT_IN_DOUBLE_LINKED_LIST_TXN(((DBTxnObject *)txnobj)->children_sequences,self);
8507 self->txn=(DBTxnObject *)txnobj;
8508 }
8509
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008510 RETURN_NONE();
8511}
8512
8513static PyObject*
8514DBSequence_remove(DBSequenceObject* self, PyObject* args, PyObject* kwargs)
8515{
Jesus Ceaef9764f2008-05-13 18:45:46 +00008516 PyObject *dummy;
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008517 int err, flags = 0;
8518 PyObject *txnobj = NULL;
8519 DB_TXN *txn = NULL;
8520
8521 static char* kwnames[] = {"txn", "flags", NULL };
Neal Norwitzdd2a6bf2006-06-06 07:23:01 +00008522 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Oi:remove", kwnames, &txnobj, &flags))
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008523 return NULL;
8524
8525 if (!checkTxnObj(txnobj, &txn))
8526 return NULL;
8527
8528 CHECK_SEQUENCE_NOT_CLOSED(self)
8529
8530 MYDB_BEGIN_ALLOW_THREADS
8531 err = self->sequence->remove(self->sequence, txn, flags);
8532 MYDB_END_ALLOW_THREADS
8533
Jesus Ceaef9764f2008-05-13 18:45:46 +00008534 dummy=DBSequence_close_internal(self,flags,1);
8535 Py_XDECREF(dummy);
8536
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008537 RETURN_IF_ERR();
8538 RETURN_NONE();
8539}
8540
8541static PyObject*
8542DBSequence_set_cachesize(DBSequenceObject* self, PyObject* args)
8543{
8544 int err, size;
Neal Norwitzdd2a6bf2006-06-06 07:23:01 +00008545 if (!PyArg_ParseTuple(args,"i:set_cachesize", &size))
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008546 return NULL;
8547 CHECK_SEQUENCE_NOT_CLOSED(self)
8548
8549 MYDB_BEGIN_ALLOW_THREADS
8550 err = self->sequence->set_cachesize(self->sequence, size);
8551 MYDB_END_ALLOW_THREADS
8552
8553 RETURN_IF_ERR();
8554 RETURN_NONE();
8555}
8556
8557static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008558DBSequence_get_cachesize(DBSequenceObject* self)
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008559{
8560 int err, size;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008561
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008562 CHECK_SEQUENCE_NOT_CLOSED(self)
8563
8564 MYDB_BEGIN_ALLOW_THREADS
8565 err = self->sequence->get_cachesize(self->sequence, &size);
8566 MYDB_END_ALLOW_THREADS
8567
8568 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008569 return NUMBER_FromLong(size);
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008570}
8571
8572static PyObject*
8573DBSequence_set_flags(DBSequenceObject* self, PyObject* args)
8574{
8575 int err, flags = 0;
Neal Norwitzdd2a6bf2006-06-06 07:23:01 +00008576 if (!PyArg_ParseTuple(args,"i:set_flags", &flags))
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008577 return NULL;
8578 CHECK_SEQUENCE_NOT_CLOSED(self)
8579
8580 MYDB_BEGIN_ALLOW_THREADS
8581 err = self->sequence->set_flags(self->sequence, flags);
8582 MYDB_END_ALLOW_THREADS
8583
8584 RETURN_IF_ERR();
8585 RETURN_NONE();
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008586}
8587
8588static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008589DBSequence_get_flags(DBSequenceObject* self)
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008590{
8591 unsigned int flags;
8592 int err;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008593
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008594 CHECK_SEQUENCE_NOT_CLOSED(self)
8595
8596 MYDB_BEGIN_ALLOW_THREADS
8597 err = self->sequence->get_flags(self->sequence, &flags);
8598 MYDB_END_ALLOW_THREADS
8599
8600 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008601 return NUMBER_FromLong((int)flags);
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008602}
8603
8604static PyObject*
8605DBSequence_set_range(DBSequenceObject* self, PyObject* args)
8606{
8607 int err;
Jesus Ceaef9764f2008-05-13 18:45:46 +00008608 PY_LONG_LONG min, max;
8609 db_seq_t min2, max2;
Tim Petersbb21b2c2006-06-06 15:50:17 +00008610 if (!PyArg_ParseTuple(args,"(LL):set_range", &min, &max))
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008611 return NULL;
8612 CHECK_SEQUENCE_NOT_CLOSED(self)
8613
Jesus Ceaef9764f2008-05-13 18:45:46 +00008614 min2=min; /* If truncation, compiler should show a warning */
8615 max2=max;
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008616 MYDB_BEGIN_ALLOW_THREADS
Jesus Ceaef9764f2008-05-13 18:45:46 +00008617 err = self->sequence->set_range(self->sequence, min2, max2);
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008618 MYDB_END_ALLOW_THREADS
8619
8620 RETURN_IF_ERR();
8621 RETURN_NONE();
8622}
8623
8624static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008625DBSequence_get_range(DBSequenceObject* self)
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008626{
8627 int err;
Jesus Ceaef9764f2008-05-13 18:45:46 +00008628 PY_LONG_LONG min, max;
8629 db_seq_t min2, max2;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008630
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008631 CHECK_SEQUENCE_NOT_CLOSED(self)
8632
8633 MYDB_BEGIN_ALLOW_THREADS
Jesus Ceaef9764f2008-05-13 18:45:46 +00008634 err = self->sequence->get_range(self->sequence, &min2, &max2);
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008635 MYDB_END_ALLOW_THREADS
8636
8637 RETURN_IF_ERR();
Jesus Ceaef9764f2008-05-13 18:45:46 +00008638 min=min2; /* If truncation, compiler should show a warning */
8639 max=max2;
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008640 return Py_BuildValue("(LL)", min, max);
8641}
8642
Jesus Cea6557aac2010-03-22 14:22:26 +00008643
8644static PyObject*
8645DBSequence_stat_print(DBSequenceObject* self, PyObject* args, PyObject *kwargs)
8646{
8647 int err;
8648 int flags=0;
8649 static char* kwnames[] = { "flags", NULL };
8650
8651 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:stat_print",
8652 kwnames, &flags))
8653 {
8654 return NULL;
8655 }
8656
8657 CHECK_SEQUENCE_NOT_CLOSED(self);
8658
8659 MYDB_BEGIN_ALLOW_THREADS;
8660 err = self->sequence->stat_print(self->sequence, flags);
8661 MYDB_END_ALLOW_THREADS;
8662 RETURN_IF_ERR();
8663 RETURN_NONE();
8664}
8665
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008666static PyObject*
8667DBSequence_stat(DBSequenceObject* self, PyObject* args, PyObject* kwargs)
8668{
8669 int err, flags = 0;
8670 DB_SEQUENCE_STAT* sp = NULL;
8671 PyObject* dict_stat;
8672 static char* kwnames[] = {"flags", NULL };
8673 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:stat", kwnames, &flags))
8674 return NULL;
8675 CHECK_SEQUENCE_NOT_CLOSED(self);
8676
8677 MYDB_BEGIN_ALLOW_THREADS;
8678 err = self->sequence->stat(self->sequence, &sp, flags);
8679 MYDB_END_ALLOW_THREADS;
8680 RETURN_IF_ERR();
8681
8682 if ((dict_stat = PyDict_New()) == NULL) {
8683 free(sp);
8684 return NULL;
8685 }
8686
8687
8688#define MAKE_INT_ENTRY(name) _addIntToDict(dict_stat, #name, sp->st_##name)
8689#define MAKE_LONG_LONG_ENTRY(name) _addDb_seq_tToDict(dict_stat, #name, sp->st_##name)
8690
8691 MAKE_INT_ENTRY(wait);
8692 MAKE_INT_ENTRY(nowait);
8693 MAKE_LONG_LONG_ENTRY(current);
8694 MAKE_LONG_LONG_ENTRY(value);
8695 MAKE_LONG_LONG_ENTRY(last_value);
8696 MAKE_LONG_LONG_ENTRY(min);
8697 MAKE_LONG_LONG_ENTRY(max);
8698 MAKE_INT_ENTRY(cache_size);
8699 MAKE_INT_ENTRY(flags);
8700
8701#undef MAKE_INT_ENTRY
8702#undef MAKE_LONG_LONG_ENTRY
8703
8704 free(sp);
8705 return dict_stat;
8706}
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008707
8708
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008709/* --------------------------------------------------------------------- */
8710/* Method definition tables and type objects */
8711
8712static PyMethodDef DB_methods[] = {
Jesus Cea4907d272008-08-31 14:00:51 +00008713 {"append", (PyCFunction)DB_append, METH_VARARGS|METH_KEYWORDS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008714 {"associate", (PyCFunction)DB_associate, METH_VARARGS|METH_KEYWORDS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008715 {"close", (PyCFunction)DB_close, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008716#if (DBVER >= 47)
8717 {"compact", (PyCFunction)DB_compact, METH_VARARGS|METH_KEYWORDS},
8718#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008719 {"consume", (PyCFunction)DB_consume, METH_VARARGS|METH_KEYWORDS},
8720 {"consume_wait", (PyCFunction)DB_consume_wait, METH_VARARGS|METH_KEYWORDS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008721 {"cursor", (PyCFunction)DB_cursor, METH_VARARGS|METH_KEYWORDS},
8722 {"delete", (PyCFunction)DB_delete, METH_VARARGS|METH_KEYWORDS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008723 {"fd", (PyCFunction)DB_fd, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008724#if (DBVER >= 46)
8725 {"exists", (PyCFunction)DB_exists,
8726 METH_VARARGS|METH_KEYWORDS},
8727#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008728 {"get", (PyCFunction)DB_get, METH_VARARGS|METH_KEYWORDS},
Gregory P. Smith19699a92004-06-28 04:06:49 +00008729 {"pget", (PyCFunction)DB_pget, METH_VARARGS|METH_KEYWORDS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008730 {"get_both", (PyCFunction)DB_get_both, METH_VARARGS|METH_KEYWORDS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008731 {"get_byteswapped", (PyCFunction)DB_get_byteswapped,METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008732 {"get_size", (PyCFunction)DB_get_size, METH_VARARGS|METH_KEYWORDS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008733 {"get_type", (PyCFunction)DB_get_type, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008734 {"join", (PyCFunction)DB_join, METH_VARARGS},
8735 {"key_range", (PyCFunction)DB_key_range, METH_VARARGS|METH_KEYWORDS},
Jesus Cea4907d272008-08-31 14:00:51 +00008736 {"has_key", (PyCFunction)DB_has_key, METH_VARARGS|METH_KEYWORDS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008737 {"items", (PyCFunction)DB_items, METH_VARARGS},
8738 {"keys", (PyCFunction)DB_keys, METH_VARARGS},
8739 {"open", (PyCFunction)DB_open, METH_VARARGS|METH_KEYWORDS},
8740 {"put", (PyCFunction)DB_put, METH_VARARGS|METH_KEYWORDS},
8741 {"remove", (PyCFunction)DB_remove, METH_VARARGS|METH_KEYWORDS},
8742 {"rename", (PyCFunction)DB_rename, METH_VARARGS},
8743 {"set_bt_minkey", (PyCFunction)DB_set_bt_minkey, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008744 {"get_bt_minkey", (PyCFunction)DB_get_bt_minkey, METH_NOARGS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008745 {"set_bt_compare", (PyCFunction)DB_set_bt_compare, METH_O},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008746 {"set_cachesize", (PyCFunction)DB_set_cachesize, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008747 {"get_cachesize", (PyCFunction)DB_get_cachesize, METH_NOARGS},
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07008748 {"set_dup_compare", (PyCFunction)DB_set_dup_compare, METH_O},
Jesus Cea6557aac2010-03-22 14:22:26 +00008749 {"set_encrypt", (PyCFunction)DB_set_encrypt, METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008750 {"get_encrypt_flags", (PyCFunction)DB_get_encrypt_flags, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008751 {"set_flags", (PyCFunction)DB_set_flags, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008752 {"get_flags", (PyCFunction)DB_get_flags, METH_NOARGS},
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07008753 {"get_transactional", (PyCFunction)DB_get_transactional, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008754 {"set_h_ffactor", (PyCFunction)DB_set_h_ffactor, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008755 {"get_h_ffactor", (PyCFunction)DB_get_h_ffactor, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008756 {"set_h_nelem", (PyCFunction)DB_set_h_nelem, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008757 {"get_h_nelem", (PyCFunction)DB_get_h_nelem, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008758 {"set_lorder", (PyCFunction)DB_set_lorder, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008759 {"get_lorder", (PyCFunction)DB_get_lorder, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008760 {"set_pagesize", (PyCFunction)DB_set_pagesize, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008761 {"get_pagesize", (PyCFunction)DB_get_pagesize, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008762 {"set_re_delim", (PyCFunction)DB_set_re_delim, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008763 {"get_re_delim", (PyCFunction)DB_get_re_delim, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008764 {"set_re_len", (PyCFunction)DB_set_re_len, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008765 {"get_re_len", (PyCFunction)DB_get_re_len, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008766 {"set_re_pad", (PyCFunction)DB_set_re_pad, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008767 {"get_re_pad", (PyCFunction)DB_get_re_pad, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008768 {"set_re_source", (PyCFunction)DB_set_re_source, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008769 {"get_re_source", (PyCFunction)DB_get_re_source, METH_NOARGS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008770 {"set_q_extentsize",(PyCFunction)DB_set_q_extentsize, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008771 {"get_q_extentsize",(PyCFunction)DB_get_q_extentsize, METH_NOARGS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008772 {"set_private", (PyCFunction)DB_set_private, METH_O},
8773 {"get_private", (PyCFunction)DB_get_private, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008774#if (DBVER >= 46)
8775 {"set_priority", (PyCFunction)DB_set_priority, METH_VARARGS},
8776 {"get_priority", (PyCFunction)DB_get_priority, METH_NOARGS},
8777#endif
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07008778 {"get_dbname", (PyCFunction)DB_get_dbname, METH_NOARGS},
8779 {"get_open_flags", (PyCFunction)DB_get_open_flags, METH_NOARGS},
Gregory P. Smith8b7e9172004-12-13 09:51:23 +00008780 {"stat", (PyCFunction)DB_stat, METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008781 {"stat_print", (PyCFunction)DB_stat_print,
8782 METH_VARARGS|METH_KEYWORDS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008783 {"sync", (PyCFunction)DB_sync, METH_VARARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008784 {"truncate", (PyCFunction)DB_truncate, METH_VARARGS|METH_KEYWORDS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008785 {"type", (PyCFunction)DB_get_type, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008786 {"upgrade", (PyCFunction)DB_upgrade, METH_VARARGS},
8787 {"values", (PyCFunction)DB_values, METH_VARARGS},
8788 {"verify", (PyCFunction)DB_verify, METH_VARARGS|METH_KEYWORDS},
8789 {"set_get_returns_none",(PyCFunction)DB_set_get_returns_none, METH_VARARGS},
8790 {NULL, NULL} /* sentinel */
8791};
8792
8793
Jesus Cea6557aac2010-03-22 14:22:26 +00008794/* We need this to support __contains__() */
8795static PySequenceMethods DB_sequence = {
8796 0, /* sq_length, mapping wins here */
8797 0, /* sq_concat */
8798 0, /* sq_repeat */
8799 0, /* sq_item */
8800 0, /* sq_slice */
8801 0, /* sq_ass_item */
8802 0, /* sq_ass_slice */
8803 (objobjproc)DB_contains, /* sq_contains */
8804 0, /* sq_inplace_concat */
8805 0, /* sq_inplace_repeat */
8806};
8807
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008808static PyMappingMethods DB_mapping = {
Martin v. Löwis70ee3cc2006-06-12 04:26:31 +00008809 DB_length, /*mp_length*/
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008810 (binaryfunc)DB_subscript, /*mp_subscript*/
8811 (objobjargproc)DB_ass_sub, /*mp_ass_subscript*/
8812};
8813
8814
8815static PyMethodDef DBCursor_methods[] = {
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008816 {"close", (PyCFunction)DBC_close, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008817 {"count", (PyCFunction)DBC_count, METH_VARARGS},
8818 {"current", (PyCFunction)DBC_current, METH_VARARGS|METH_KEYWORDS},
8819 {"delete", (PyCFunction)DBC_delete, METH_VARARGS},
8820 {"dup", (PyCFunction)DBC_dup, METH_VARARGS},
8821 {"first", (PyCFunction)DBC_first, METH_VARARGS|METH_KEYWORDS},
8822 {"get", (PyCFunction)DBC_get, METH_VARARGS|METH_KEYWORDS},
Gregory P. Smith19699a92004-06-28 04:06:49 +00008823 {"pget", (PyCFunction)DBC_pget, METH_VARARGS|METH_KEYWORDS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008824 {"get_recno", (PyCFunction)DBC_get_recno, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008825 {"last", (PyCFunction)DBC_last, METH_VARARGS|METH_KEYWORDS},
8826 {"next", (PyCFunction)DBC_next, METH_VARARGS|METH_KEYWORDS},
8827 {"prev", (PyCFunction)DBC_prev, METH_VARARGS|METH_KEYWORDS},
8828 {"put", (PyCFunction)DBC_put, METH_VARARGS|METH_KEYWORDS},
8829 {"set", (PyCFunction)DBC_set, METH_VARARGS|METH_KEYWORDS},
8830 {"set_range", (PyCFunction)DBC_set_range, METH_VARARGS|METH_KEYWORDS},
8831 {"get_both", (PyCFunction)DBC_get_both, METH_VARARGS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008832 {"get_current_size",(PyCFunction)DBC_get_current_size, METH_NOARGS},
Gregory P. Smith455d46f2003-07-09 04:45:59 +00008833 {"set_both", (PyCFunction)DBC_set_both, METH_VARARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008834 {"set_recno", (PyCFunction)DBC_set_recno, METH_VARARGS|METH_KEYWORDS},
8835 {"consume", (PyCFunction)DBC_consume, METH_VARARGS|METH_KEYWORDS},
8836 {"next_dup", (PyCFunction)DBC_next_dup, METH_VARARGS|METH_KEYWORDS},
8837 {"next_nodup", (PyCFunction)DBC_next_nodup, METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008838#if (DBVER >= 46)
8839 {"prev_dup", (PyCFunction)DBC_prev_dup,
8840 METH_VARARGS|METH_KEYWORDS},
8841#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008842 {"prev_nodup", (PyCFunction)DBC_prev_nodup, METH_VARARGS|METH_KEYWORDS},
8843 {"join_item", (PyCFunction)DBC_join_item, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008844#if (DBVER >= 46)
8845 {"set_priority", (PyCFunction)DBC_set_priority,
8846 METH_VARARGS|METH_KEYWORDS},
8847 {"get_priority", (PyCFunction)DBC_get_priority, METH_NOARGS},
8848#endif
8849 {NULL, NULL} /* sentinel */
8850};
8851
8852
8853static PyMethodDef DBLogCursor_methods[] = {
8854 {"close", (PyCFunction)DBLogCursor_close, METH_NOARGS},
8855 {"current", (PyCFunction)DBLogCursor_current, METH_NOARGS},
8856 {"first", (PyCFunction)DBLogCursor_first, METH_NOARGS},
8857 {"last", (PyCFunction)DBLogCursor_last, METH_NOARGS},
8858 {"next", (PyCFunction)DBLogCursor_next, METH_NOARGS},
8859 {"prev", (PyCFunction)DBLogCursor_prev, METH_NOARGS},
8860 {"set", (PyCFunction)DBLogCursor_set, METH_VARARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008861 {NULL, NULL} /* sentinel */
8862};
8863
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07008864#if (DBVER >= 52)
8865static PyMethodDef DBSite_methods[] = {
8866 {"get_config", (PyCFunction)DBSite_get_config,
8867 METH_VARARGS | METH_KEYWORDS},
8868 {"set_config", (PyCFunction)DBSite_set_config,
8869 METH_VARARGS | METH_KEYWORDS},
8870 {"remove", (PyCFunction)DBSite_remove, METH_NOARGS},
8871 {"get_eid", (PyCFunction)DBSite_get_eid, METH_NOARGS},
8872 {"get_address", (PyCFunction)DBSite_get_address, METH_NOARGS},
8873 {"close", (PyCFunction)DBSite_close, METH_NOARGS},
8874 {NULL, NULL} /* sentinel */
8875};
8876#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008877
8878static PyMethodDef DBEnv_methods[] = {
8879 {"close", (PyCFunction)DBEnv_close, METH_VARARGS},
8880 {"open", (PyCFunction)DBEnv_open, METH_VARARGS},
8881 {"remove", (PyCFunction)DBEnv_remove, METH_VARARGS},
Barry Warsaw9a0d7792002-12-30 20:53:52 +00008882 {"dbremove", (PyCFunction)DBEnv_dbremove, METH_VARARGS|METH_KEYWORDS},
8883 {"dbrename", (PyCFunction)DBEnv_dbrename, METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008884#if (DBVER >= 46)
8885 {"set_thread_count", (PyCFunction)DBEnv_set_thread_count, METH_VARARGS},
8886 {"get_thread_count", (PyCFunction)DBEnv_get_thread_count, METH_NOARGS},
8887#endif
Barry Warsaw9a0d7792002-12-30 20:53:52 +00008888 {"set_encrypt", (PyCFunction)DBEnv_set_encrypt, METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008889 {"get_encrypt_flags", (PyCFunction)DBEnv_get_encrypt_flags, METH_NOARGS},
8890 {"get_timeout", (PyCFunction)DBEnv_get_timeout,
8891 METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008892 {"set_timeout", (PyCFunction)DBEnv_set_timeout, METH_VARARGS|METH_KEYWORDS},
8893 {"set_shm_key", (PyCFunction)DBEnv_set_shm_key, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008894 {"get_shm_key", (PyCFunction)DBEnv_get_shm_key, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008895#if (DBVER >= 46)
8896 {"set_cache_max", (PyCFunction)DBEnv_set_cache_max, METH_VARARGS},
8897 {"get_cache_max", (PyCFunction)DBEnv_get_cache_max, METH_NOARGS},
8898#endif
8899 {"set_cachesize", (PyCFunction)DBEnv_set_cachesize, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008900 {"get_cachesize", (PyCFunction)DBEnv_get_cachesize, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008901 {"memp_trickle", (PyCFunction)DBEnv_memp_trickle, METH_VARARGS},
8902 {"memp_sync", (PyCFunction)DBEnv_memp_sync, METH_VARARGS},
8903 {"memp_stat", (PyCFunction)DBEnv_memp_stat,
8904 METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008905 {"memp_stat_print", (PyCFunction)DBEnv_memp_stat_print,
8906 METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008907#if (DBVER >= 44)
8908 {"mutex_set_max", (PyCFunction)DBEnv_mutex_set_max, METH_VARARGS},
8909 {"mutex_get_max", (PyCFunction)DBEnv_mutex_get_max, METH_NOARGS},
8910 {"mutex_set_align", (PyCFunction)DBEnv_mutex_set_align, METH_VARARGS},
8911 {"mutex_get_align", (PyCFunction)DBEnv_mutex_get_align, METH_NOARGS},
8912 {"mutex_set_increment", (PyCFunction)DBEnv_mutex_set_increment,
8913 METH_VARARGS},
8914 {"mutex_get_increment", (PyCFunction)DBEnv_mutex_get_increment,
8915 METH_NOARGS},
8916 {"mutex_set_tas_spins", (PyCFunction)DBEnv_mutex_set_tas_spins,
8917 METH_VARARGS},
8918 {"mutex_get_tas_spins", (PyCFunction)DBEnv_mutex_get_tas_spins,
8919 METH_NOARGS},
8920 {"mutex_stat", (PyCFunction)DBEnv_mutex_stat, METH_VARARGS},
8921#if (DBVER >= 44)
8922 {"mutex_stat_print", (PyCFunction)DBEnv_mutex_stat_print,
8923 METH_VARARGS|METH_KEYWORDS},
8924#endif
8925#endif
8926 {"set_data_dir", (PyCFunction)DBEnv_set_data_dir, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008927 {"get_data_dirs", (PyCFunction)DBEnv_get_data_dirs, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008928 {"get_flags", (PyCFunction)DBEnv_get_flags, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008929 {"set_flags", (PyCFunction)DBEnv_set_flags, METH_VARARGS},
8930#if (DBVER >= 47)
8931 {"log_set_config", (PyCFunction)DBEnv_log_set_config, METH_VARARGS},
8932 {"log_get_config", (PyCFunction)DBEnv_log_get_config, METH_VARARGS},
8933#endif
8934 {"set_lg_bsize", (PyCFunction)DBEnv_set_lg_bsize, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008935 {"get_lg_bsize", (PyCFunction)DBEnv_get_lg_bsize, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008936 {"set_lg_dir", (PyCFunction)DBEnv_set_lg_dir, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008937 {"get_lg_dir", (PyCFunction)DBEnv_get_lg_dir, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008938 {"set_lg_max", (PyCFunction)DBEnv_set_lg_max, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008939 {"get_lg_max", (PyCFunction)DBEnv_get_lg_max, METH_NOARGS},
Gregory P. Smithe9477062005-06-04 06:46:59 +00008940 {"set_lg_regionmax",(PyCFunction)DBEnv_set_lg_regionmax, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008941 {"get_lg_regionmax",(PyCFunction)DBEnv_get_lg_regionmax, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008942#if (DBVER >= 44)
8943 {"set_lg_filemode", (PyCFunction)DBEnv_set_lg_filemode, METH_VARARGS},
8944 {"get_lg_filemode", (PyCFunction)DBEnv_get_lg_filemode, METH_NOARGS},
8945#endif
8946#if (DBVER >= 47)
8947 {"set_lk_partitions", (PyCFunction)DBEnv_set_lk_partitions, METH_VARARGS},
8948 {"get_lk_partitions", (PyCFunction)DBEnv_get_lk_partitions, METH_NOARGS},
8949#endif
8950 {"set_lk_detect", (PyCFunction)DBEnv_set_lk_detect, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008951 {"get_lk_detect", (PyCFunction)DBEnv_get_lk_detect, METH_NOARGS},
Gregory P. Smith8b96a352007-01-05 01:59:42 +00008952#if (DBVER < 45)
Jesus Cea6557aac2010-03-22 14:22:26 +00008953 {"set_lk_max", (PyCFunction)DBEnv_set_lk_max, METH_VARARGS},
Gregory P. Smith8b96a352007-01-05 01:59:42 +00008954#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008955 {"set_lk_max_locks", (PyCFunction)DBEnv_set_lk_max_locks, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008956 {"get_lk_max_locks", (PyCFunction)DBEnv_get_lk_max_locks, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008957 {"set_lk_max_lockers", (PyCFunction)DBEnv_set_lk_max_lockers, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008958 {"get_lk_max_lockers", (PyCFunction)DBEnv_get_lk_max_lockers, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008959 {"set_lk_max_objects", (PyCFunction)DBEnv_set_lk_max_objects, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008960 {"get_lk_max_objects", (PyCFunction)DBEnv_get_lk_max_objects, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008961 {"stat_print", (PyCFunction)DBEnv_stat_print,
8962 METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008963 {"set_mp_mmapsize", (PyCFunction)DBEnv_set_mp_mmapsize, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008964 {"get_mp_mmapsize", (PyCFunction)DBEnv_get_mp_mmapsize, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008965 {"set_tmp_dir", (PyCFunction)DBEnv_set_tmp_dir, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008966 {"get_tmp_dir", (PyCFunction)DBEnv_get_tmp_dir, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008967 {"txn_begin", (PyCFunction)DBEnv_txn_begin, METH_VARARGS|METH_KEYWORDS},
8968 {"txn_checkpoint", (PyCFunction)DBEnv_txn_checkpoint, METH_VARARGS},
8969 {"txn_stat", (PyCFunction)DBEnv_txn_stat, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008970 {"txn_stat_print", (PyCFunction)DBEnv_txn_stat_print,
8971 METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008972 {"get_tx_max", (PyCFunction)DBEnv_get_tx_max, METH_NOARGS},
8973 {"get_tx_timestamp", (PyCFunction)DBEnv_get_tx_timestamp, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008974 {"set_tx_max", (PyCFunction)DBEnv_set_tx_max, METH_VARARGS},
Gregory P. Smith8a474042006-01-27 07:05:40 +00008975 {"set_tx_timestamp", (PyCFunction)DBEnv_set_tx_timestamp, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008976 {"lock_detect", (PyCFunction)DBEnv_lock_detect, METH_VARARGS},
8977 {"lock_get", (PyCFunction)DBEnv_lock_get, METH_VARARGS},
8978 {"lock_id", (PyCFunction)DBEnv_lock_id, METH_NOARGS},
8979 {"lock_id_free", (PyCFunction)DBEnv_lock_id_free, METH_VARARGS},
8980 {"lock_put", (PyCFunction)DBEnv_lock_put, METH_VARARGS},
8981 {"lock_stat", (PyCFunction)DBEnv_lock_stat, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008982 {"lock_stat_print", (PyCFunction)DBEnv_lock_stat_print,
8983 METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008984 {"log_cursor", (PyCFunction)DBEnv_log_cursor, METH_NOARGS},
8985 {"log_file", (PyCFunction)DBEnv_log_file, METH_VARARGS},
Gregory P. Smithdb8a8072006-06-05 01:56:15 +00008986#if (DBVER >= 44)
Jesus Cea6557aac2010-03-22 14:22:26 +00008987 {"log_printf", (PyCFunction)DBEnv_log_printf,
8988 METH_VARARGS|METH_KEYWORDS},
8989#endif
8990 {"log_archive", (PyCFunction)DBEnv_log_archive, METH_VARARGS},
8991 {"log_flush", (PyCFunction)DBEnv_log_flush, METH_NOARGS},
8992 {"log_stat", (PyCFunction)DBEnv_log_stat, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008993 {"log_stat_print", (PyCFunction)DBEnv_log_stat_print,
8994 METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008995#if (DBVER >= 44)
8996 {"fileid_reset", (PyCFunction)DBEnv_fileid_reset, METH_VARARGS|METH_KEYWORDS},
8997 {"lsn_reset", (PyCFunction)DBEnv_lsn_reset, METH_VARARGS|METH_KEYWORDS},
Gregory P. Smithdb8a8072006-06-05 01:56:15 +00008998#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008999 {"set_get_returns_none",(PyCFunction)DBEnv_set_get_returns_none, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00009000 {"txn_recover", (PyCFunction)DBEnv_txn_recover, METH_NOARGS},
Matthias Klose54cc5392010-03-15 12:46:18 +00009001#if (DBVER < 48)
Jesus Ceaca3939c2008-05-22 15:27:38 +00009002 {"set_rpc_server", (PyCFunction)DBEnv_set_rpc_server,
Stefan Krah77112732011-09-15 22:56:00 +02009003 METH_VARARGS|METH_KEYWORDS},
Matthias Klose54cc5392010-03-15 12:46:18 +00009004#endif
Jesus Cea6557aac2010-03-22 14:22:26 +00009005 {"set_mp_max_openfd", (PyCFunction)DBEnv_set_mp_max_openfd, METH_VARARGS},
9006 {"get_mp_max_openfd", (PyCFunction)DBEnv_get_mp_max_openfd, METH_NOARGS},
9007 {"set_mp_max_write", (PyCFunction)DBEnv_set_mp_max_write, METH_VARARGS},
9008 {"get_mp_max_write", (PyCFunction)DBEnv_get_mp_max_write, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00009009 {"set_verbose", (PyCFunction)DBEnv_set_verbose, METH_VARARGS},
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009010 {"get_verbose", (PyCFunction)DBEnv_get_verbose, METH_VARARGS},
9011 {"set_private", (PyCFunction)DBEnv_set_private, METH_O},
9012 {"get_private", (PyCFunction)DBEnv_get_private, METH_NOARGS},
9013 {"get_open_flags", (PyCFunction)DBEnv_get_open_flags, METH_NOARGS},
9014#if (DBVER >= 47)
9015 {"set_intermediate_dir_mode", (PyCFunction)DBEnv_set_intermediate_dir_mode,
9016 METH_VARARGS},
9017 {"get_intermediate_dir_mode", (PyCFunction)DBEnv_get_intermediate_dir_mode,
9018 METH_NOARGS},
Jesus Ceaef9764f2008-05-13 18:45:46 +00009019#endif
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009020#if (DBVER < 47)
9021 {"set_intermediate_dir", (PyCFunction)DBEnv_set_intermediate_dir,
9022 METH_VARARGS},
9023#endif
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009024 {"rep_start", (PyCFunction)DBEnv_rep_start,
9025 METH_VARARGS|METH_KEYWORDS},
9026 {"rep_set_transport", (PyCFunction)DBEnv_rep_set_transport, METH_VARARGS},
9027 {"rep_process_message", (PyCFunction)DBEnv_rep_process_message,
9028 METH_VARARGS},
9029#if (DBVER >= 46)
9030 {"rep_elect", (PyCFunction)DBEnv_rep_elect, METH_VARARGS},
9031#endif
9032#if (DBVER >= 44)
9033 {"rep_set_config", (PyCFunction)DBEnv_rep_set_config, METH_VARARGS},
9034 {"rep_get_config", (PyCFunction)DBEnv_rep_get_config, METH_VARARGS},
9035 {"rep_sync", (PyCFunction)DBEnv_rep_sync, METH_NOARGS},
Jesus Ceaef9764f2008-05-13 18:45:46 +00009036#endif
9037#if (DBVER >= 45)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009038 {"rep_set_limit", (PyCFunction)DBEnv_rep_set_limit, METH_VARARGS},
9039 {"rep_get_limit", (PyCFunction)DBEnv_rep_get_limit, METH_NOARGS},
9040#endif
9041#if (DBVER >= 47)
9042 {"rep_set_request", (PyCFunction)DBEnv_rep_set_request, METH_VARARGS},
9043 {"rep_get_request", (PyCFunction)DBEnv_rep_get_request, METH_NOARGS},
9044#endif
9045#if (DBVER >= 45)
9046 {"set_event_notify", (PyCFunction)DBEnv_set_event_notify, METH_O},
Jesus Ceaef9764f2008-05-13 18:45:46 +00009047#endif
9048#if (DBVER >= 45)
9049 {"rep_set_nsites", (PyCFunction)DBEnv_rep_set_nsites, METH_VARARGS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009050 {"rep_get_nsites", (PyCFunction)DBEnv_rep_get_nsites, METH_NOARGS},
Jesus Ceaef9764f2008-05-13 18:45:46 +00009051 {"rep_set_priority", (PyCFunction)DBEnv_rep_set_priority, METH_VARARGS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009052 {"rep_get_priority", (PyCFunction)DBEnv_rep_get_priority, METH_NOARGS},
Jesus Ceaef9764f2008-05-13 18:45:46 +00009053 {"rep_set_timeout", (PyCFunction)DBEnv_rep_set_timeout, METH_VARARGS},
9054 {"rep_get_timeout", (PyCFunction)DBEnv_rep_get_timeout, METH_VARARGS},
9055#endif
Jesus Cea6557aac2010-03-22 14:22:26 +00009056#if (DBVER >= 47)
9057 {"rep_set_clockskew", (PyCFunction)DBEnv_rep_set_clockskew, METH_VARARGS},
9058 {"rep_get_clockskew", (PyCFunction)DBEnv_rep_get_clockskew, METH_VARARGS},
9059#endif
9060 {"rep_stat", (PyCFunction)DBEnv_rep_stat,
9061 METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00009062 {"rep_stat_print", (PyCFunction)DBEnv_rep_stat_print,
9063 METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00009064
Jesus Ceaef9764f2008-05-13 18:45:46 +00009065#if (DBVER >= 45)
9066 {"repmgr_start", (PyCFunction)DBEnv_repmgr_start,
9067 METH_VARARGS|METH_KEYWORDS},
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009068#if (DBVER < 52)
Jesus Ceaef9764f2008-05-13 18:45:46 +00009069 {"repmgr_set_local_site", (PyCFunction)DBEnv_repmgr_set_local_site,
9070 METH_VARARGS|METH_KEYWORDS},
9071 {"repmgr_add_remote_site", (PyCFunction)DBEnv_repmgr_add_remote_site,
9072 METH_VARARGS|METH_KEYWORDS},
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009073#endif
Jesus Ceaef9764f2008-05-13 18:45:46 +00009074 {"repmgr_set_ack_policy", (PyCFunction)DBEnv_repmgr_set_ack_policy,
9075 METH_VARARGS},
9076 {"repmgr_get_ack_policy", (PyCFunction)DBEnv_repmgr_get_ack_policy,
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009077 METH_NOARGS},
Jesus Ceaef9764f2008-05-13 18:45:46 +00009078 {"repmgr_site_list", (PyCFunction)DBEnv_repmgr_site_list,
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009079 METH_NOARGS},
Jesus Ceaef9764f2008-05-13 18:45:46 +00009080#endif
9081#if (DBVER >= 46)
9082 {"repmgr_stat", (PyCFunction)DBEnv_repmgr_stat,
9083 METH_VARARGS|METH_KEYWORDS},
9084 {"repmgr_stat_print", (PyCFunction)DBEnv_repmgr_stat_print,
9085 METH_VARARGS|METH_KEYWORDS},
9086#endif
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009087#if (DBVER >= 52)
9088 {"repmgr_site", (PyCFunction)DBEnv_repmgr_site,
9089 METH_VARARGS | METH_KEYWORDS},
9090 {"repmgr_site_by_eid", (PyCFunction)DBEnv_repmgr_site_by_eid,
9091 METH_VARARGS | METH_KEYWORDS},
9092#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009093 {NULL, NULL} /* sentinel */
9094};
9095
9096
9097static PyMethodDef DBTxn_methods[] = {
9098 {"commit", (PyCFunction)DBTxn_commit, METH_VARARGS},
9099 {"prepare", (PyCFunction)DBTxn_prepare, METH_VARARGS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009100 {"discard", (PyCFunction)DBTxn_discard, METH_NOARGS},
9101 {"abort", (PyCFunction)DBTxn_abort, METH_NOARGS},
9102 {"id", (PyCFunction)DBTxn_id, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00009103 {"set_timeout", (PyCFunction)DBTxn_set_timeout,
9104 METH_VARARGS|METH_KEYWORDS},
9105#if (DBVER >= 44)
9106 {"set_name", (PyCFunction)DBTxn_set_name, METH_VARARGS},
9107 {"get_name", (PyCFunction)DBTxn_get_name, METH_NOARGS},
9108#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009109 {NULL, NULL} /* sentinel */
9110};
9111
9112
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009113static PyMethodDef DBSequence_methods[] = {
9114 {"close", (PyCFunction)DBSequence_close, METH_VARARGS},
9115 {"get", (PyCFunction)DBSequence_get, METH_VARARGS|METH_KEYWORDS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009116 {"get_dbp", (PyCFunction)DBSequence_get_dbp, METH_NOARGS},
9117 {"get_key", (PyCFunction)DBSequence_get_key, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00009118 {"initial_value", (PyCFunction)DBSequence_initial_value, METH_VARARGS},
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009119 {"open", (PyCFunction)DBSequence_open, METH_VARARGS|METH_KEYWORDS},
9120 {"remove", (PyCFunction)DBSequence_remove, METH_VARARGS|METH_KEYWORDS},
9121 {"set_cachesize", (PyCFunction)DBSequence_set_cachesize, METH_VARARGS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009122 {"get_cachesize", (PyCFunction)DBSequence_get_cachesize, METH_NOARGS},
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009123 {"set_flags", (PyCFunction)DBSequence_set_flags, METH_VARARGS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009124 {"get_flags", (PyCFunction)DBSequence_get_flags, METH_NOARGS},
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009125 {"set_range", (PyCFunction)DBSequence_set_range, METH_VARARGS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009126 {"get_range", (PyCFunction)DBSequence_get_range, METH_NOARGS},
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009127 {"stat", (PyCFunction)DBSequence_stat, METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00009128 {"stat_print", (PyCFunction)DBSequence_stat_print,
9129 METH_VARARGS|METH_KEYWORDS},
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009130 {NULL, NULL} /* sentinel */
9131};
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009132
9133
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009134static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009135DBEnv_db_home_get(DBEnvObject* self)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009136{
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009137 const char *home = NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009138
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009139 CHECK_ENV_NOT_CLOSED(self);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009140
Jesus Cea6557aac2010-03-22 14:22:26 +00009141 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009142 self->db_env->get_home(self->db_env, &home);
Jesus Cea6557aac2010-03-22 14:22:26 +00009143 MYDB_END_ALLOW_THREADS;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009144
9145 if (home == NULL) {
9146 RETURN_NONE();
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009147 }
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009148 return PyBytes_FromString(home);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009149}
9150
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009151static PyGetSetDef DBEnv_getsets[] = {
9152 {"db_home", (getter)DBEnv_db_home_get, NULL,},
9153 {NULL}
9154};
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009155
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009156
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009157statichere PyTypeObject DB_Type = {
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009158#if (PY_VERSION_HEX < 0x03000000)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009159 PyObject_HEAD_INIT(NULL)
9160 0, /*ob_size*/
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009161#else
9162 PyVarObject_HEAD_INIT(NULL, 0)
9163#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009164 "DB", /*tp_name*/
9165 sizeof(DBObject), /*tp_basicsize*/
9166 0, /*tp_itemsize*/
9167 /* methods */
9168 (destructor)DB_dealloc, /*tp_dealloc*/
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009169 0, /*tp_print*/
9170 0, /*tp_getattr*/
9171 0, /*tp_setattr*/
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009172 0, /*tp_compare*/
9173 0, /*tp_repr*/
9174 0, /*tp_as_number*/
Jesus Cea6557aac2010-03-22 14:22:26 +00009175 &DB_sequence,/*tp_as_sequence*/
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009176 &DB_mapping,/*tp_as_mapping*/
9177 0, /*tp_hash*/
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009178 0, /* tp_call */
9179 0, /* tp_str */
9180 0, /* tp_getattro */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009181 0, /* tp_setattro */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009182 0, /* tp_as_buffer */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009183#if (PY_VERSION_HEX < 0x03000000)
Gregory P. Smith31c50652004-06-28 01:20:40 +00009184 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009185#else
9186 Py_TPFLAGS_DEFAULT, /* tp_flags */
9187#endif
9188 0, /* tp_doc */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009189 0, /* tp_traverse */
9190 0, /* tp_clear */
9191 0, /* tp_richcompare */
Gregory P. Smith31c50652004-06-28 01:20:40 +00009192 offsetof(DBObject, in_weakreflist), /* tp_weaklistoffset */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009193 0, /*tp_iter*/
9194 0, /*tp_iternext*/
9195 DB_methods, /*tp_methods*/
9196 0, /*tp_members*/
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009197};
9198
9199
9200statichere PyTypeObject DBCursor_Type = {
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009201#if (PY_VERSION_HEX < 0x03000000)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009202 PyObject_HEAD_INIT(NULL)
9203 0, /*ob_size*/
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009204#else
9205 PyVarObject_HEAD_INIT(NULL, 0)
9206#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009207 "DBCursor", /*tp_name*/
9208 sizeof(DBCursorObject), /*tp_basicsize*/
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009209 0, /*tp_itemsize*/
9210 /* methods */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009211 (destructor)DBCursor_dealloc,/*tp_dealloc*/
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009212 0, /*tp_print*/
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009213 0, /*tp_getattr*/
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009214 0, /*tp_setattr*/
9215 0, /*tp_compare*/
9216 0, /*tp_repr*/
9217 0, /*tp_as_number*/
9218 0, /*tp_as_sequence*/
9219 0, /*tp_as_mapping*/
9220 0, /*tp_hash*/
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009221 0, /*tp_call*/
9222 0, /*tp_str*/
9223 0, /*tp_getattro*/
9224 0, /*tp_setattro*/
9225 0, /*tp_as_buffer*/
9226#if (PY_VERSION_HEX < 0x03000000)
Gregory P. Smith31c50652004-06-28 01:20:40 +00009227 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009228#else
9229 Py_TPFLAGS_DEFAULT, /* tp_flags */
9230#endif
9231 0, /* tp_doc */
9232 0, /* tp_traverse */
9233 0, /* tp_clear */
9234 0, /* tp_richcompare */
9235 offsetof(DBCursorObject, in_weakreflist), /* tp_weaklistoffset */
9236 0, /*tp_iter*/
9237 0, /*tp_iternext*/
9238 DBCursor_methods, /*tp_methods*/
9239 0, /*tp_members*/
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009240};
9241
9242
Jesus Cea6557aac2010-03-22 14:22:26 +00009243statichere PyTypeObject DBLogCursor_Type = {
9244#if (PY_VERSION_HEX < 0x03000000)
9245 PyObject_HEAD_INIT(NULL)
9246 0, /*ob_size*/
9247#else
9248 PyVarObject_HEAD_INIT(NULL, 0)
9249#endif
9250 "DBLogCursor", /*tp_name*/
9251 sizeof(DBLogCursorObject), /*tp_basicsize*/
9252 0, /*tp_itemsize*/
9253 /* methods */
9254 (destructor)DBLogCursor_dealloc,/*tp_dealloc*/
9255 0, /*tp_print*/
9256 0, /*tp_getattr*/
9257 0, /*tp_setattr*/
9258 0, /*tp_compare*/
9259 0, /*tp_repr*/
9260 0, /*tp_as_number*/
9261 0, /*tp_as_sequence*/
9262 0, /*tp_as_mapping*/
9263 0, /*tp_hash*/
9264 0, /*tp_call*/
9265 0, /*tp_str*/
9266 0, /*tp_getattro*/
9267 0, /*tp_setattro*/
9268 0, /*tp_as_buffer*/
9269#if (PY_VERSION_HEX < 0x03000000)
9270 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
9271#else
9272 Py_TPFLAGS_DEFAULT, /* tp_flags */
9273#endif
9274 0, /* tp_doc */
9275 0, /* tp_traverse */
9276 0, /* tp_clear */
9277 0, /* tp_richcompare */
9278 offsetof(DBLogCursorObject, in_weakreflist), /* tp_weaklistoffset */
9279 0, /*tp_iter*/
9280 0, /*tp_iternext*/
9281 DBLogCursor_methods, /*tp_methods*/
9282 0, /*tp_members*/
9283};
9284
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009285#if (DBVER >= 52)
9286statichere PyTypeObject DBSite_Type = {
9287#if (PY_VERSION_HEX < 0x03000000)
9288 PyObject_HEAD_INIT(NULL)
9289 0, /*ob_size*/
9290#else
9291 PyVarObject_HEAD_INIT(NULL, 0)
9292#endif
9293 "DBSite", /*tp_name*/
9294 sizeof(DBSiteObject), /*tp_basicsize*/
9295 0, /*tp_itemsize*/
9296 /* methods */
9297 (destructor)DBSite_dealloc,/*tp_dealloc*/
9298 0, /*tp_print*/
9299 0, /*tp_getattr*/
9300 0, /*tp_setattr*/
9301 0, /*tp_compare*/
9302 0, /*tp_repr*/
9303 0, /*tp_as_number*/
9304 0, /*tp_as_sequence*/
9305 0, /*tp_as_mapping*/
9306 0, /*tp_hash*/
9307 0, /*tp_call*/
9308 0, /*tp_str*/
9309 0, /*tp_getattro*/
9310 0, /*tp_setattro*/
9311 0, /*tp_as_buffer*/
9312#if (PY_VERSION_HEX < 0x03000000)
9313 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
9314#else
9315 Py_TPFLAGS_DEFAULT, /* tp_flags */
9316#endif
9317 0, /* tp_doc */
9318 0, /* tp_traverse */
9319 0, /* tp_clear */
9320 0, /* tp_richcompare */
9321 offsetof(DBSiteObject, in_weakreflist), /* tp_weaklistoffset */
9322 0, /*tp_iter*/
9323 0, /*tp_iternext*/
9324 DBSite_methods, /*tp_methods*/
9325 0, /*tp_members*/
9326};
9327#endif
Jesus Cea6557aac2010-03-22 14:22:26 +00009328
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009329statichere PyTypeObject DBEnv_Type = {
9330#if (PY_VERSION_HEX < 0x03000000)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009331 PyObject_HEAD_INIT(NULL)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009332 0, /*ob_size*/
9333#else
9334 PyVarObject_HEAD_INIT(NULL, 0)
9335#endif
9336 "DBEnv", /*tp_name*/
9337 sizeof(DBEnvObject), /*tp_basicsize*/
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009338 0, /*tp_itemsize*/
9339 /* methods */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009340 (destructor)DBEnv_dealloc, /*tp_dealloc*/
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009341 0, /*tp_print*/
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009342 0, /*tp_getattr*/
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009343 0, /*tp_setattr*/
9344 0, /*tp_compare*/
9345 0, /*tp_repr*/
9346 0, /*tp_as_number*/
9347 0, /*tp_as_sequence*/
9348 0, /*tp_as_mapping*/
9349 0, /*tp_hash*/
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009350 0, /* tp_call */
9351 0, /* tp_str */
9352 0, /* tp_getattro */
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009353 0, /* tp_setattro */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009354 0, /* tp_as_buffer */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009355#if (PY_VERSION_HEX < 0x03000000)
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009356 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009357#else
9358 Py_TPFLAGS_DEFAULT, /* tp_flags */
9359#endif
9360 0, /* tp_doc */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009361 0, /* tp_traverse */
9362 0, /* tp_clear */
9363 0, /* tp_richcompare */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009364 offsetof(DBEnvObject, in_weakreflist), /* tp_weaklistoffset */
9365 0, /* tp_iter */
9366 0, /* tp_iternext */
9367 DBEnv_methods, /* tp_methods */
9368 0, /* tp_members */
9369 DBEnv_getsets, /* tp_getsets */
9370};
9371
9372statichere PyTypeObject DBTxn_Type = {
9373#if (PY_VERSION_HEX < 0x03000000)
9374 PyObject_HEAD_INIT(NULL)
9375 0, /*ob_size*/
9376#else
9377 PyVarObject_HEAD_INIT(NULL, 0)
9378#endif
9379 "DBTxn", /*tp_name*/
9380 sizeof(DBTxnObject), /*tp_basicsize*/
9381 0, /*tp_itemsize*/
9382 /* methods */
9383 (destructor)DBTxn_dealloc, /*tp_dealloc*/
9384 0, /*tp_print*/
9385 0, /*tp_getattr*/
9386 0, /*tp_setattr*/
9387 0, /*tp_compare*/
9388 0, /*tp_repr*/
9389 0, /*tp_as_number*/
9390 0, /*tp_as_sequence*/
9391 0, /*tp_as_mapping*/
9392 0, /*tp_hash*/
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009393 0, /* tp_call */
9394 0, /* tp_str */
9395 0, /* tp_getattro */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009396 0, /* tp_setattro */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009397 0, /* tp_as_buffer */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009398#if (PY_VERSION_HEX < 0x03000000)
9399 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
9400#else
9401 Py_TPFLAGS_DEFAULT, /* tp_flags */
9402#endif
9403 0, /* tp_doc */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009404 0, /* tp_traverse */
9405 0, /* tp_clear */
9406 0, /* tp_richcompare */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009407 offsetof(DBTxnObject, in_weakreflist), /* tp_weaklistoffset */
9408 0, /*tp_iter*/
9409 0, /*tp_iternext*/
9410 DBTxn_methods, /*tp_methods*/
9411 0, /*tp_members*/
9412};
9413
9414
9415statichere PyTypeObject DBLock_Type = {
9416#if (PY_VERSION_HEX < 0x03000000)
9417 PyObject_HEAD_INIT(NULL)
9418 0, /*ob_size*/
9419#else
9420 PyVarObject_HEAD_INIT(NULL, 0)
9421#endif
9422 "DBLock", /*tp_name*/
9423 sizeof(DBLockObject), /*tp_basicsize*/
9424 0, /*tp_itemsize*/
9425 /* methods */
9426 (destructor)DBLock_dealloc, /*tp_dealloc*/
9427 0, /*tp_print*/
9428 0, /*tp_getattr*/
9429 0, /*tp_setattr*/
9430 0, /*tp_compare*/
9431 0, /*tp_repr*/
9432 0, /*tp_as_number*/
9433 0, /*tp_as_sequence*/
9434 0, /*tp_as_mapping*/
9435 0, /*tp_hash*/
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009436 0, /* tp_call */
9437 0, /* tp_str */
9438 0, /* tp_getattro */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009439 0, /* tp_setattro */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009440 0, /* tp_as_buffer */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009441#if (PY_VERSION_HEX < 0x03000000)
9442 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
9443#else
9444 Py_TPFLAGS_DEFAULT, /* tp_flags */
9445#endif
9446 0, /* tp_doc */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009447 0, /* tp_traverse */
9448 0, /* tp_clear */
9449 0, /* tp_richcompare */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009450 offsetof(DBLockObject, in_weakreflist), /* tp_weaklistoffset */
9451};
9452
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009453statichere PyTypeObject DBSequence_Type = {
9454#if (PY_VERSION_HEX < 0x03000000)
9455 PyObject_HEAD_INIT(NULL)
9456 0, /*ob_size*/
9457#else
9458 PyVarObject_HEAD_INIT(NULL, 0)
9459#endif
9460 "DBSequence", /*tp_name*/
9461 sizeof(DBSequenceObject), /*tp_basicsize*/
9462 0, /*tp_itemsize*/
9463 /* methods */
9464 (destructor)DBSequence_dealloc, /*tp_dealloc*/
9465 0, /*tp_print*/
9466 0, /*tp_getattr*/
9467 0, /*tp_setattr*/
9468 0, /*tp_compare*/
9469 0, /*tp_repr*/
9470 0, /*tp_as_number*/
9471 0, /*tp_as_sequence*/
9472 0, /*tp_as_mapping*/
9473 0, /*tp_hash*/
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009474 0, /* tp_call */
9475 0, /* tp_str */
9476 0, /* tp_getattro */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009477 0, /* tp_setattro */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009478 0, /* tp_as_buffer */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009479#if (PY_VERSION_HEX < 0x03000000)
9480 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
9481#else
9482 Py_TPFLAGS_DEFAULT, /* tp_flags */
9483#endif
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009484 0, /* tp_doc */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009485 0, /* tp_traverse */
9486 0, /* tp_clear */
9487 0, /* tp_richcompare */
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009488 offsetof(DBSequenceObject, in_weakreflist), /* tp_weaklistoffset */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009489 0, /*tp_iter*/
9490 0, /*tp_iternext*/
9491 DBSequence_methods, /*tp_methods*/
9492 0, /*tp_members*/
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009493};
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009494
9495/* --------------------------------------------------------------------- */
9496/* Module-level functions */
9497
9498static PyObject*
9499DB_construct(PyObject* self, PyObject* args, PyObject* kwargs)
9500{
9501 PyObject* dbenvobj = NULL;
9502 int flags = 0;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00009503 static char* kwnames[] = { "dbEnv", "flags", NULL};
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009504
Barry Warsaw9a0d7792002-12-30 20:53:52 +00009505 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Oi:DB", kwnames,
9506 &dbenvobj, &flags))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009507 return NULL;
9508 if (dbenvobj == Py_None)
9509 dbenvobj = NULL;
9510 else if (dbenvobj && !DBEnvObject_Check(dbenvobj)) {
9511 makeTypeError("DBEnv", dbenvobj);
9512 return NULL;
9513 }
9514
9515 return (PyObject* )newDBObject((DBEnvObject*)dbenvobj, flags);
9516}
9517
9518
9519static PyObject*
9520DBEnv_construct(PyObject* self, PyObject* args)
9521{
9522 int flags = 0;
9523 if (!PyArg_ParseTuple(args, "|i:DbEnv", &flags)) return NULL;
9524 return (PyObject* )newDBEnvObject(flags);
9525}
9526
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009527static PyObject*
9528DBSequence_construct(PyObject* self, PyObject* args, PyObject* kwargs)
9529{
Neal Norwitzb4fcf8d2006-06-11 05:44:18 +00009530 PyObject* dbobj;
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009531 int flags = 0;
9532 static char* kwnames[] = { "db", "flags", NULL};
9533
9534 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|i:DBSequence", kwnames, &dbobj, &flags))
9535 return NULL;
Neal Norwitzb4fcf8d2006-06-11 05:44:18 +00009536 if (!DBObject_Check(dbobj)) {
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009537 makeTypeError("DB", dbobj);
9538 return NULL;
9539 }
9540 return (PyObject* )newDBSequenceObject((DBObject*)dbobj, flags);
9541}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009542
9543static char bsddb_version_doc[] =
9544"Returns a tuple of major, minor, and patch release numbers of the\n\
9545underlying DB library.";
9546
9547static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009548bsddb_version(PyObject* self)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009549{
9550 int major, minor, patch;
9551
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009552 /* This should be instantaneous, no need to release the GIL */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009553 db_version(&major, &minor, &patch);
9554 return Py_BuildValue("(iii)", major, minor, patch);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009555}
9556
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009557#if (DBVER >= 50)
9558static PyObject*
9559bsddb_version_full(PyObject* self)
9560{
9561 char *version_string;
9562 int family, release, major, minor, patch;
9563
9564 /* This should be instantaneous, no need to release the GIL */
9565 version_string = db_full_version(&family, &release, &major, &minor, &patch);
9566 return Py_BuildValue("(siiiii)",
9567 version_string, family, release, major, minor, patch);
9568}
9569#endif
9570
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009571
9572/* List of functions defined in the module */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009573static PyMethodDef bsddb_methods[] = {
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009574 {"DB", (PyCFunction)DB_construct, METH_VARARGS | METH_KEYWORDS },
9575 {"DBEnv", (PyCFunction)DBEnv_construct, METH_VARARGS},
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009576 {"DBSequence", (PyCFunction)DBSequence_construct, METH_VARARGS | METH_KEYWORDS },
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009577 {"version", (PyCFunction)bsddb_version, METH_NOARGS, bsddb_version_doc},
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009578#if (DBVER >= 50)
9579 {"full_version", (PyCFunction)bsddb_version_full, METH_NOARGS},
9580#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009581 {NULL, NULL} /* sentinel */
9582};
9583
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009584
Gregory P. Smith39250532007-10-09 06:02:21 +00009585/* API structure */
9586static BSDDB_api bsddb_api;
9587
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009588
9589/* --------------------------------------------------------------------- */
9590/* Module initialization */
9591
9592
9593/* Convenience routine to export an integer value.
9594 * Errors are silently ignored, for better or for worse...
9595 */
9596#define ADD_INT(dict, NAME) _addIntToDict(dict, #NAME, NAME)
9597
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009598/*
9599** We can rename the module at import time, so the string allocated
9600** must be big enough, and any use of the name must use this particular
9601** string.
9602*/
Gregory P. Smith41631e82003-09-21 00:08:14 +00009603#define MODULE_NAME_MAX_LEN 11
9604static char _bsddbModuleName[MODULE_NAME_MAX_LEN+1] = "_bsddb";
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009605
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009606#if (PY_VERSION_HEX >= 0x03000000)
9607static struct PyModuleDef bsddbmodule = {
9608 PyModuleDef_HEAD_INIT,
9609 _bsddbModuleName, /* Name of module */
9610 NULL, /* module documentation, may be NULL */
9611 -1, /* size of per-interpreter state of the module,
9612 or -1 if the module keeps state in global variables. */
9613 bsddb_methods,
9614 NULL, /* Reload */
9615 NULL, /* Traverse */
9616 NULL, /* Clear */
9617 NULL /* Free */
9618};
9619#endif
9620
9621
9622#if (PY_VERSION_HEX < 0x03000000)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009623DL_EXPORT(void) init_bsddb(void)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009624#else
9625PyMODINIT_FUNC PyInit__bsddb(void) /* Note the two underscores */
9626#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009627{
9628 PyObject* m;
9629 PyObject* d;
Gregory P. Smith39250532007-10-09 06:02:21 +00009630 PyObject* py_api;
Jesus Cea6557aac2010-03-22 14:22:26 +00009631 PyObject* pybsddb_version_s;
9632 PyObject* db_version_s;
9633 PyObject* cvsid_s;
9634
9635#if (PY_VERSION_HEX < 0x03000000)
9636 pybsddb_version_s = PyString_FromString(PY_BSDDB_VERSION);
9637 db_version_s = PyString_FromString(DB_VERSION_STRING);
9638 cvsid_s = PyString_FromString(rcs_id);
9639#else
9640 /* This data should be ascii, so UTF-8 conversion is fine */
9641 pybsddb_version_s = PyUnicode_FromString(PY_BSDDB_VERSION);
9642 db_version_s = PyUnicode_FromString(DB_VERSION_STRING);
9643 cvsid_s = PyUnicode_FromString(rcs_id);
9644#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009645
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009646 /* Initialize object types */
9647 if ((PyType_Ready(&DB_Type) < 0)
9648 || (PyType_Ready(&DBCursor_Type) < 0)
Jesus Cea6557aac2010-03-22 14:22:26 +00009649 || (PyType_Ready(&DBLogCursor_Type) < 0)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009650 || (PyType_Ready(&DBEnv_Type) < 0)
9651 || (PyType_Ready(&DBTxn_Type) < 0)
9652 || (PyType_Ready(&DBLock_Type) < 0)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009653 || (PyType_Ready(&DBSequence_Type) < 0)
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009654#if (DBVER >= 52)
9655 || (PyType_Ready(&DBSite_Type) < 0)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009656#endif
9657 ) {
9658#if (PY_VERSION_HEX < 0x03000000)
9659 return;
9660#else
9661 return NULL;
9662#endif
9663 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009664
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009665 /* Create the module and add the functions */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009666#if (PY_VERSION_HEX < 0x03000000)
Gregory P. Smith41631e82003-09-21 00:08:14 +00009667 m = Py_InitModule(_bsddbModuleName, bsddb_methods);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009668#else
9669 m=PyModule_Create(&bsddbmodule);
9670#endif
9671 if (m == NULL) {
9672#if (PY_VERSION_HEX < 0x03000000)
9673 return;
9674#else
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009675 return NULL;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009676#endif
9677 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009678
9679 /* Add some symbolic constants to the module */
9680 d = PyModule_GetDict(m);
9681 PyDict_SetItemString(d, "__version__", pybsddb_version_s);
9682 PyDict_SetItemString(d, "cvsid", cvsid_s);
9683 PyDict_SetItemString(d, "DB_VERSION_STRING", db_version_s);
9684 Py_DECREF(pybsddb_version_s);
9685 pybsddb_version_s = NULL;
9686 Py_DECREF(cvsid_s);
9687 cvsid_s = NULL;
9688 Py_DECREF(db_version_s);
9689 db_version_s = NULL;
9690
9691 ADD_INT(d, DB_VERSION_MAJOR);
9692 ADD_INT(d, DB_VERSION_MINOR);
9693 ADD_INT(d, DB_VERSION_PATCH);
9694
9695 ADD_INT(d, DB_MAX_PAGES);
9696 ADD_INT(d, DB_MAX_RECORDS);
9697
Matthias Klose54cc5392010-03-15 12:46:18 +00009698#if (DBVER < 48)
Gregory P. Smith41631e82003-09-21 00:08:14 +00009699 ADD_INT(d, DB_RPCCLIENT);
Matthias Klose54cc5392010-03-15 12:46:18 +00009700#endif
9701
9702#if (DBVER < 48)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009703 ADD_INT(d, DB_XA_CREATE);
Matthias Klose54cc5392010-03-15 12:46:18 +00009704#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009705
9706 ADD_INT(d, DB_CREATE);
9707 ADD_INT(d, DB_NOMMAP);
9708 ADD_INT(d, DB_THREAD);
Jesus Ceaef9764f2008-05-13 18:45:46 +00009709#if (DBVER >= 45)
9710 ADD_INT(d, DB_MULTIVERSION);
9711#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009712
9713 ADD_INT(d, DB_FORCE);
9714 ADD_INT(d, DB_INIT_CDB);
9715 ADD_INT(d, DB_INIT_LOCK);
9716 ADD_INT(d, DB_INIT_LOG);
9717 ADD_INT(d, DB_INIT_MPOOL);
9718 ADD_INT(d, DB_INIT_TXN);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009719 ADD_INT(d, DB_JOINENV);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009720
Matthias Klose54cc5392010-03-15 12:46:18 +00009721#if (DBVER >= 48)
9722 ADD_INT(d, DB_GID_SIZE);
9723#else
Jesus Ceaef9764f2008-05-13 18:45:46 +00009724 ADD_INT(d, DB_XIDDATASIZE);
Matthias Klose54cc5392010-03-15 12:46:18 +00009725 /* Allow new code to work in old BDB releases */
9726 _addIntToDict(d, "DB_GID_SIZE", DB_XIDDATASIZE);
9727#endif
Jesus Ceaef9764f2008-05-13 18:45:46 +00009728
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009729 ADD_INT(d, DB_RECOVER);
9730 ADD_INT(d, DB_RECOVER_FATAL);
9731 ADD_INT(d, DB_TXN_NOSYNC);
9732 ADD_INT(d, DB_USE_ENVIRON);
9733 ADD_INT(d, DB_USE_ENVIRON_ROOT);
9734
9735 ADD_INT(d, DB_LOCKDOWN);
9736 ADD_INT(d, DB_PRIVATE);
9737 ADD_INT(d, DB_SYSTEM_MEM);
9738
9739 ADD_INT(d, DB_TXN_SYNC);
9740 ADD_INT(d, DB_TXN_NOWAIT);
9741
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009742#if (DBVER >= 51)
9743 ADD_INT(d, DB_TXN_BULK);
9744#endif
9745
9746#if (DBVER >= 48)
9747 ADD_INT(d, DB_CURSOR_BULK);
9748#endif
9749
Jesus Cea6557aac2010-03-22 14:22:26 +00009750#if (DBVER >= 46)
9751 ADD_INT(d, DB_TXN_WAIT);
9752#endif
9753
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009754 ADD_INT(d, DB_EXCL);
9755 ADD_INT(d, DB_FCNTL_LOCKING);
9756 ADD_INT(d, DB_ODDFILESIZE);
9757 ADD_INT(d, DB_RDWRMASTER);
9758 ADD_INT(d, DB_RDONLY);
9759 ADD_INT(d, DB_TRUNCATE);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009760 ADD_INT(d, DB_EXTENT);
9761 ADD_INT(d, DB_CDB_ALLDB);
9762 ADD_INT(d, DB_VERIFY);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009763 ADD_INT(d, DB_UPGRADE);
9764
Jesus Cea6557aac2010-03-22 14:22:26 +00009765 ADD_INT(d, DB_PRINTABLE);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009766 ADD_INT(d, DB_AGGRESSIVE);
9767 ADD_INT(d, DB_NOORDERCHK);
9768 ADD_INT(d, DB_ORDERCHKONLY);
9769 ADD_INT(d, DB_PR_PAGE);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009770
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009771 ADD_INT(d, DB_PR_RECOVERYTEST);
9772 ADD_INT(d, DB_SALVAGE);
9773
9774 ADD_INT(d, DB_LOCK_NORUN);
9775 ADD_INT(d, DB_LOCK_DEFAULT);
9776 ADD_INT(d, DB_LOCK_OLDEST);
9777 ADD_INT(d, DB_LOCK_RANDOM);
9778 ADD_INT(d, DB_LOCK_YOUNGEST);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009779 ADD_INT(d, DB_LOCK_MAXLOCKS);
9780 ADD_INT(d, DB_LOCK_MINLOCKS);
9781 ADD_INT(d, DB_LOCK_MINWRITE);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009782
Jesus Ceaef9764f2008-05-13 18:45:46 +00009783 ADD_INT(d, DB_LOCK_EXPIRE);
Jesus Ceaef9764f2008-05-13 18:45:46 +00009784 ADD_INT(d, DB_LOCK_MAXWRITE);
Jesus Ceaef9764f2008-05-13 18:45:46 +00009785
Barry Warsaw9a0d7792002-12-30 20:53:52 +00009786 _addIntToDict(d, "DB_LOCK_CONFLICT", 0);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009787
9788 ADD_INT(d, DB_LOCK_DUMP);
9789 ADD_INT(d, DB_LOCK_GET);
9790 ADD_INT(d, DB_LOCK_INHERIT);
9791 ADD_INT(d, DB_LOCK_PUT);
9792 ADD_INT(d, DB_LOCK_PUT_ALL);
9793 ADD_INT(d, DB_LOCK_PUT_OBJ);
9794
9795 ADD_INT(d, DB_LOCK_NG);
9796 ADD_INT(d, DB_LOCK_READ);
9797 ADD_INT(d, DB_LOCK_WRITE);
9798 ADD_INT(d, DB_LOCK_NOWAIT);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009799 ADD_INT(d, DB_LOCK_WAIT);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009800 ADD_INT(d, DB_LOCK_IWRITE);
9801 ADD_INT(d, DB_LOCK_IREAD);
9802 ADD_INT(d, DB_LOCK_IWR);
Gregory P. Smith29602d22006-01-24 09:46:48 +00009803#if (DBVER < 44)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009804 ADD_INT(d, DB_LOCK_DIRTY);
Gregory P. Smith29602d22006-01-24 09:46:48 +00009805#else
9806 ADD_INT(d, DB_LOCK_READ_UNCOMMITTED); /* renamed in 4.4 */
9807#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009808 ADD_INT(d, DB_LOCK_WWRITE);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009809
9810 ADD_INT(d, DB_LOCK_RECORD);
9811 ADD_INT(d, DB_LOCK_UPGRADE);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009812 ADD_INT(d, DB_LOCK_SWITCH);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009813 ADD_INT(d, DB_LOCK_UPGRADE_WRITE);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009814
9815 ADD_INT(d, DB_LOCK_NOWAIT);
9816 ADD_INT(d, DB_LOCK_RECORD);
9817 ADD_INT(d, DB_LOCK_UPGRADE);
9818
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009819 ADD_INT(d, DB_LSTAT_ABORTED);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009820 ADD_INT(d, DB_LSTAT_FREE);
9821 ADD_INT(d, DB_LSTAT_HELD);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009822
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009823 ADD_INT(d, DB_LSTAT_PENDING);
9824 ADD_INT(d, DB_LSTAT_WAITING);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009825
9826 ADD_INT(d, DB_ARCH_ABS);
9827 ADD_INT(d, DB_ARCH_DATA);
9828 ADD_INT(d, DB_ARCH_LOG);
Gregory P. Smith3dd20022006-06-05 00:31:01 +00009829 ADD_INT(d, DB_ARCH_REMOVE);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009830
9831 ADD_INT(d, DB_BTREE);
9832 ADD_INT(d, DB_HASH);
9833 ADD_INT(d, DB_RECNO);
9834 ADD_INT(d, DB_QUEUE);
9835 ADD_INT(d, DB_UNKNOWN);
9836
9837 ADD_INT(d, DB_DUP);
9838 ADD_INT(d, DB_DUPSORT);
9839 ADD_INT(d, DB_RECNUM);
9840 ADD_INT(d, DB_RENUMBER);
9841 ADD_INT(d, DB_REVSPLITOFF);
9842 ADD_INT(d, DB_SNAPSHOT);
9843
Jesus Cea6557aac2010-03-22 14:22:26 +00009844 ADD_INT(d, DB_INORDER);
Jesus Cea6557aac2010-03-22 14:22:26 +00009845
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009846 ADD_INT(d, DB_JOIN_NOSORT);
9847
9848 ADD_INT(d, DB_AFTER);
9849 ADD_INT(d, DB_APPEND);
9850 ADD_INT(d, DB_BEFORE);
Gregory P. Smith8b96a352007-01-05 01:59:42 +00009851#if (DBVER < 45)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009852 ADD_INT(d, DB_CACHED_COUNTS);
Gregory P. Smith8b96a352007-01-05 01:59:42 +00009853#endif
Jesus Ceaca3939c2008-05-22 15:27:38 +00009854
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009855 ADD_INT(d, DB_CONSUME);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009856 ADD_INT(d, DB_CONSUME_WAIT);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009857 ADD_INT(d, DB_CURRENT);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009858 ADD_INT(d, DB_FAST_STAT);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009859 ADD_INT(d, DB_FIRST);
9860 ADD_INT(d, DB_FLUSH);
9861 ADD_INT(d, DB_GET_BOTH);
Jesus Cea6557aac2010-03-22 14:22:26 +00009862 ADD_INT(d, DB_GET_BOTH_RANGE);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009863 ADD_INT(d, DB_GET_RECNO);
9864 ADD_INT(d, DB_JOIN_ITEM);
9865 ADD_INT(d, DB_KEYFIRST);
9866 ADD_INT(d, DB_KEYLAST);
9867 ADD_INT(d, DB_LAST);
9868 ADD_INT(d, DB_NEXT);
9869 ADD_INT(d, DB_NEXT_DUP);
9870 ADD_INT(d, DB_NEXT_NODUP);
9871 ADD_INT(d, DB_NODUPDATA);
9872 ADD_INT(d, DB_NOOVERWRITE);
9873 ADD_INT(d, DB_NOSYNC);
9874 ADD_INT(d, DB_POSITION);
9875 ADD_INT(d, DB_PREV);
9876 ADD_INT(d, DB_PREV_NODUP);
Jesus Cea6557aac2010-03-22 14:22:26 +00009877#if (DBVER >= 46)
9878 ADD_INT(d, DB_PREV_DUP);
9879#endif
Gregory P. Smith8b96a352007-01-05 01:59:42 +00009880#if (DBVER < 45)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009881 ADD_INT(d, DB_RECORDCOUNT);
Gregory P. Smith8b96a352007-01-05 01:59:42 +00009882#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009883 ADD_INT(d, DB_SET);
9884 ADD_INT(d, DB_SET_RANGE);
9885 ADD_INT(d, DB_SET_RECNO);
9886 ADD_INT(d, DB_WRITECURSOR);
9887
9888 ADD_INT(d, DB_OPFLAGS_MASK);
9889 ADD_INT(d, DB_RMW);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009890 ADD_INT(d, DB_DIRTY_READ);
9891 ADD_INT(d, DB_MULTIPLE);
9892 ADD_INT(d, DB_MULTIPLE_KEY);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009893
Gregory P. Smith29602d22006-01-24 09:46:48 +00009894#if (DBVER >= 44)
Jesus Cea6557aac2010-03-22 14:22:26 +00009895 ADD_INT(d, DB_IMMUTABLE_KEY);
Gregory P. Smith29602d22006-01-24 09:46:48 +00009896 ADD_INT(d, DB_READ_UNCOMMITTED); /* replaces DB_DIRTY_READ in 4.4 */
9897 ADD_INT(d, DB_READ_COMMITTED);
9898#endif
9899
Jesus Cea6557aac2010-03-22 14:22:26 +00009900#if (DBVER >= 44)
9901 ADD_INT(d, DB_FREELIST_ONLY);
9902 ADD_INT(d, DB_FREE_SPACE);
9903#endif
9904
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009905 ADD_INT(d, DB_DONOTINDEX);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009906
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009907 ADD_INT(d, DB_KEYEMPTY);
9908 ADD_INT(d, DB_KEYEXIST);
9909 ADD_INT(d, DB_LOCK_DEADLOCK);
9910 ADD_INT(d, DB_LOCK_NOTGRANTED);
9911 ADD_INT(d, DB_NOSERVER);
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009912#if (DBVER < 52)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009913 ADD_INT(d, DB_NOSERVER_HOME);
9914 ADD_INT(d, DB_NOSERVER_ID);
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009915#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009916 ADD_INT(d, DB_NOTFOUND);
9917 ADD_INT(d, DB_OLD_VERSION);
9918 ADD_INT(d, DB_RUNRECOVERY);
9919 ADD_INT(d, DB_VERIFY_BAD);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009920 ADD_INT(d, DB_PAGE_NOTFOUND);
9921 ADD_INT(d, DB_SECONDARY_BAD);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009922 ADD_INT(d, DB_STAT_CLEAR);
9923 ADD_INT(d, DB_REGION_INIT);
9924 ADD_INT(d, DB_NOLOCKING);
9925 ADD_INT(d, DB_YIELDCPU);
9926 ADD_INT(d, DB_PANIC_ENVIRONMENT);
9927 ADD_INT(d, DB_NOPANIC);
Jesus Ceaef9764f2008-05-13 18:45:46 +00009928 ADD_INT(d, DB_OVERWRITE);
Jesus Cea6557aac2010-03-22 14:22:26 +00009929
Jesus Cea6557aac2010-03-22 14:22:26 +00009930 ADD_INT(d, DB_STAT_SUBSYSTEM);
9931 ADD_INT(d, DB_STAT_MEMP_HASH);
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009932 ADD_INT(d, DB_STAT_LOCK_CONF);
9933 ADD_INT(d, DB_STAT_LOCK_LOCKERS);
9934 ADD_INT(d, DB_STAT_LOCK_OBJECTS);
9935 ADD_INT(d, DB_STAT_LOCK_PARAMS);
Jesus Ceaef9764f2008-05-13 18:45:46 +00009936
Jesus Cea6557aac2010-03-22 14:22:26 +00009937#if (DBVER >= 48)
9938 ADD_INT(d, DB_OVERWRITE_DUP);
9939#endif
9940
9941#if (DBVER >= 47)
9942 ADD_INT(d, DB_FOREIGN_ABORT);
9943 ADD_INT(d, DB_FOREIGN_CASCADE);
9944 ADD_INT(d, DB_FOREIGN_NULLIFY);
9945#endif
9946
9947#if (DBVER >= 44)
Gregory P. Smithaae141a2007-11-01 21:08:14 +00009948 ADD_INT(d, DB_REGISTER);
9949#endif
9950
Jesus Cea6557aac2010-03-22 14:22:26 +00009951 ADD_INT(d, DB_EID_INVALID);
9952 ADD_INT(d, DB_EID_BROADCAST);
9953
Gregory P. Smith41631e82003-09-21 00:08:14 +00009954 ADD_INT(d, DB_TIME_NOTGRANTED);
9955 ADD_INT(d, DB_TXN_NOT_DURABLE);
9956 ADD_INT(d, DB_TXN_WRITE_NOSYNC);
Gregory P. Smith41631e82003-09-21 00:08:14 +00009957 ADD_INT(d, DB_DIRECT_DB);
9958 ADD_INT(d, DB_INIT_REP);
9959 ADD_INT(d, DB_ENCRYPT);
9960 ADD_INT(d, DB_CHKSUM);
Gregory P. Smith41631e82003-09-21 00:08:14 +00009961
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009962#if (DBVER < 47)
Jesus Ceaca3939c2008-05-22 15:27:38 +00009963 ADD_INT(d, DB_LOG_AUTOREMOVE);
9964 ADD_INT(d, DB_DIRECT_LOG);
9965#endif
9966
9967#if (DBVER >= 47)
9968 ADD_INT(d, DB_LOG_DIRECT);
9969 ADD_INT(d, DB_LOG_DSYNC);
9970 ADD_INT(d, DB_LOG_IN_MEMORY);
9971 ADD_INT(d, DB_LOG_AUTO_REMOVE);
9972 ADD_INT(d, DB_LOG_ZERO);
9973#endif
9974
Jesus Ceaef9764f2008-05-13 18:45:46 +00009975#if (DBVER >= 44)
9976 ADD_INT(d, DB_DSYNC_DB);
9977#endif
9978
9979#if (DBVER >= 45)
9980 ADD_INT(d, DB_TXN_SNAPSHOT);
9981#endif
9982
Jesus Ceaef9764f2008-05-13 18:45:46 +00009983 ADD_INT(d, DB_VERB_DEADLOCK);
9984#if (DBVER >= 46)
9985 ADD_INT(d, DB_VERB_FILEOPS);
9986 ADD_INT(d, DB_VERB_FILEOPS_ALL);
9987#endif
9988 ADD_INT(d, DB_VERB_RECOVERY);
9989#if (DBVER >= 44)
9990 ADD_INT(d, DB_VERB_REGISTER);
9991#endif
9992 ADD_INT(d, DB_VERB_REPLICATION);
9993 ADD_INT(d, DB_VERB_WAITSFOR);
Jesus Ceaef9764f2008-05-13 18:45:46 +00009994
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009995#if (DBVER >= 50)
9996 ADD_INT(d, DB_VERB_REP_SYSTEM);
9997#endif
9998
9999#if (DBVER >= 47)
10000 ADD_INT(d, DB_VERB_REP_ELECT);
10001 ADD_INT(d, DB_VERB_REP_LEASE);
10002 ADD_INT(d, DB_VERB_REP_MISC);
10003 ADD_INT(d, DB_VERB_REP_MSGS);
10004 ADD_INT(d, DB_VERB_REP_SYNC);
10005 ADD_INT(d, DB_VERB_REPMGR_CONNFAIL);
10006 ADD_INT(d, DB_VERB_REPMGR_MISC);
10007#endif
10008
Jesus Ceaef9764f2008-05-13 18:45:46 +000010009#if (DBVER >= 45)
10010 ADD_INT(d, DB_EVENT_PANIC);
10011 ADD_INT(d, DB_EVENT_REP_CLIENT);
10012#if (DBVER >= 46)
10013 ADD_INT(d, DB_EVENT_REP_ELECTED);
10014#endif
10015 ADD_INT(d, DB_EVENT_REP_MASTER);
10016 ADD_INT(d, DB_EVENT_REP_NEWMASTER);
10017#if (DBVER >= 46)
10018 ADD_INT(d, DB_EVENT_REP_PERM_FAILED);
10019#endif
10020 ADD_INT(d, DB_EVENT_REP_STARTUPDONE);
10021 ADD_INT(d, DB_EVENT_WRITE_FAILED);
10022#endif
10023
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010024#if (DBVER >= 50)
10025 ADD_INT(d, DB_REPMGR_CONF_ELECTIONS);
10026 ADD_INT(d, DB_EVENT_REP_MASTER_FAILURE);
10027 ADD_INT(d, DB_EVENT_REP_DUPMASTER);
10028 ADD_INT(d, DB_EVENT_REP_ELECTION_FAILED);
10029#endif
10030#if (DBVER >= 48)
10031 ADD_INT(d, DB_EVENT_REG_ALIVE);
10032 ADD_INT(d, DB_EVENT_REG_PANIC);
10033#endif
10034
10035#if (DBVER >=52)
10036 ADD_INT(d, DB_EVENT_REP_SITE_ADDED);
10037 ADD_INT(d, DB_EVENT_REP_SITE_REMOVED);
10038 ADD_INT(d, DB_EVENT_REP_LOCAL_SITE_REMOVED);
10039 ADD_INT(d, DB_EVENT_REP_CONNECT_BROKEN);
10040 ADD_INT(d, DB_EVENT_REP_CONNECT_ESTD);
10041 ADD_INT(d, DB_EVENT_REP_CONNECT_TRY_FAILED);
10042 ADD_INT(d, DB_EVENT_REP_INIT_DONE);
10043
10044 ADD_INT(d, DB_MEM_LOCK);
10045 ADD_INT(d, DB_MEM_LOCKOBJECT);
10046 ADD_INT(d, DB_MEM_LOCKER);
10047 ADD_INT(d, DB_MEM_LOGID);
10048 ADD_INT(d, DB_MEM_TRANSACTION);
10049 ADD_INT(d, DB_MEM_THREAD);
10050
10051 ADD_INT(d, DB_BOOTSTRAP_HELPER);
10052 ADD_INT(d, DB_GROUP_CREATOR);
10053 ADD_INT(d, DB_LEGACY);
10054 ADD_INT(d, DB_LOCAL_SITE);
10055 ADD_INT(d, DB_REPMGR_PEER);
10056#endif
10057
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010058 ADD_INT(d, DB_REP_DUPMASTER);
10059 ADD_INT(d, DB_REP_HOLDELECTION);
10060#if (DBVER >= 44)
10061 ADD_INT(d, DB_REP_IGNORE);
10062 ADD_INT(d, DB_REP_JOIN_FAILURE);
10063#endif
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010064 ADD_INT(d, DB_REP_ISPERM);
10065 ADD_INT(d, DB_REP_NOTPERM);
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010066 ADD_INT(d, DB_REP_NEWSITE);
10067
Jesus Ceaef9764f2008-05-13 18:45:46 +000010068 ADD_INT(d, DB_REP_MASTER);
10069 ADD_INT(d, DB_REP_CLIENT);
Jesus Cea6557aac2010-03-22 14:22:26 +000010070
10071 ADD_INT(d, DB_REP_PERMANENT);
10072
10073#if (DBVER >= 44)
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010074#if (DBVER >= 50)
10075 ADD_INT(d, DB_REP_CONF_AUTOINIT);
10076#else
Jesus Cea6557aac2010-03-22 14:22:26 +000010077 ADD_INT(d, DB_REP_CONF_NOAUTOINIT);
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010078#endif /* 5.0 */
10079#endif /* 4.4 */
10080#if (DBVER >= 44)
Jesus Cea6557aac2010-03-22 14:22:26 +000010081 ADD_INT(d, DB_REP_CONF_DELAYCLIENT);
10082 ADD_INT(d, DB_REP_CONF_BULK);
10083 ADD_INT(d, DB_REP_CONF_NOWAIT);
10084 ADD_INT(d, DB_REP_ANYWHERE);
10085 ADD_INT(d, DB_REP_REREQUEST);
10086#endif
10087
Jesus Cea6557aac2010-03-22 14:22:26 +000010088 ADD_INT(d, DB_REP_NOBUFFER);
Jesus Cea6557aac2010-03-22 14:22:26 +000010089
10090#if (DBVER >= 46)
10091 ADD_INT(d, DB_REP_LEASE_EXPIRED);
10092 ADD_INT(d, DB_IGNORE_LEASE);
10093#endif
10094
10095#if (DBVER >= 47)
10096 ADD_INT(d, DB_REP_CONF_LEASE);
10097 ADD_INT(d, DB_REPMGR_CONF_2SITE_STRICT);
10098#endif
10099
Jesus Ceaef9764f2008-05-13 18:45:46 +000010100#if (DBVER >= 45)
10101 ADD_INT(d, DB_REP_ELECTION);
10102
10103 ADD_INT(d, DB_REP_ACK_TIMEOUT);
10104 ADD_INT(d, DB_REP_CONNECTION_RETRY);
10105 ADD_INT(d, DB_REP_ELECTION_TIMEOUT);
10106 ADD_INT(d, DB_REP_ELECTION_RETRY);
10107#endif
10108#if (DBVER >= 46)
10109 ADD_INT(d, DB_REP_CHECKPOINT_DELAY);
10110 ADD_INT(d, DB_REP_FULL_ELECTION_TIMEOUT);
Jesus Cea6557aac2010-03-22 14:22:26 +000010111 ADD_INT(d, DB_REP_LEASE_TIMEOUT);
10112#endif
10113#if (DBVER >= 47)
10114 ADD_INT(d, DB_REP_HEARTBEAT_MONITOR);
10115 ADD_INT(d, DB_REP_HEARTBEAT_SEND);
Jesus Ceaef9764f2008-05-13 18:45:46 +000010116#endif
Jesus Ceaef9764f2008-05-13 18:45:46 +000010117
10118#if (DBVER >= 45)
10119 ADD_INT(d, DB_REPMGR_PEER);
10120 ADD_INT(d, DB_REPMGR_ACKS_ALL);
10121 ADD_INT(d, DB_REPMGR_ACKS_ALL_PEERS);
10122 ADD_INT(d, DB_REPMGR_ACKS_NONE);
10123 ADD_INT(d, DB_REPMGR_ACKS_ONE);
10124 ADD_INT(d, DB_REPMGR_ACKS_ONE_PEER);
10125 ADD_INT(d, DB_REPMGR_ACKS_QUORUM);
10126 ADD_INT(d, DB_REPMGR_CONNECTED);
10127 ADD_INT(d, DB_REPMGR_DISCONNECTED);
Jesus Ceaef9764f2008-05-13 18:45:46 +000010128 ADD_INT(d, DB_STAT_ALL);
10129#endif
10130
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010131#if (DBVER >= 51)
10132 ADD_INT(d, DB_REPMGR_ACKS_ALL_AVAILABLE);
10133#endif
10134
10135#if (DBVER >= 48)
10136 ADD_INT(d, DB_REP_CONF_INMEM);
10137#endif
10138
10139 ADD_INT(d, DB_TIMEOUT);
10140
10141#if (DBVER >= 50)
10142 ADD_INT(d, DB_FORCESYNC);
10143#endif
10144
10145#if (DBVER >= 48)
10146 ADD_INT(d, DB_FAILCHK);
10147#endif
10148
10149#if (DBVER >= 51)
10150 ADD_INT(d, DB_HOTBACKUP_IN_PROGRESS);
10151#endif
10152
Gregory P. Smith8b7e9172004-12-13 09:51:23 +000010153 ADD_INT(d, DB_BUFFER_SMALL);
Gregory P. Smithf0547d02006-06-05 17:38:04 +000010154 ADD_INT(d, DB_SEQ_DEC);
10155 ADD_INT(d, DB_SEQ_INC);
10156 ADD_INT(d, DB_SEQ_WRAP);
Gregory P. Smith8b7e9172004-12-13 09:51:23 +000010157
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010158#if (DBVER < 47)
Jesus Ceaca3939c2008-05-22 15:27:38 +000010159 ADD_INT(d, DB_LOG_INMEMORY);
10160 ADD_INT(d, DB_DSYNC_LOG);
10161#endif
10162
Barry Warsaw9a0d7792002-12-30 20:53:52 +000010163 ADD_INT(d, DB_ENCRYPT_AES);
10164 ADD_INT(d, DB_AUTO_COMMIT);
Jesus Cea6557aac2010-03-22 14:22:26 +000010165 ADD_INT(d, DB_PRIORITY_VERY_LOW);
10166 ADD_INT(d, DB_PRIORITY_LOW);
10167 ADD_INT(d, DB_PRIORITY_DEFAULT);
10168 ADD_INT(d, DB_PRIORITY_HIGH);
10169 ADD_INT(d, DB_PRIORITY_VERY_HIGH);
10170
10171#if (DBVER >= 46)
10172 ADD_INT(d, DB_PRIORITY_UNCHANGED);
Barry Warsaw9a0d7792002-12-30 20:53:52 +000010173#endif
10174
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010175 ADD_INT(d, EINVAL);
10176 ADD_INT(d, EACCES);
10177 ADD_INT(d, ENOSPC);
10178 ADD_INT(d, ENOMEM);
10179 ADD_INT(d, EAGAIN);
10180 ADD_INT(d, EBUSY);
10181 ADD_INT(d, EEXIST);
10182 ADD_INT(d, ENOENT);
10183 ADD_INT(d, EPERM);
10184
Barry Warsaw1baa9822003-03-31 19:51:29 +000010185 ADD_INT(d, DB_SET_LOCK_TIMEOUT);
10186 ADD_INT(d, DB_SET_TXN_TIMEOUT);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010187
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010188#if (DBVER >= 48)
10189 ADD_INT(d, DB_SET_REG_TIMEOUT);
10190#endif
10191
Gregory P. Smith7f5b6f42006-04-08 07:10:51 +000010192 /* The exception name must be correct for pickled exception *
10193 * objects to unpickle properly. */
10194#ifdef PYBSDDB_STANDALONE /* different value needed for standalone pybsddb */
10195#define PYBSDDB_EXCEPTION_BASE "bsddb3.db."
10196#else
10197#define PYBSDDB_EXCEPTION_BASE "bsddb.db."
10198#endif
10199
10200 /* All the rest of the exceptions derive only from DBError */
10201#define MAKE_EX(name) name = PyErr_NewException(PYBSDDB_EXCEPTION_BASE #name, DBError, NULL); \
10202 PyDict_SetItemString(d, #name, name)
10203
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010204 /* The base exception class is DBError */
Gregory P. Smith7f5b6f42006-04-08 07:10:51 +000010205 DBError = NULL; /* used in MAKE_EX so that it derives from nothing */
10206 MAKE_EX(DBError);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010207
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010208#if (PY_VERSION_HEX < 0x03000000)
Gregory P. Smithe9477062005-06-04 06:46:59 +000010209 /* Some magic to make DBNotFoundError and DBKeyEmptyError derive
10210 * from both DBError and KeyError, since the API only supports
10211 * using one base class. */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010212 PyDict_SetItemString(d, "KeyError", PyExc_KeyError);
Gregory P. Smithe9477062005-06-04 06:46:59 +000010213 PyRun_String("class DBNotFoundError(DBError, KeyError): pass\n"
Antoine Pitrouc83ea132010-05-09 14:46:46 +000010214 "class DBKeyEmptyError(DBError, KeyError): pass",
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010215 Py_file_input, d, d);
10216 DBNotFoundError = PyDict_GetItemString(d, "DBNotFoundError");
Gregory P. Smithe9477062005-06-04 06:46:59 +000010217 DBKeyEmptyError = PyDict_GetItemString(d, "DBKeyEmptyError");
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010218 PyDict_DelItemString(d, "KeyError");
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010219#else
10220 /* Since Python 2.5, PyErr_NewException() accepts a tuple, to be able to
10221 ** derive from several classes. We use this new API only for Python 3.0,
10222 ** though.
10223 */
10224 {
10225 PyObject* bases;
10226
10227 bases = PyTuple_Pack(2, DBError, PyExc_KeyError);
10228
10229#define MAKE_EX2(name) name = PyErr_NewException(PYBSDDB_EXCEPTION_BASE #name, bases, NULL); \
10230 PyDict_SetItemString(d, #name, name)
10231 MAKE_EX2(DBNotFoundError);
10232 MAKE_EX2(DBKeyEmptyError);
10233
10234#undef MAKE_EX2
10235
10236 Py_XDECREF(bases);
10237 }
10238#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010239
Gregory P. Smithe2767172003-11-02 08:06:29 +000010240 MAKE_EX(DBCursorClosedError);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010241 MAKE_EX(DBKeyExistError);
10242 MAKE_EX(DBLockDeadlockError);
10243 MAKE_EX(DBLockNotGrantedError);
10244 MAKE_EX(DBOldVersionError);
10245 MAKE_EX(DBRunRecoveryError);
10246 MAKE_EX(DBVerifyBadError);
10247 MAKE_EX(DBNoServerError);
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010248#if (DBVER < 52)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010249 MAKE_EX(DBNoServerHomeError);
10250 MAKE_EX(DBNoServerIDError);
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010251#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010252 MAKE_EX(DBPageNotFoundError);
10253 MAKE_EX(DBSecondaryBadError);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010254
10255 MAKE_EX(DBInvalidArgError);
10256 MAKE_EX(DBAccessError);
10257 MAKE_EX(DBNoSpaceError);
10258 MAKE_EX(DBNoMemoryError);
10259 MAKE_EX(DBAgainError);
10260 MAKE_EX(DBBusyError);
10261 MAKE_EX(DBFileExistsError);
10262 MAKE_EX(DBNoSuchFileError);
10263 MAKE_EX(DBPermissionsError);
10264
Jesus Ceaef9764f2008-05-13 18:45:46 +000010265 MAKE_EX(DBRepHandleDeadError);
Jesus Cea6557aac2010-03-22 14:22:26 +000010266#if (DBVER >= 44)
10267 MAKE_EX(DBRepLockoutError);
10268#endif
Jesus Ceaef9764f2008-05-13 18:45:46 +000010269
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010270 MAKE_EX(DBRepUnavailError);
10271
Jesus Cea6557aac2010-03-22 14:22:26 +000010272#if (DBVER >= 46)
10273 MAKE_EX(DBRepLeaseExpiredError);
10274#endif
10275
10276#if (DBVER >= 47)
10277 MAKE_EX(DBForeignConflictError);
10278#endif
10279
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010280#undef MAKE_EX
10281
Jesus Cea6557aac2010-03-22 14:22:26 +000010282 /* Initialise the C API structure and add it to the module */
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010283 bsddb_api.api_version = PYBSDDB_API_VERSION;
Jesus Cea6557aac2010-03-22 14:22:26 +000010284 bsddb_api.db_type = &DB_Type;
10285 bsddb_api.dbcursor_type = &DBCursor_Type;
10286 bsddb_api.dblogcursor_type = &DBLogCursor_Type;
10287 bsddb_api.dbenv_type = &DBEnv_Type;
10288 bsddb_api.dbtxn_type = &DBTxn_Type;
10289 bsddb_api.dblock_type = &DBLock_Type;
Jesus Cea6557aac2010-03-22 14:22:26 +000010290 bsddb_api.dbsequence_type = &DBSequence_Type;
Jesus Cea6557aac2010-03-22 14:22:26 +000010291 bsddb_api.makeDBError = makeDBError;
Gregory P. Smith39250532007-10-09 06:02:21 +000010292
Jesus Cea6557aac2010-03-22 14:22:26 +000010293 /*
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010294 ** Capsules exist from Python 2.7 and 3.1.
10295 ** We don't support Python 3.0 anymore, so...
10296 ** #if (PY_VERSION_HEX < ((PY_MAJOR_VERSION < 3) ? 0x02070000 : 0x03020000))
Jesus Cea6557aac2010-03-22 14:22:26 +000010297 */
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010298#if (PY_VERSION_HEX < 0x02070000)
Gregory P. Smith39250532007-10-09 06:02:21 +000010299 py_api = PyCObject_FromVoidPtr((void*)&bsddb_api, NULL);
Jesus Cea6557aac2010-03-22 14:22:26 +000010300#else
10301 {
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010302 /*
10303 ** The data must outlive the call!!. So, the static definition.
10304 ** The buffer must be big enough...
10305 */
10306 static char py_api_name[MODULE_NAME_MAX_LEN+10];
Jesus Cea6557aac2010-03-22 14:22:26 +000010307
10308 strcpy(py_api_name, _bsddbModuleName);
10309 strcat(py_api_name, ".api");
10310
10311 py_api = PyCapsule_New((void*)&bsddb_api, py_api_name, NULL);
10312 }
10313#endif
10314
Jesus Cea84f2c322010-11-05 00:13:50 +000010315 /* Check error control */
10316 /*
10317 ** PyErr_NoMemory();
10318 ** py_api = NULL;
10319 */
10320
10321 if (py_api) {
10322 PyDict_SetItemString(d, "api", py_api);
10323 Py_DECREF(py_api);
10324 } else { /* Something bad happened */
10325 PyErr_WriteUnraisable(m);
Jesus Ceabf088f82010-11-08 12:57:59 +000010326 if(PyErr_Warn(PyExc_RuntimeWarning,
10327 "_bsddb/_pybsddb C API will be not available")) {
10328 PyErr_WriteUnraisable(m);
10329 }
Jesus Cea84f2c322010-11-05 00:13:50 +000010330 PyErr_Clear();
10331 }
Gregory P. Smith39250532007-10-09 06:02:21 +000010332
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010333 /* Check for errors */
10334 if (PyErr_Occurred()) {
10335 PyErr_Print();
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010336 Py_FatalError("can't initialize module _bsddb/_pybsddb");
10337 Py_DECREF(m);
10338 m = NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010339 }
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010340#if (PY_VERSION_HEX < 0x03000000)
10341 return;
10342#else
10343 return m;
10344#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010345}
Gregory P. Smith41631e82003-09-21 00:08:14 +000010346
10347/* allow this module to be named _pybsddb so that it can be installed
10348 * and imported on top of python >= 2.3 that includes its own older
10349 * copy of the library named _bsddb without importing the old version. */
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010350#if (PY_VERSION_HEX < 0x03000000)
Gregory P. Smith41631e82003-09-21 00:08:14 +000010351DL_EXPORT(void) init_pybsddb(void)
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010352#else
10353PyMODINIT_FUNC PyInit__pybsddb(void) /* Note the two underscores */
10354#endif
Gregory P. Smith41631e82003-09-21 00:08:14 +000010355{
10356 strncpy(_bsddbModuleName, "_pybsddb", MODULE_NAME_MAX_LEN);
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010357#if (PY_VERSION_HEX < 0x03000000)
Gregory P. Smith41631e82003-09-21 00:08:14 +000010358 init_bsddb();
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010359#else
10360 return PyInit__bsddb(); /* Note the two underscores */
10361#endif
Gregory P. Smith41631e82003-09-21 00:08:14 +000010362}