blob: 203bba26727262a2443f9a2533264d80fb5275ad [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) {
Serhiy Storchaka98a97222014-02-09 13:14:04 +0200952 Py_CLEAR(self->myenvobj);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000953 }
Gregory P. Smith664782e2008-05-17 06:12:02 +0000954 Py_DECREF(self);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000955 self = NULL;
956 }
957 return self;
958}
959
960
Jesus Ceaef9764f2008-05-13 18:45:46 +0000961/* Forward declaration */
Jesus Cea5cd5f122008-09-23 18:54:08 +0000962static PyObject *DB_close_internal(DBObject* self, int flags, int do_not_close);
Jesus Ceaef9764f2008-05-13 18:45:46 +0000963
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000964static void
965DB_dealloc(DBObject* self)
966{
Jesus Ceaef9764f2008-05-13 18:45:46 +0000967 PyObject *dummy;
968
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000969 if (self->db != NULL) {
Jesus Cea5cd5f122008-09-23 18:54:08 +0000970 dummy=DB_close_internal(self, 0, 0);
971 /*
972 ** Raising exceptions while doing
973 ** garbage collection is a fatal error.
974 */
975 if (dummy)
976 Py_DECREF(dummy);
977 else
978 PyErr_Clear();
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000979 }
Gregory P. Smith31c50652004-06-28 01:20:40 +0000980 if (self->in_weakreflist != NULL) {
981 PyObject_ClearWeakRefs((PyObject *) self);
982 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000983 if (self->myenvobj) {
Serhiy Storchaka98a97222014-02-09 13:14:04 +0200984 Py_CLEAR(self->myenvobj);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000985 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000986 if (self->associateCallback != NULL) {
Serhiy Storchaka98a97222014-02-09 13:14:04 +0200987 Py_CLEAR(self->associateCallback);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000988 }
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +0000989 if (self->btCompareCallback != NULL) {
Serhiy Storchaka98a97222014-02-09 13:14:04 +0200990 Py_CLEAR(self->btCompareCallback);
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +0000991 }
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -0700992 if (self->dupCompareCallback != NULL) {
Serhiy Storchaka98a97222014-02-09 13:14:04 +0200993 Py_CLEAR(self->dupCompareCallback);
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -0700994 }
Jesus Cea4907d272008-08-31 14:00:51 +0000995 Py_DECREF(self->private_obj);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000996 PyObject_Del(self);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000997}
998
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000999static DBCursorObject*
Jesus Ceaef9764f2008-05-13 18:45:46 +00001000newDBCursorObject(DBC* dbc, DBTxnObject *txn, DBObject* db)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001001{
Neal Norwitzb4a55812004-07-09 23:30:57 +00001002 DBCursorObject* self = PyObject_New(DBCursorObject, &DBCursor_Type);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001003 if (self == NULL)
1004 return NULL;
1005
1006 self->dbc = dbc;
1007 self->mydb = db;
Jesus Ceaef9764f2008-05-13 18:45:46 +00001008
1009 INSERT_IN_DOUBLE_LINKED_LIST(self->mydb->children_cursors,self);
1010 if (txn && ((PyObject *)txn!=Py_None)) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001011 INSERT_IN_DOUBLE_LINKED_LIST_TXN(txn->children_cursors,self);
1012 self->txn=txn;
Jesus Ceaef9764f2008-05-13 18:45:46 +00001013 } else {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001014 self->txn=NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00001015 }
1016
Gregory P. Smitha703a212003-11-03 01:04:41 +00001017 self->in_weakreflist = NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001018 Py_INCREF(self->mydb);
1019 return self;
1020}
1021
1022
Jesus Ceaef9764f2008-05-13 18:45:46 +00001023/* Forward declaration */
1024static PyObject *DBC_close_internal(DBCursorObject* self);
1025
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001026static void
1027DBCursor_dealloc(DBCursorObject* self)
1028{
Jesus Ceaef9764f2008-05-13 18:45:46 +00001029 PyObject *dummy;
Gregory P. Smitha703a212003-11-03 01:04:41 +00001030
Jesus Ceaef9764f2008-05-13 18:45:46 +00001031 if (self->dbc != NULL) {
Jesus Cea5cd5f122008-09-23 18:54:08 +00001032 dummy=DBC_close_internal(self);
1033 /*
1034 ** Raising exceptions while doing
1035 ** garbage collection is a fatal error.
1036 */
1037 if (dummy)
1038 Py_DECREF(dummy);
1039 else
1040 PyErr_Clear();
Jesus Ceaef9764f2008-05-13 18:45:46 +00001041 }
Gregory P. Smitha703a212003-11-03 01:04:41 +00001042 if (self->in_weakreflist != NULL) {
1043 PyObject_ClearWeakRefs((PyObject *) self);
1044 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00001045 Py_DECREF(self->mydb);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001046 PyObject_Del(self);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001047}
1048
1049
Jesus Cea6557aac2010-03-22 14:22:26 +00001050static DBLogCursorObject*
1051newDBLogCursorObject(DB_LOGC* dblogc, DBEnvObject* env)
1052{
1053 DBLogCursorObject* self;
1054
1055 self = PyObject_New(DBLogCursorObject, &DBLogCursor_Type);
1056
1057 if (self == NULL)
1058 return NULL;
1059
1060 self->logc = dblogc;
1061 self->env = env;
1062
1063 INSERT_IN_DOUBLE_LINKED_LIST(self->env->children_logcursors, self);
1064
1065 self->in_weakreflist = NULL;
1066 Py_INCREF(self->env);
1067 return self;
1068}
1069
1070
1071/* Forward declaration */
1072static PyObject *DBLogCursor_close_internal(DBLogCursorObject* self);
1073
1074static void
1075DBLogCursor_dealloc(DBLogCursorObject* self)
1076{
1077 PyObject *dummy;
1078
1079 if (self->logc != NULL) {
1080 dummy = DBLogCursor_close_internal(self);
1081 /*
1082 ** Raising exceptions while doing
1083 ** garbage collection is a fatal error.
1084 */
1085 if (dummy)
1086 Py_DECREF(dummy);
1087 else
1088 PyErr_Clear();
1089 }
1090 if (self->in_weakreflist != NULL) {
1091 PyObject_ClearWeakRefs((PyObject *) self);
1092 }
1093 Py_DECREF(self->env);
1094 PyObject_Del(self);
1095}
1096
1097
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001098static DBEnvObject*
1099newDBEnvObject(int flags)
1100{
1101 int err;
Neal Norwitzb4a55812004-07-09 23:30:57 +00001102 DBEnvObject* self = PyObject_New(DBEnvObject, &DBEnv_Type);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001103 if (self == NULL)
1104 return NULL;
1105
Jesus Cea5cd5f122008-09-23 18:54:08 +00001106 self->db_env = NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001107 self->closed = 1;
1108 self->flags = flags;
Gregory P. Smith455d46f2003-07-09 04:45:59 +00001109 self->moduleFlags.getReturnsNone = DEFAULT_GET_RETURNS_NONE;
1110 self->moduleFlags.cursorSetReturnsNone = DEFAULT_CURSOR_SET_RETURNS_NONE;
Jesus Ceaef9764f2008-05-13 18:45:46 +00001111 self->children_dbs = NULL;
1112 self->children_txns = NULL;
Jesus Cea6557aac2010-03-22 14:22:26 +00001113 self->children_logcursors = NULL ;
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07001114#if (DBVER >= 52)
1115 self->children_sites = NULL;
1116#endif
Jesus Ceac5a11fa2008-07-23 11:38:42 +00001117 Py_INCREF(Py_None);
Jesus Cea4907d272008-08-31 14:00:51 +00001118 self->private_obj = Py_None;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00001119 Py_INCREF(Py_None);
1120 self->rep_transport = Py_None;
Gregory P. Smith31c50652004-06-28 01:20:40 +00001121 self->in_weakreflist = NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00001122 self->event_notifyCallback = NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00001123
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001124 MYDB_BEGIN_ALLOW_THREADS;
1125 err = db_env_create(&self->db_env, flags);
1126 MYDB_END_ALLOW_THREADS;
1127 if (makeDBError(err)) {
Gregory P. Smith664782e2008-05-17 06:12:02 +00001128 Py_DECREF(self);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001129 self = NULL;
1130 }
1131 else {
1132 self->db_env->set_errcall(self->db_env, _db_errorCallback);
Jesus Cea4907d272008-08-31 14:00:51 +00001133 self->db_env->app_private = self;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001134 }
1135 return self;
1136}
1137
Jesus Ceaef9764f2008-05-13 18:45:46 +00001138/* Forward declaration */
1139static PyObject *DBEnv_close_internal(DBEnvObject* self, int flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001140
1141static void
1142DBEnv_dealloc(DBEnvObject* self)
1143{
Jesus Ceaef9764f2008-05-13 18:45:46 +00001144 PyObject *dummy;
1145
Jesus Ceaac25fab2008-09-03 17:50:32 +00001146 if (self->db_env) {
Jesus Cea5cd5f122008-09-23 18:54:08 +00001147 dummy=DBEnv_close_internal(self, 0);
1148 /*
1149 ** Raising exceptions while doing
1150 ** garbage collection is a fatal error.
1151 */
1152 if (dummy)
1153 Py_DECREF(dummy);
1154 else
1155 PyErr_Clear();
Jesus Ceaef9764f2008-05-13 18:45:46 +00001156 }
1157
Serhiy Storchaka98a97222014-02-09 13:14:04 +02001158 Py_CLEAR(self->event_notifyCallback);
Jesus Ceaef9764f2008-05-13 18:45:46 +00001159
Gregory P. Smith31c50652004-06-28 01:20:40 +00001160 if (self->in_weakreflist != NULL) {
1161 PyObject_ClearWeakRefs((PyObject *) self);
1162 }
Jesus Cea4907d272008-08-31 14:00:51 +00001163 Py_DECREF(self->private_obj);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00001164 Py_DECREF(self->rep_transport);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001165 PyObject_Del(self);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001166}
1167
1168
1169static DBTxnObject*
Jesus Ceaef9764f2008-05-13 18:45:46 +00001170newDBTxnObject(DBEnvObject* myenv, DBTxnObject *parent, DB_TXN *txn, int flags)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001171{
1172 int err;
Gregory P. Smith664782e2008-05-17 06:12:02 +00001173 DB_TXN *parent_txn = NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00001174
Neal Norwitzb4a55812004-07-09 23:30:57 +00001175 DBTxnObject* self = PyObject_New(DBTxnObject, &DBTxn_Type);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001176 if (self == NULL)
1177 return NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00001178
Gregory P. Smith31c50652004-06-28 01:20:40 +00001179 self->in_weakreflist = NULL;
Gregory P. Smith664782e2008-05-17 06:12:02 +00001180 self->children_txns = NULL;
1181 self->children_dbs = NULL;
1182 self->children_cursors = NULL;
1183 self->children_sequences = NULL;
1184 self->flag_prepare = 0;
1185 self->parent_txn = NULL;
1186 self->env = NULL;
Jesus Cea6557aac2010-03-22 14:22:26 +00001187 /* We initialize just in case "txn_begin" fails */
1188 self->txn = NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001189
Jesus Ceaef9764f2008-05-13 18:45:46 +00001190 if (parent && ((PyObject *)parent!=Py_None)) {
Gregory P. Smith664782e2008-05-17 06:12:02 +00001191 parent_txn = parent->txn;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001192 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00001193
1194 if (txn) {
Gregory P. Smith664782e2008-05-17 06:12:02 +00001195 self->txn = txn;
Jesus Ceaef9764f2008-05-13 18:45:46 +00001196 } else {
1197 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00001198 err = myenv->db_env->txn_begin(myenv->db_env, parent_txn, &(self->txn), flags);
Jesus Ceaef9764f2008-05-13 18:45:46 +00001199 MYDB_END_ALLOW_THREADS;
1200
1201 if (makeDBError(err)) {
Jesus Cea6557aac2010-03-22 14:22:26 +00001202 /* Free object half initialized */
Gregory P. Smith664782e2008-05-17 06:12:02 +00001203 Py_DECREF(self);
Jesus Ceaef9764f2008-05-13 18:45:46 +00001204 return NULL;
1205 }
1206 }
1207
Gregory P. Smith664782e2008-05-17 06:12:02 +00001208 /* Can't use 'parent' because could be 'parent==Py_None' */
1209 if (parent_txn) {
1210 self->parent_txn = parent;
Jesus Ceaef9764f2008-05-13 18:45:46 +00001211 Py_INCREF(parent);
1212 self->env = NULL;
Gregory P. Smith664782e2008-05-17 06:12:02 +00001213 INSERT_IN_DOUBLE_LINKED_LIST(parent->children_txns, self);
Jesus Ceaef9764f2008-05-13 18:45:46 +00001214 } else {
Gregory P. Smith664782e2008-05-17 06:12:02 +00001215 self->parent_txn = NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00001216 Py_INCREF(myenv);
1217 self->env = myenv;
Gregory P. Smith664782e2008-05-17 06:12:02 +00001218 INSERT_IN_DOUBLE_LINKED_LIST(myenv->children_txns, self);
Jesus Ceaef9764f2008-05-13 18:45:46 +00001219 }
1220
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001221 return self;
1222}
1223
Jesus Ceaef9764f2008-05-13 18:45:46 +00001224/* Forward declaration */
1225static PyObject *
1226DBTxn_abort_discard_internal(DBTxnObject* self, int discard);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001227
1228static void
1229DBTxn_dealloc(DBTxnObject* self)
1230{
Jesus Ceaef9764f2008-05-13 18:45:46 +00001231 PyObject *dummy;
1232
1233 if (self->txn) {
1234 int flag_prepare = self->flag_prepare;
Jesus Cea5cd5f122008-09-23 18:54:08 +00001235
Jesus Cea6557aac2010-03-22 14:22:26 +00001236 dummy=DBTxn_abort_discard_internal(self, 0);
Jesus Cea5cd5f122008-09-23 18:54:08 +00001237 /*
1238 ** Raising exceptions while doing
1239 ** garbage collection is a fatal error.
1240 */
1241 if (dummy)
1242 Py_DECREF(dummy);
1243 else
1244 PyErr_Clear();
1245
Jesus Ceaef9764f2008-05-13 18:45:46 +00001246 if (!flag_prepare) {
1247 PyErr_Warn(PyExc_RuntimeWarning,
1248 "DBTxn aborted in destructor. No prior commit() or abort().");
1249 }
1250 }
1251
Gregory P. Smith31c50652004-06-28 01:20:40 +00001252 if (self->in_weakreflist != NULL) {
1253 PyObject_ClearWeakRefs((PyObject *) self);
1254 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001255
Jesus Ceaef9764f2008-05-13 18:45:46 +00001256 if (self->env) {
1257 Py_DECREF(self->env);
1258 } else {
Jesus Cea6557aac2010-03-22 14:22:26 +00001259 /*
1260 ** We can have "self->env==NULL" and "self->parent_txn==NULL"
1261 ** if something happens when creating the transaction object
1262 ** and we abort the object while half done.
1263 */
1264 Py_XDECREF(self->parent_txn);
Gregory P. Smith31c50652004-06-28 01:20:40 +00001265 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001266 PyObject_Del(self);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001267}
1268
1269
1270static DBLockObject*
1271newDBLockObject(DBEnvObject* myenv, u_int32_t locker, DBT* obj,
1272 db_lockmode_t lock_mode, int flags)
1273{
1274 int err;
Neal Norwitzb4a55812004-07-09 23:30:57 +00001275 DBLockObject* self = PyObject_New(DBLockObject, &DBLock_Type);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001276 if (self == NULL)
1277 return NULL;
Gregory P. Smith31c50652004-06-28 01:20:40 +00001278 self->in_weakreflist = NULL;
Jesus Cea6557aac2010-03-22 14:22:26 +00001279 self->lock_initialized = 0; /* Just in case the call fails */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001280
1281 MYDB_BEGIN_ALLOW_THREADS;
Barry Warsaw9a0d7792002-12-30 20:53:52 +00001282 err = myenv->db_env->lock_get(myenv->db_env, locker, flags, obj, lock_mode,
1283 &self->lock);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001284 MYDB_END_ALLOW_THREADS;
1285 if (makeDBError(err)) {
Gregory P. Smith664782e2008-05-17 06:12:02 +00001286 Py_DECREF(self);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001287 self = NULL;
Jesus Cea6557aac2010-03-22 14:22:26 +00001288 } else {
1289 self->lock_initialized = 1;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001290 }
1291
1292 return self;
1293}
1294
1295
1296static void
1297DBLock_dealloc(DBLockObject* self)
1298{
Gregory P. Smith31c50652004-06-28 01:20:40 +00001299 if (self->in_weakreflist != NULL) {
1300 PyObject_ClearWeakRefs((PyObject *) self);
1301 }
Gregory P. Smith31c50652004-06-28 01:20:40 +00001302 /* TODO: is this lock held? should we release it? */
Jesus Cea6557aac2010-03-22 14:22:26 +00001303 /* CAUTION: The lock can be not initialized if the creation has failed */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001304
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001305 PyObject_Del(self);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001306}
1307
1308
Gregory P. Smithf0547d02006-06-05 17:38:04 +00001309static DBSequenceObject*
1310newDBSequenceObject(DBObject* mydb, int flags)
1311{
1312 int err;
1313 DBSequenceObject* self = PyObject_New(DBSequenceObject, &DBSequence_Type);
1314 if (self == NULL)
1315 return NULL;
1316 Py_INCREF(mydb);
1317 self->mydb = mydb;
Gregory P. Smithf0547d02006-06-05 17:38:04 +00001318
Jesus Ceaef9764f2008-05-13 18:45:46 +00001319 INSERT_IN_DOUBLE_LINKED_LIST(self->mydb->children_sequences,self);
Gregory P. Smith664782e2008-05-17 06:12:02 +00001320 self->txn = NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00001321
1322 self->in_weakreflist = NULL;
Jesus Cea6557aac2010-03-22 14:22:26 +00001323 self->sequence = NULL; /* Just in case the call fails */
Gregory P. Smithf0547d02006-06-05 17:38:04 +00001324
1325 MYDB_BEGIN_ALLOW_THREADS;
1326 err = db_sequence_create(&self->sequence, self->mydb->db, flags);
1327 MYDB_END_ALLOW_THREADS;
1328 if (makeDBError(err)) {
Gregory P. Smith664782e2008-05-17 06:12:02 +00001329 Py_DECREF(self);
Gregory P. Smithf0547d02006-06-05 17:38:04 +00001330 self = NULL;
1331 }
1332
1333 return self;
1334}
1335
Jesus Ceaef9764f2008-05-13 18:45:46 +00001336/* Forward declaration */
1337static PyObject
1338*DBSequence_close_internal(DBSequenceObject* self, int flags, int do_not_close);
Gregory P. Smithf0547d02006-06-05 17:38:04 +00001339
1340static void
1341DBSequence_dealloc(DBSequenceObject* self)
1342{
Jesus Ceaef9764f2008-05-13 18:45:46 +00001343 PyObject *dummy;
1344
1345 if (self->sequence != NULL) {
1346 dummy=DBSequence_close_internal(self,0,0);
Jesus Cea5cd5f122008-09-23 18:54:08 +00001347 /*
1348 ** Raising exceptions while doing
1349 ** garbage collection is a fatal error.
1350 */
1351 if (dummy)
1352 Py_DECREF(dummy);
1353 else
1354 PyErr_Clear();
Jesus Ceaef9764f2008-05-13 18:45:46 +00001355 }
1356
Gregory P. Smithf0547d02006-06-05 17:38:04 +00001357 if (self->in_weakreflist != NULL) {
1358 PyObject_ClearWeakRefs((PyObject *) self);
1359 }
Gregory P. Smithf0547d02006-06-05 17:38:04 +00001360
1361 Py_DECREF(self->mydb);
1362 PyObject_Del(self);
1363}
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07001364
1365#if (DBVER >= 52)
1366static DBSiteObject*
1367newDBSiteObject(DB_SITE* sitep, DBEnvObject* env)
1368{
1369 DBSiteObject* self;
1370
1371 self = PyObject_New(DBSiteObject, &DBSite_Type);
1372
1373 if (self == NULL)
1374 return NULL;
1375
1376 self->site = sitep;
1377 self->env = env;
1378
1379 INSERT_IN_DOUBLE_LINKED_LIST(self->env->children_sites, self);
1380
1381 self->in_weakreflist = NULL;
1382 Py_INCREF(self->env);
1383 return self;
1384}
1385
1386/* Forward declaration */
1387static PyObject *DBSite_close_internal(DBSiteObject* self);
1388
1389static void
1390DBSite_dealloc(DBSiteObject* self)
1391{
1392 PyObject *dummy;
1393
1394 if (self->site != NULL) {
1395 dummy = DBSite_close_internal(self);
1396 /*
1397 ** Raising exceptions while doing
1398 ** garbage collection is a fatal error.
1399 */
1400 if (dummy)
1401 Py_DECREF(dummy);
1402 else
1403 PyErr_Clear();
1404 }
1405 if (self->in_weakreflist != NULL) {
1406 PyObject_ClearWeakRefs((PyObject *) self);
1407 }
1408 Py_DECREF(self->env);
1409 PyObject_Del(self);
1410}
Gregory P. Smithf0547d02006-06-05 17:38:04 +00001411#endif
1412
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001413/* --------------------------------------------------------------------- */
1414/* DB methods */
1415
1416static PyObject*
Jesus Cea4907d272008-08-31 14:00:51 +00001417DB_append(DBObject* self, PyObject* args, PyObject* kwargs)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001418{
1419 PyObject* txnobj = NULL;
1420 PyObject* dataobj;
1421 db_recno_t recno;
1422 DBT key, data;
1423 DB_TXN *txn = NULL;
Jesus Cea4907d272008-08-31 14:00:51 +00001424 static char* kwnames[] = { "data", "txn", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001425
Jesus Cea4907d272008-08-31 14:00:51 +00001426 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O:append", kwnames,
1427 &dataobj, &txnobj))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001428 return NULL;
1429
1430 CHECK_DB_NOT_CLOSED(self);
1431
1432 /* make a dummy key out of a recno */
1433 recno = 0;
1434 CLEAR_DBT(key);
1435 key.data = &recno;
1436 key.size = sizeof(recno);
1437 key.ulen = key.size;
1438 key.flags = DB_DBT_USERMEM;
1439
1440 if (!make_dbt(dataobj, &data)) return NULL;
1441 if (!checkTxnObj(txnobj, &txn)) return NULL;
1442
1443 if (-1 == _DB_put(self, txn, &key, &data, DB_APPEND))
1444 return NULL;
1445
Jesus Ceac5a11fa2008-07-23 11:38:42 +00001446 return NUMBER_FromLong(recno);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001447}
1448
1449
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001450static int
Barry Warsaw9a0d7792002-12-30 20:53:52 +00001451_db_associateCallback(DB* db, const DBT* priKey, const DBT* priData,
1452 DBT* secKey)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001453{
1454 int retval = DB_DONOTINDEX;
1455 DBObject* secondaryDB = (DBObject*)db->app_private;
1456 PyObject* callback = secondaryDB->associateCallback;
1457 int type = secondaryDB->primaryDBType;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001458 PyObject* args;
Thomas Wouters89ba3812006-03-07 14:14:51 +00001459 PyObject* result = NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001460
1461
1462 if (callback != NULL) {
1463 MYDB_BEGIN_BLOCK_THREADS;
1464
Thomas Woutersb3153832006-03-08 01:47:19 +00001465 if (type == DB_RECNO || type == DB_QUEUE)
Jesus Ceaef9764f2008-05-13 18:45:46 +00001466 args = BuildValue_LS(*((db_recno_t*)priKey->data), priData->data, priData->size);
Thomas Woutersb3153832006-03-08 01:47:19 +00001467 else
Jesus Ceaef9764f2008-05-13 18:45:46 +00001468 args = BuildValue_SS(priKey->data, priKey->size, priData->data, priData->size);
Thomas Wouters098f6942006-03-07 14:13:17 +00001469 if (args != NULL) {
Thomas Wouters098f6942006-03-07 14:13:17 +00001470 result = PyEval_CallObject(callback, args);
1471 }
1472 if (args == NULL || result == NULL) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001473 PyErr_Print();
1474 }
1475 else if (result == Py_None) {
1476 retval = DB_DONOTINDEX;
1477 }
Jesus Ceac5a11fa2008-07-23 11:38:42 +00001478 else if (NUMBER_Check(result)) {
1479 retval = NUMBER_AsLong(result);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001480 }
Christian Heimes593daf52008-05-26 12:51:38 +00001481 else if (PyBytes_Check(result)) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001482 char* data;
Martin v. Löwis18e16552006-02-15 17:27:45 +00001483 Py_ssize_t size;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001484
1485 CLEAR_DBT(*secKey);
Christian Heimes593daf52008-05-26 12:51:38 +00001486 PyBytes_AsStringAndSize(result, &data, &size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001487 secKey->flags = DB_DBT_APPMALLOC; /* DB will free */
1488 secKey->data = malloc(size); /* TODO, check this */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001489 if (secKey->data) {
1490 memcpy(secKey->data, data, size);
1491 secKey->size = size;
1492 retval = 0;
1493 }
1494 else {
1495 PyErr_SetString(PyExc_MemoryError,
Barry Warsaw9a0d7792002-12-30 20:53:52 +00001496 "malloc failed in _db_associateCallback");
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001497 PyErr_Print();
1498 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001499 }
Jesus Cea6557aac2010-03-22 14:22:26 +00001500#if (DBVER >= 46)
1501 else if (PyList_Check(result))
1502 {
1503 char* data;
1504 Py_ssize_t size;
1505 int i, listlen;
1506 DBT* dbts;
1507
1508 listlen = PyList_Size(result);
1509
1510 dbts = (DBT *)malloc(sizeof(DBT) * listlen);
1511
1512 for (i=0; i<listlen; i++)
1513 {
1514 if (!PyBytes_Check(PyList_GetItem(result, i)))
1515 {
1516 PyErr_SetString(
1517 PyExc_TypeError,
1518#if (PY_VERSION_HEX < 0x03000000)
1519"The list returned by DB->associate callback should be a list of strings.");
1520#else
1521"The list returned by DB->associate callback should be a list of bytes.");
1522#endif
1523 PyErr_Print();
1524 }
1525
1526 PyBytes_AsStringAndSize(
1527 PyList_GetItem(result, i),
1528 &data, &size);
1529
1530 CLEAR_DBT(dbts[i]);
1531 dbts[i].data = malloc(size); /* TODO, check this */
1532
1533 if (dbts[i].data)
1534 {
1535 memcpy(dbts[i].data, data, size);
1536 dbts[i].size = size;
1537 dbts[i].ulen = dbts[i].size;
1538 dbts[i].flags = DB_DBT_APPMALLOC; /* DB will free */
1539 }
1540 else
1541 {
1542 PyErr_SetString(PyExc_MemoryError,
1543 "malloc failed in _db_associateCallback (list)");
1544 PyErr_Print();
1545 }
1546 }
1547
1548 CLEAR_DBT(*secKey);
1549
1550 secKey->data = dbts;
1551 secKey->size = listlen;
1552 secKey->flags = DB_DBT_APPMALLOC | DB_DBT_MULTIPLE;
1553 retval = 0;
1554 }
1555#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001556 else {
Barry Warsaw9a0d7792002-12-30 20:53:52 +00001557 PyErr_SetString(
1558 PyExc_TypeError,
Jesus Cea6557aac2010-03-22 14:22:26 +00001559#if (PY_VERSION_HEX < 0x03000000)
1560"DB associate callback should return DB_DONOTINDEX/string/list of strings.");
1561#else
1562"DB associate callback should return DB_DONOTINDEX/bytes/list of bytes.");
1563#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001564 PyErr_Print();
1565 }
1566
Thomas Woutersb3153832006-03-08 01:47:19 +00001567 Py_XDECREF(args);
1568 Py_XDECREF(result);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001569
1570 MYDB_END_BLOCK_THREADS;
1571 }
1572 return retval;
1573}
1574
1575
1576static PyObject*
1577DB_associate(DBObject* self, PyObject* args, PyObject* kwargs)
1578{
1579 int err, flags=0;
1580 DBObject* secondaryDB;
1581 PyObject* callback;
Barry Warsaw9a0d7792002-12-30 20:53:52 +00001582 PyObject *txnobj = NULL;
1583 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00001584 static char* kwnames[] = {"secondaryDB", "callback", "flags", "txn",
Jeremy Hyltonaf68c872005-12-10 18:50:16 +00001585 NULL};
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001586
Barry Warsaw9a0d7792002-12-30 20:53:52 +00001587 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|iO:associate", kwnames,
1588 &secondaryDB, &callback, &flags,
1589 &txnobj)) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001590 return NULL;
Barry Warsaw9a0d7792002-12-30 20:53:52 +00001591 }
1592
Barry Warsaw9a0d7792002-12-30 20:53:52 +00001593 if (!checkTxnObj(txnobj, &txn)) return NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001594
1595 CHECK_DB_NOT_CLOSED(self);
1596 if (!DBObject_Check(secondaryDB)) {
1597 makeTypeError("DB", (PyObject*)secondaryDB);
1598 return NULL;
1599 }
Gregory P. Smith91116b62005-06-06 10:28:06 +00001600 CHECK_DB_NOT_CLOSED(secondaryDB);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001601 if (callback == Py_None) {
1602 callback = NULL;
1603 }
1604 else if (!PyCallable_Check(callback)) {
1605 makeTypeError("Callable", callback);
1606 return NULL;
1607 }
1608
1609 /* Save a reference to the callback in the secondary DB. */
Gregory P. Smith692ca9a2005-06-06 09:55:06 +00001610 Py_XDECREF(secondaryDB->associateCallback);
Thomas Woutersb3153832006-03-08 01:47:19 +00001611 Py_XINCREF(callback);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001612 secondaryDB->associateCallback = callback;
1613 secondaryDB->primaryDBType = _DB_get_type(self);
1614
Martin v. Löwisb2c7aff2002-11-23 11:26:07 +00001615 /* PyEval_InitThreads is called here due to a quirk in python 1.5
1616 * - 2.2.1 (at least) according to Russell Williamson <merel@wt.net>:
1617 * The global interepreter lock is not initialized until the first
1618 * thread is created using thread.start_new_thread() or fork() is
1619 * called. that would cause the ALLOW_THREADS here to segfault due
1620 * to a null pointer reference if no threads or child processes
1621 * have been created. This works around that and is a no-op if
1622 * threads have already been initialized.
1623 * (see pybsddb-users mailing list post on 2002-08-07)
1624 */
Gregory P. Smithaa71f5f2003-01-17 07:56:16 +00001625#ifdef WITH_THREAD
Martin v. Löwisb2c7aff2002-11-23 11:26:07 +00001626 PyEval_InitThreads();
Gregory P. Smithaa71f5f2003-01-17 07:56:16 +00001627#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001628 MYDB_BEGIN_ALLOW_THREADS;
Barry Warsaw9a0d7792002-12-30 20:53:52 +00001629 err = self->db->associate(self->db,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001630 txn,
Barry Warsaw9a0d7792002-12-30 20:53:52 +00001631 secondaryDB->db,
1632 _db_associateCallback,
1633 flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001634 MYDB_END_ALLOW_THREADS;
1635
1636 if (err) {
Serhiy Storchaka98a97222014-02-09 13:14:04 +02001637 Py_CLEAR(secondaryDB->associateCallback);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001638 secondaryDB->primaryDBType = 0;
1639 }
1640
1641 RETURN_IF_ERR();
1642 RETURN_NONE();
1643}
1644
1645
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001646static PyObject*
Jesus Cea5cd5f122008-09-23 18:54:08 +00001647DB_close_internal(DBObject* self, int flags, int do_not_close)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001648{
Jesus Ceaef9764f2008-05-13 18:45:46 +00001649 PyObject *dummy;
Jesus Cea5cd5f122008-09-23 18:54:08 +00001650 int err = 0;
Jesus Ceaef9764f2008-05-13 18:45:46 +00001651
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001652 if (self->db != NULL) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00001653 /* Can be NULL if db is not in an environment */
1654 EXTRACT_FROM_DOUBLE_LINKED_LIST_MAYBE_NULL(self);
Jesus Cea4907d272008-08-31 14:00:51 +00001655
Jesus Ceaef9764f2008-05-13 18:45:46 +00001656 if (self->txn) {
1657 EXTRACT_FROM_DOUBLE_LINKED_LIST_TXN(self);
1658 self->txn=NULL;
1659 }
1660
1661 while(self->children_cursors) {
1662 dummy=DBC_close_internal(self->children_cursors);
1663 Py_XDECREF(dummy);
1664 }
1665
Jesus Ceaef9764f2008-05-13 18:45:46 +00001666 while(self->children_sequences) {
1667 dummy=DBSequence_close_internal(self->children_sequences,0,0);
1668 Py_XDECREF(dummy);
1669 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00001670
Jesus Cea5cd5f122008-09-23 18:54:08 +00001671 /*
1672 ** "do_not_close" is used to dispose all related objects in the
1673 ** tree, without actually releasing the "root" object.
1674 ** This is done, for example, because function calls like
1675 ** "DB.verify()" implicitly close the underlying handle. So
1676 ** the handle doesn't need to be closed, but related objects
1677 ** must be cleaned up.
1678 */
1679 if (!do_not_close) {
1680 MYDB_BEGIN_ALLOW_THREADS;
1681 err = self->db->close(self->db, flags);
1682 MYDB_END_ALLOW_THREADS;
1683 self->db = NULL;
1684 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001685 RETURN_IF_ERR();
1686 }
1687 RETURN_NONE();
1688}
1689
Jesus Ceaef9764f2008-05-13 18:45:46 +00001690static PyObject*
1691DB_close(DBObject* self, PyObject* args)
1692{
1693 int flags=0;
1694 if (!PyArg_ParseTuple(args,"|i:close", &flags))
1695 return NULL;
Jesus Cea5cd5f122008-09-23 18:54:08 +00001696 return DB_close_internal(self, flags, 0);
Jesus Ceaef9764f2008-05-13 18:45:46 +00001697}
1698
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001699
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001700static PyObject*
1701_DB_consume(DBObject* self, PyObject* args, PyObject* kwargs, int consume_flag)
1702{
1703 int err, flags=0, type;
1704 PyObject* txnobj = NULL;
1705 PyObject* retval = NULL;
1706 DBT key, data;
1707 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00001708 static char* kwnames[] = { "txn", "flags", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001709
1710 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Oi:consume", kwnames,
1711 &txnobj, &flags))
1712 return NULL;
1713
1714 CHECK_DB_NOT_CLOSED(self);
1715 type = _DB_get_type(self);
1716 if (type == -1)
1717 return NULL;
1718 if (type != DB_QUEUE) {
Barry Warsaw9a0d7792002-12-30 20:53:52 +00001719 PyErr_SetString(PyExc_TypeError,
1720 "Consume methods only allowed for Queue DB's");
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001721 return NULL;
1722 }
1723 if (!checkTxnObj(txnobj, &txn))
1724 return NULL;
1725
1726 CLEAR_DBT(key);
1727 CLEAR_DBT(data);
1728 if (CHECK_DBFLAG(self, DB_THREAD)) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00001729 /* Tell Berkeley DB to malloc the return value (thread safe) */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001730 data.flags = DB_DBT_MALLOC;
1731 key.flags = DB_DBT_MALLOC;
1732 }
1733
1734 MYDB_BEGIN_ALLOW_THREADS;
1735 err = self->db->get(self->db, txn, &key, &data, flags|consume_flag);
1736 MYDB_END_ALLOW_THREADS;
1737
Gregory P. Smithe9477062005-06-04 06:46:59 +00001738 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001739 && self->moduleFlags.getReturnsNone) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001740 err = 0;
1741 Py_INCREF(Py_None);
1742 retval = Py_None;
1743 }
1744 else if (!err) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00001745 retval = BuildValue_SS(key.data, key.size, data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001746 FREE_DBT(key);
1747 FREE_DBT(data);
1748 }
1749
1750 RETURN_IF_ERR();
1751 return retval;
1752}
1753
1754static PyObject*
1755DB_consume(DBObject* self, PyObject* args, PyObject* kwargs, int consume_flag)
1756{
1757 return _DB_consume(self, args, kwargs, DB_CONSUME);
1758}
1759
1760static PyObject*
Barry Warsaw9a0d7792002-12-30 20:53:52 +00001761DB_consume_wait(DBObject* self, PyObject* args, PyObject* kwargs,
1762 int consume_flag)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001763{
1764 return _DB_consume(self, args, kwargs, DB_CONSUME_WAIT);
1765}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001766
1767
1768static PyObject*
1769DB_cursor(DBObject* self, PyObject* args, PyObject* kwargs)
1770{
1771 int err, flags=0;
1772 DBC* dbc;
1773 PyObject* txnobj = NULL;
1774 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00001775 static char* kwnames[] = { "txn", "flags", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001776
1777 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Oi:cursor", kwnames,
1778 &txnobj, &flags))
1779 return NULL;
1780 CHECK_DB_NOT_CLOSED(self);
1781 if (!checkTxnObj(txnobj, &txn))
1782 return NULL;
1783
1784 MYDB_BEGIN_ALLOW_THREADS;
1785 err = self->db->cursor(self->db, txn, &dbc, flags);
1786 MYDB_END_ALLOW_THREADS;
1787 RETURN_IF_ERR();
Jesus Ceaef9764f2008-05-13 18:45:46 +00001788 return (PyObject*) newDBCursorObject(dbc, (DBTxnObject *)txnobj, self);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001789}
1790
1791
1792static PyObject*
1793DB_delete(DBObject* self, PyObject* args, PyObject* kwargs)
1794{
1795 PyObject* txnobj = NULL;
1796 int flags = 0;
1797 PyObject* keyobj;
1798 DBT key;
1799 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00001800 static char* kwnames[] = { "key", "txn", "flags", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001801
1802 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|Oi:delete", kwnames,
1803 &keyobj, &txnobj, &flags))
1804 return NULL;
1805 CHECK_DB_NOT_CLOSED(self);
1806 if (!make_key_dbt(self, keyobj, &key, NULL))
1807 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00001808 if (!checkTxnObj(txnobj, &txn)) {
1809 FREE_DBT(key);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001810 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00001811 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001812
Gregory P. Smithdc5af702004-06-27 23:32:34 +00001813 if (-1 == _DB_delete(self, txn, &key, 0)) {
1814 FREE_DBT(key);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001815 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00001816 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001817
1818 FREE_DBT(key);
1819 RETURN_NONE();
1820}
1821
1822
Jesus Cea6557aac2010-03-22 14:22:26 +00001823#if (DBVER >= 47)
1824/*
1825** This function is available since Berkeley DB 4.4,
1826** but 4.6 version is so buggy that we only support
1827** it from BDB 4.7 and newer.
1828*/
1829static PyObject*
1830DB_compact(DBObject* self, PyObject* args, PyObject* kwargs)
1831{
1832 PyObject* txnobj = NULL;
1833 PyObject *startobj = NULL, *stopobj = NULL;
1834 int flags = 0;
1835 DB_TXN *txn = NULL;
1836 DBT *start_p = NULL, *stop_p = NULL;
1837 DBT start, stop;
1838 int err;
1839 DB_COMPACT c_data = { 0 };
1840 static char* kwnames[] = { "txn", "start", "stop", "flags",
1841 "compact_fillpercent", "compact_pages",
1842 "compact_timeout", NULL };
1843
1844
1845 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OOOiiiI:compact", kwnames,
1846 &txnobj, &startobj, &stopobj, &flags,
1847 &c_data.compact_fillpercent,
1848 &c_data.compact_pages,
1849 &c_data.compact_timeout))
1850 return NULL;
1851
1852 CHECK_DB_NOT_CLOSED(self);
1853 if (!checkTxnObj(txnobj, &txn)) {
1854 return NULL;
1855 }
1856
1857 if (startobj && make_key_dbt(self, startobj, &start, NULL)) {
1858 start_p = &start;
1859 }
1860 if (stopobj && make_key_dbt(self, stopobj, &stop, NULL)) {
1861 stop_p = &stop;
1862 }
1863
1864 MYDB_BEGIN_ALLOW_THREADS;
1865 err = self->db->compact(self->db, txn, start_p, stop_p, &c_data,
1866 flags, NULL);
1867 MYDB_END_ALLOW_THREADS;
1868
1869 if (startobj)
1870 FREE_DBT(start);
1871 if (stopobj)
1872 FREE_DBT(stop);
1873
1874 RETURN_IF_ERR();
1875
1876 return PyLong_FromUnsignedLong(c_data.compact_pages_truncated);
1877}
1878#endif
1879
1880
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001881static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00001882DB_fd(DBObject* self)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001883{
1884 int err, the_fd;
1885
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001886 CHECK_DB_NOT_CLOSED(self);
1887
1888 MYDB_BEGIN_ALLOW_THREADS;
1889 err = self->db->fd(self->db, &the_fd);
1890 MYDB_END_ALLOW_THREADS;
1891 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00001892 return NUMBER_FromLong(the_fd);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001893}
1894
1895
Jesus Cea6557aac2010-03-22 14:22:26 +00001896#if (DBVER >= 46)
1897static PyObject*
1898DB_exists(DBObject* self, PyObject* args, PyObject* kwargs)
1899{
1900 int err, flags=0;
1901 PyObject* txnobj = NULL;
1902 PyObject* keyobj;
1903 DBT key;
1904 DB_TXN *txn;
1905
1906 static char* kwnames[] = {"key", "txn", "flags", NULL};
1907
1908 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|Oi:exists", kwnames,
1909 &keyobj, &txnobj, &flags))
1910 return NULL;
1911
1912 CHECK_DB_NOT_CLOSED(self);
1913 if (!make_key_dbt(self, keyobj, &key, NULL))
1914 return NULL;
1915 if (!checkTxnObj(txnobj, &txn)) {
1916 FREE_DBT(key);
1917 return NULL;
1918 }
1919
1920 MYDB_BEGIN_ALLOW_THREADS;
1921 err = self->db->exists(self->db, txn, &key, flags);
1922 MYDB_END_ALLOW_THREADS;
1923
1924 FREE_DBT(key);
1925
1926 if (!err) {
1927 Py_INCREF(Py_True);
1928 return Py_True;
1929 }
1930 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)) {
1931 Py_INCREF(Py_False);
1932 return Py_False;
1933 }
1934
1935 /*
1936 ** If we reach there, there was an error. The
1937 ** "return" should be unreachable.
1938 */
1939 RETURN_IF_ERR();
1940 assert(0); /* This coude SHOULD be unreachable */
1941 return NULL;
1942}
1943#endif
1944
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001945static PyObject*
1946DB_get(DBObject* self, PyObject* args, PyObject* kwargs)
1947{
1948 int err, flags=0;
1949 PyObject* txnobj = NULL;
1950 PyObject* keyobj;
1951 PyObject* dfltobj = NULL;
1952 PyObject* retval = NULL;
1953 int dlen = -1;
1954 int doff = -1;
1955 DBT key, data;
1956 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00001957 static char* kwnames[] = {"key", "default", "txn", "flags", "dlen",
Jeremy Hyltonaf68c872005-12-10 18:50:16 +00001958 "doff", NULL};
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001959
1960 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|OOiii:get", kwnames,
Barry Warsaw9a0d7792002-12-30 20:53:52 +00001961 &keyobj, &dfltobj, &txnobj, &flags, &dlen,
1962 &doff))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001963 return NULL;
1964
1965 CHECK_DB_NOT_CLOSED(self);
1966 if (!make_key_dbt(self, keyobj, &key, &flags))
1967 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00001968 if (!checkTxnObj(txnobj, &txn)) {
1969 FREE_DBT(key);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001970 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00001971 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001972
1973 CLEAR_DBT(data);
1974 if (CHECK_DBFLAG(self, DB_THREAD)) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00001975 /* Tell Berkeley DB to malloc the return value (thread safe) */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001976 data.flags = DB_DBT_MALLOC;
1977 }
Gregory P. Smithdc5af702004-06-27 23:32:34 +00001978 if (!add_partial_dbt(&data, dlen, doff)) {
1979 FREE_DBT(key);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001980 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00001981 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001982
1983 MYDB_BEGIN_ALLOW_THREADS;
1984 err = self->db->get(self->db, txn, &key, &data, flags);
1985 MYDB_END_ALLOW_THREADS;
1986
Gregory P. Smithe9477062005-06-04 06:46:59 +00001987 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY) && (dfltobj != NULL)) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001988 err = 0;
1989 Py_INCREF(dfltobj);
1990 retval = dfltobj;
1991 }
Gregory P. Smithe9477062005-06-04 06:46:59 +00001992 else if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001993 && self->moduleFlags.getReturnsNone) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001994 err = 0;
1995 Py_INCREF(Py_None);
1996 retval = Py_None;
1997 }
1998 else if (!err) {
1999 if (flags & DB_SET_RECNO) /* return both key and data */
Jesus Ceaef9764f2008-05-13 18:45:46 +00002000 retval = BuildValue_SS(key.data, key.size, data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002001 else /* return just the data */
Jesus Ceaef9764f2008-05-13 18:45:46 +00002002 retval = Build_PyString(data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002003 FREE_DBT(data);
2004 }
Gregory P. Smithdc5af702004-06-27 23:32:34 +00002005 FREE_DBT(key);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002006
2007 RETURN_IF_ERR();
2008 return retval;
2009}
2010
Gregory P. Smith19699a92004-06-28 04:06:49 +00002011static PyObject*
2012DB_pget(DBObject* self, PyObject* args, PyObject* kwargs)
2013{
2014 int err, flags=0;
2015 PyObject* txnobj = NULL;
2016 PyObject* keyobj;
2017 PyObject* dfltobj = NULL;
2018 PyObject* retval = NULL;
2019 int dlen = -1;
2020 int doff = -1;
2021 DBT key, pkey, data;
2022 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002023 static char* kwnames[] = {"key", "default", "txn", "flags", "dlen",
Jeremy Hyltonaf68c872005-12-10 18:50:16 +00002024 "doff", NULL};
Gregory P. Smith19699a92004-06-28 04:06:49 +00002025
2026 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|OOiii:pget", kwnames,
2027 &keyobj, &dfltobj, &txnobj, &flags, &dlen,
2028 &doff))
2029 return NULL;
2030
2031 CHECK_DB_NOT_CLOSED(self);
2032 if (!make_key_dbt(self, keyobj, &key, &flags))
2033 return NULL;
2034 if (!checkTxnObj(txnobj, &txn)) {
2035 FREE_DBT(key);
2036 return NULL;
2037 }
2038
2039 CLEAR_DBT(data);
2040 if (CHECK_DBFLAG(self, DB_THREAD)) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00002041 /* Tell Berkeley DB to malloc the return value (thread safe) */
Gregory P. Smith19699a92004-06-28 04:06:49 +00002042 data.flags = DB_DBT_MALLOC;
2043 }
2044 if (!add_partial_dbt(&data, dlen, doff)) {
2045 FREE_DBT(key);
2046 return NULL;
2047 }
2048
2049 CLEAR_DBT(pkey);
2050 pkey.flags = DB_DBT_MALLOC;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002051
Gregory P. Smith19699a92004-06-28 04:06:49 +00002052 MYDB_BEGIN_ALLOW_THREADS;
2053 err = self->db->pget(self->db, txn, &key, &pkey, &data, flags);
2054 MYDB_END_ALLOW_THREADS;
2055
Gregory P. Smithe9477062005-06-04 06:46:59 +00002056 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY) && (dfltobj != NULL)) {
Gregory P. Smith19699a92004-06-28 04:06:49 +00002057 err = 0;
2058 Py_INCREF(dfltobj);
2059 retval = dfltobj;
2060 }
Gregory P. Smithe9477062005-06-04 06:46:59 +00002061 else if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002062 && self->moduleFlags.getReturnsNone) {
Gregory P. Smith19699a92004-06-28 04:06:49 +00002063 err = 0;
2064 Py_INCREF(Py_None);
2065 retval = Py_None;
2066 }
2067 else if (!err) {
2068 PyObject *pkeyObj;
2069 PyObject *dataObj;
Jesus Ceaef9764f2008-05-13 18:45:46 +00002070 dataObj = Build_PyString(data.data, data.size);
Gregory P. Smith19699a92004-06-28 04:06:49 +00002071
2072 if (self->primaryDBType == DB_RECNO ||
2073 self->primaryDBType == DB_QUEUE)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002074 pkeyObj = NUMBER_FromLong(*(int *)pkey.data);
Gregory P. Smith19699a92004-06-28 04:06:49 +00002075 else
Jesus Ceaef9764f2008-05-13 18:45:46 +00002076 pkeyObj = Build_PyString(pkey.data, pkey.size);
Gregory P. Smith19699a92004-06-28 04:06:49 +00002077
2078 if (flags & DB_SET_RECNO) /* return key , pkey and data */
2079 {
2080 PyObject *keyObj;
2081 int type = _DB_get_type(self);
2082 if (type == DB_RECNO || type == DB_QUEUE)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002083 keyObj = NUMBER_FromLong(*(int *)key.data);
Gregory P. Smith19699a92004-06-28 04:06:49 +00002084 else
Jesus Ceaef9764f2008-05-13 18:45:46 +00002085 keyObj = Build_PyString(key.data, key.size);
Gregory P. Smith4e414d82006-01-24 19:55:02 +00002086 retval = PyTuple_Pack(3, keyObj, pkeyObj, dataObj);
Thomas Woutersb3153832006-03-08 01:47:19 +00002087 Py_DECREF(keyObj);
Gregory P. Smith19699a92004-06-28 04:06:49 +00002088 }
2089 else /* return just the pkey and data */
2090 {
Gregory P. Smith4e414d82006-01-24 19:55:02 +00002091 retval = PyTuple_Pack(2, pkeyObj, dataObj);
Gregory P. Smith19699a92004-06-28 04:06:49 +00002092 }
Thomas Woutersb3153832006-03-08 01:47:19 +00002093 Py_DECREF(dataObj);
2094 Py_DECREF(pkeyObj);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002095 FREE_DBT(pkey);
Gregory P. Smith19699a92004-06-28 04:06:49 +00002096 FREE_DBT(data);
2097 }
2098 FREE_DBT(key);
2099
2100 RETURN_IF_ERR();
2101 return retval;
2102}
2103
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002104
2105/* Return size of entry */
2106static PyObject*
2107DB_get_size(DBObject* self, PyObject* args, PyObject* kwargs)
2108{
2109 int err, flags=0;
2110 PyObject* txnobj = NULL;
2111 PyObject* keyobj;
2112 PyObject* retval = NULL;
2113 DBT key, data;
2114 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002115 static char* kwnames[] = { "key", "txn", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002116
2117 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O:get_size", kwnames,
2118 &keyobj, &txnobj))
2119 return NULL;
2120 CHECK_DB_NOT_CLOSED(self);
2121 if (!make_key_dbt(self, keyobj, &key, &flags))
2122 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00002123 if (!checkTxnObj(txnobj, &txn)) {
2124 FREE_DBT(key);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002125 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00002126 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002127 CLEAR_DBT(data);
2128
Gregory P. Smith8b7e9172004-12-13 09:51:23 +00002129 /* We don't allocate any memory, forcing a DB_BUFFER_SMALL error and
2130 thus getting the record size. */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002131 data.flags = DB_DBT_USERMEM;
2132 data.ulen = 0;
2133 MYDB_BEGIN_ALLOW_THREADS;
2134 err = self->db->get(self->db, txn, &key, &data, flags);
2135 MYDB_END_ALLOW_THREADS;
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07002136 if ((err == DB_BUFFER_SMALL) || (err == 0)) {
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002137 retval = NUMBER_FromLong((long)data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002138 err = 0;
2139 }
2140
2141 FREE_DBT(key);
2142 FREE_DBT(data);
2143 RETURN_IF_ERR();
2144 return retval;
2145}
2146
2147
2148static PyObject*
2149DB_get_both(DBObject* self, PyObject* args, PyObject* kwargs)
2150{
2151 int err, flags=0;
2152 PyObject* txnobj = NULL;
2153 PyObject* keyobj;
2154 PyObject* dataobj;
2155 PyObject* retval = NULL;
2156 DBT key, data;
Neal Norwitz994ebed2007-06-03 20:32:50 +00002157 void *orig_data;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002158 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002159 static char* kwnames[] = { "key", "data", "txn", "flags", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002160
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002161 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|Oi:get_both", kwnames,
2162 &keyobj, &dataobj, &txnobj, &flags))
2163 return NULL;
2164
2165 CHECK_DB_NOT_CLOSED(self);
2166 if (!make_key_dbt(self, keyobj, &key, NULL))
2167 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00002168 if ( !make_dbt(dataobj, &data) ||
2169 !checkTxnObj(txnobj, &txn) )
2170 {
2171 FREE_DBT(key);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002172 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00002173 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002174
2175 flags |= DB_GET_BOTH;
Neal Norwitz994ebed2007-06-03 20:32:50 +00002176 orig_data = data.data;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002177
2178 if (CHECK_DBFLAG(self, DB_THREAD)) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00002179 /* Tell Berkeley DB to malloc the return value (thread safe) */
Neal Norwitz994ebed2007-06-03 20:32:50 +00002180 /* XXX(nnorwitz): At least 4.4.20 and 4.5.20 require this flag. */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002181 data.flags = DB_DBT_MALLOC;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002182 }
2183
2184 MYDB_BEGIN_ALLOW_THREADS;
2185 err = self->db->get(self->db, txn, &key, &data, flags);
2186 MYDB_END_ALLOW_THREADS;
2187
Gregory P. Smithe9477062005-06-04 06:46:59 +00002188 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002189 && self->moduleFlags.getReturnsNone) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002190 err = 0;
2191 Py_INCREF(Py_None);
2192 retval = Py_None;
2193 }
2194 else if (!err) {
Neal Norwitz994ebed2007-06-03 20:32:50 +00002195 /* XXX(nnorwitz): can we do: retval = dataobj; Py_INCREF(retval); */
Jesus Ceaef9764f2008-05-13 18:45:46 +00002196 retval = Build_PyString(data.data, data.size);
Neal Norwitz994ebed2007-06-03 20:32:50 +00002197
2198 /* Even though the flags require DB_DBT_MALLOC, data is not always
2199 allocated. 4.4: allocated, 4.5: *not* allocated. :-( */
2200 if (data.data != orig_data)
2201 FREE_DBT(data);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002202 }
2203
2204 FREE_DBT(key);
2205 RETURN_IF_ERR();
2206 return retval;
2207}
2208
2209
2210static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002211DB_get_byteswapped(DBObject* self)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002212{
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002213 int err = 0;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002214 int retval = -1;
2215
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002216 CHECK_DB_NOT_CLOSED(self);
2217
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002218 MYDB_BEGIN_ALLOW_THREADS;
2219 err = self->db->get_byteswapped(self->db, &retval);
2220 MYDB_END_ALLOW_THREADS;
2221 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002222 return NUMBER_FromLong(retval);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002223}
2224
2225
2226static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002227DB_get_type(DBObject* self)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002228{
2229 int type;
2230
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002231 CHECK_DB_NOT_CLOSED(self);
2232
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002233 type = _DB_get_type(self);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002234 if (type == -1)
2235 return NULL;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002236 return NUMBER_FromLong(type);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002237}
2238
2239
2240static PyObject*
2241DB_join(DBObject* self, PyObject* args)
2242{
2243 int err, flags=0;
2244 int length, x;
2245 PyObject* cursorsObj;
2246 DBC** cursors;
2247 DBC* dbc;
2248
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002249 if (!PyArg_ParseTuple(args,"O|i:join", &cursorsObj, &flags))
2250 return NULL;
2251
2252 CHECK_DB_NOT_CLOSED(self);
2253
2254 if (!PySequence_Check(cursorsObj)) {
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002255 PyErr_SetString(PyExc_TypeError,
2256 "Sequence of DBCursor objects expected");
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002257 return NULL;
2258 }
2259
2260 length = PyObject_Length(cursorsObj);
2261 cursors = malloc((length+1) * sizeof(DBC*));
Neal Norwitz5aa96892006-08-13 18:11:43 +00002262 if (!cursors) {
Jesus Cea6557aac2010-03-22 14:22:26 +00002263 PyErr_NoMemory();
2264 return NULL;
Neal Norwitz5aa96892006-08-13 18:11:43 +00002265 }
2266
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002267 cursors[length] = NULL;
2268 for (x=0; x<length; x++) {
2269 PyObject* item = PySequence_GetItem(cursorsObj, x);
Thomas Woutersb3153832006-03-08 01:47:19 +00002270 if (item == NULL) {
2271 free(cursors);
2272 return NULL;
2273 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002274 if (!DBCursorObject_Check(item)) {
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002275 PyErr_SetString(PyExc_TypeError,
2276 "Sequence of DBCursor objects expected");
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002277 free(cursors);
2278 return NULL;
2279 }
2280 cursors[x] = ((DBCursorObject*)item)->dbc;
Thomas Woutersb2820ae2006-03-12 00:01:38 +00002281 Py_DECREF(item);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002282 }
2283
2284 MYDB_BEGIN_ALLOW_THREADS;
2285 err = self->db->join(self->db, cursors, &dbc, flags);
2286 MYDB_END_ALLOW_THREADS;
2287 free(cursors);
2288 RETURN_IF_ERR();
2289
Gregory P. Smith7441e652003-11-03 21:35:31 +00002290 /* FIXME: this is a buggy interface. The returned cursor
2291 contains internal references to the passed in cursors
2292 but does not hold python references to them or prevent
2293 them from being closed prematurely. This can cause
2294 python to crash when things are done in the wrong order. */
Jesus Ceaef9764f2008-05-13 18:45:46 +00002295 return (PyObject*) newDBCursorObject(dbc, NULL, self);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002296}
2297
2298
2299static PyObject*
2300DB_key_range(DBObject* self, PyObject* args, PyObject* kwargs)
2301{
2302 int err, flags=0;
2303 PyObject* txnobj = NULL;
2304 PyObject* keyobj;
2305 DBT key;
2306 DB_TXN *txn = NULL;
2307 DB_KEY_RANGE range;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002308 static char* kwnames[] = { "key", "txn", "flags", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002309
2310 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|Oi:key_range", kwnames,
2311 &keyobj, &txnobj, &flags))
2312 return NULL;
2313 CHECK_DB_NOT_CLOSED(self);
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002314 if (!make_dbt(keyobj, &key))
2315 /* BTree only, don't need to allow for an int key */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002316 return NULL;
2317 if (!checkTxnObj(txnobj, &txn))
2318 return NULL;
2319
2320 MYDB_BEGIN_ALLOW_THREADS;
2321 err = self->db->key_range(self->db, txn, &key, &range, flags);
2322 MYDB_END_ALLOW_THREADS;
2323
2324 RETURN_IF_ERR();
2325 return Py_BuildValue("ddd", range.less, range.equal, range.greater);
2326}
2327
2328
2329static PyObject*
2330DB_open(DBObject* self, PyObject* args, PyObject* kwargs)
2331{
2332 int err, type = DB_UNKNOWN, flags=0, mode=0660;
2333 char* filename = NULL;
2334 char* dbname = NULL;
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002335 PyObject *txnobj = NULL;
2336 DB_TXN *txn = NULL;
2337 /* with dbname */
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002338 static char* kwnames[] = {
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002339 "filename", "dbname", "dbtype", "flags", "mode", "txn", NULL};
2340 /* without dbname */
Tim Peters85b10522006-02-28 18:33:35 +00002341 static char* kwnames_basic[] = {
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002342 "filename", "dbtype", "flags", "mode", "txn", NULL};
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002343
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002344 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "z|ziiiO:open", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002345 &filename, &dbname, &type, &flags, &mode,
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002346 &txnobj))
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002347 {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002348 PyErr_Clear();
2349 type = DB_UNKNOWN; flags = 0; mode = 0660;
2350 filename = NULL; dbname = NULL;
2351 if (!PyArg_ParseTupleAndKeywords(args, kwargs,"z|iiiO:open",
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002352 kwnames_basic,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002353 &filename, &type, &flags, &mode,
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002354 &txnobj))
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002355 return NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002356 }
2357
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002358 if (!checkTxnObj(txnobj, &txn)) return NULL;
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002359
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002360 if (NULL == self->db) {
Thomas Woutersb3153832006-03-08 01:47:19 +00002361 PyObject *t = Py_BuildValue("(is)", 0,
2362 "Cannot call open() twice for DB object");
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002363 if (t) {
2364 PyErr_SetObject(DBError, t);
2365 Py_DECREF(t);
2366 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002367 return NULL;
2368 }
2369
Jesus Ceaef9764f2008-05-13 18:45:46 +00002370 if (txn) { /* Can't use 'txnobj' because could be 'txnobj==Py_None' */
2371 INSERT_IN_DOUBLE_LINKED_LIST_TXN(((DBTxnObject *)txnobj)->children_dbs,self);
2372 self->txn=(DBTxnObject *)txnobj;
2373 } else {
2374 self->txn=NULL;
2375 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00002376
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002377 MYDB_BEGIN_ALLOW_THREADS;
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002378 err = self->db->open(self->db, txn, filename, dbname, type, flags, mode);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002379 MYDB_END_ALLOW_THREADS;
Jesus Cea6557aac2010-03-22 14:22:26 +00002380
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002381 if (makeDBError(err)) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00002382 PyObject *dummy;
2383
Jesus Cea5cd5f122008-09-23 18:54:08 +00002384 dummy=DB_close_internal(self, 0, 0);
Jesus Ceaef9764f2008-05-13 18:45:46 +00002385 Py_XDECREF(dummy);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002386 return NULL;
2387 }
2388
Gregory P. Smithec10a4a2007-11-05 02:32:26 +00002389 self->db->get_flags(self->db, &self->setflags);
2390
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002391 self->flags = flags;
Jesus Ceaef9764f2008-05-13 18:45:46 +00002392
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002393 RETURN_NONE();
2394}
2395
2396
2397static PyObject*
2398DB_put(DBObject* self, PyObject* args, PyObject* kwargs)
2399{
2400 int flags=0;
2401 PyObject* txnobj = NULL;
2402 int dlen = -1;
2403 int doff = -1;
2404 PyObject* keyobj, *dataobj, *retval;
2405 DBT key, data;
2406 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002407 static char* kwnames[] = { "key", "data", "txn", "flags", "dlen",
Jeremy Hyltonaf68c872005-12-10 18:50:16 +00002408 "doff", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002409
2410 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|Oiii:put", kwnames,
2411 &keyobj, &dataobj, &txnobj, &flags, &dlen, &doff))
2412 return NULL;
2413
2414 CHECK_DB_NOT_CLOSED(self);
Gregory P. Smithdc5af702004-06-27 23:32:34 +00002415 if (!make_key_dbt(self, keyobj, &key, NULL))
2416 return NULL;
2417 if ( !make_dbt(dataobj, &data) ||
2418 !add_partial_dbt(&data, dlen, doff) ||
2419 !checkTxnObj(txnobj, &txn) )
2420 {
2421 FREE_DBT(key);
2422 return NULL;
2423 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002424
2425 if (-1 == _DB_put(self, txn, &key, &data, flags)) {
2426 FREE_DBT(key);
2427 return NULL;
2428 }
2429
2430 if (flags & DB_APPEND)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002431 retval = NUMBER_FromLong(*((db_recno_t*)key.data));
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002432 else {
2433 retval = Py_None;
2434 Py_INCREF(retval);
2435 }
2436 FREE_DBT(key);
2437 return retval;
2438}
2439
2440
2441
2442static PyObject*
2443DB_remove(DBObject* self, PyObject* args, PyObject* kwargs)
2444{
2445 char* filename;
2446 char* database = NULL;
2447 int err, flags=0;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002448 static char* kwnames[] = { "filename", "dbname", "flags", NULL};
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002449
2450 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|zi:remove", kwnames,
2451 &filename, &database, &flags))
2452 return NULL;
2453 CHECK_DB_NOT_CLOSED(self);
2454
Jesus Cea4907d272008-08-31 14:00:51 +00002455 EXTRACT_FROM_DOUBLE_LINKED_LIST_MAYBE_NULL(self);
2456
2457 MYDB_BEGIN_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002458 err = self->db->remove(self->db, filename, database, flags);
Jesus Cea4907d272008-08-31 14:00:51 +00002459 MYDB_END_ALLOW_THREADS;
2460
Gregory P. Smithf655dff2003-05-15 00:13:18 +00002461 self->db = NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002462 RETURN_IF_ERR();
2463 RETURN_NONE();
2464}
2465
2466
2467
2468static PyObject*
2469DB_rename(DBObject* self, PyObject* args)
2470{
2471 char* filename;
2472 char* database;
2473 char* newname;
2474 int err, flags=0;
2475
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002476 if (!PyArg_ParseTuple(args, "sss|i:rename", &filename, &database, &newname,
2477 &flags))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002478 return NULL;
2479 CHECK_DB_NOT_CLOSED(self);
2480
2481 MYDB_BEGIN_ALLOW_THREADS;
2482 err = self->db->rename(self->db, filename, database, newname, flags);
2483 MYDB_END_ALLOW_THREADS;
2484 RETURN_IF_ERR();
2485 RETURN_NONE();
2486}
2487
2488
2489static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002490DB_get_private(DBObject* self)
2491{
2492 /* We can give out the private field even if db is closed */
Jesus Cea4907d272008-08-31 14:00:51 +00002493 Py_INCREF(self->private_obj);
2494 return self->private_obj;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002495}
2496
2497static PyObject*
Jesus Cea4907d272008-08-31 14:00:51 +00002498DB_set_private(DBObject* self, PyObject* private_obj)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002499{
2500 /* We can set the private field even if db is closed */
Jesus Cea4907d272008-08-31 14:00:51 +00002501 Py_DECREF(self->private_obj);
2502 Py_INCREF(private_obj);
2503 self->private_obj = private_obj;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002504 RETURN_NONE();
2505}
2506
Jesus Cea6557aac2010-03-22 14:22:26 +00002507#if (DBVER >= 46)
2508static PyObject*
2509DB_set_priority(DBObject* self, PyObject* args)
2510{
2511 int err, priority;
2512
2513 if (!PyArg_ParseTuple(args,"i:set_priority", &priority))
2514 return NULL;
2515 CHECK_DB_NOT_CLOSED(self);
2516
2517 MYDB_BEGIN_ALLOW_THREADS;
2518 err = self->db->set_priority(self->db, priority);
2519 MYDB_END_ALLOW_THREADS;
2520 RETURN_IF_ERR();
2521 RETURN_NONE();
2522}
2523
2524static PyObject*
2525DB_get_priority(DBObject* self)
2526{
2527 int err = 0;
2528 DB_CACHE_PRIORITY priority;
2529
2530 CHECK_DB_NOT_CLOSED(self);
2531
2532 MYDB_BEGIN_ALLOW_THREADS;
2533 err = self->db->get_priority(self->db, &priority);
2534 MYDB_END_ALLOW_THREADS;
2535 RETURN_IF_ERR();
2536 return NUMBER_FromLong(priority);
2537}
2538#endif
2539
2540static PyObject*
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07002541DB_get_dbname(DBObject* self)
2542{
2543 int err;
2544 const char *filename, *dbname;
2545
2546 CHECK_DB_NOT_CLOSED(self);
2547
2548 MYDB_BEGIN_ALLOW_THREADS;
2549 err = self->db->get_dbname(self->db, &filename, &dbname);
2550 MYDB_END_ALLOW_THREADS;
2551 RETURN_IF_ERR();
2552 /* If "dbname==NULL", it is correctly converted to "None" */
2553 return Py_BuildValue("(ss)", filename, dbname);
2554}
2555
2556static PyObject*
2557DB_get_open_flags(DBObject* self)
2558{
2559 int err;
2560 unsigned int flags;
2561
2562 CHECK_DB_NOT_CLOSED(self);
2563
2564 MYDB_BEGIN_ALLOW_THREADS;
2565 err = self->db->get_open_flags(self->db, &flags);
2566 MYDB_END_ALLOW_THREADS;
2567 RETURN_IF_ERR();
2568 return NUMBER_FromLong(flags);
2569}
2570
2571static PyObject*
Jesus Cea6557aac2010-03-22 14:22:26 +00002572DB_set_q_extentsize(DBObject* self, PyObject* args)
2573{
2574 int err;
2575 u_int32_t extentsize;
2576
2577 if (!PyArg_ParseTuple(args,"i:set_q_extentsize", &extentsize))
2578 return NULL;
2579 CHECK_DB_NOT_CLOSED(self);
2580
2581 MYDB_BEGIN_ALLOW_THREADS;
2582 err = self->db->set_q_extentsize(self->db, extentsize);
2583 MYDB_END_ALLOW_THREADS;
2584 RETURN_IF_ERR();
2585 RETURN_NONE();
2586}
2587
Jesus Cea6557aac2010-03-22 14:22:26 +00002588static PyObject*
2589DB_get_q_extentsize(DBObject* self)
2590{
2591 int err = 0;
2592 u_int32_t extentsize;
2593
2594 CHECK_DB_NOT_CLOSED(self);
2595
2596 MYDB_BEGIN_ALLOW_THREADS;
2597 err = self->db->get_q_extentsize(self->db, &extentsize);
2598 MYDB_END_ALLOW_THREADS;
2599 RETURN_IF_ERR();
2600 return NUMBER_FromLong(extentsize);
2601}
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002602
2603static PyObject*
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002604DB_set_bt_minkey(DBObject* self, PyObject* args)
2605{
2606 int err, minkey;
2607
Jesus Cea6557aac2010-03-22 14:22:26 +00002608 if (!PyArg_ParseTuple(args,"i:set_bt_minkey", &minkey))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002609 return NULL;
2610 CHECK_DB_NOT_CLOSED(self);
2611
2612 MYDB_BEGIN_ALLOW_THREADS;
2613 err = self->db->set_bt_minkey(self->db, minkey);
2614 MYDB_END_ALLOW_THREADS;
2615 RETURN_IF_ERR();
2616 RETURN_NONE();
2617}
2618
Jesus Cea6557aac2010-03-22 14:22:26 +00002619static PyObject*
2620DB_get_bt_minkey(DBObject* self)
2621{
2622 int err;
2623 u_int32_t bt_minkey;
2624
2625 CHECK_DB_NOT_CLOSED(self);
2626
2627 MYDB_BEGIN_ALLOW_THREADS;
2628 err = self->db->get_bt_minkey(self->db, &bt_minkey);
2629 MYDB_END_ALLOW_THREADS;
2630 RETURN_IF_ERR();
2631 return NUMBER_FromLong(bt_minkey);
2632}
Jesus Cea6557aac2010-03-22 14:22:26 +00002633
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002634static int
Georg Brandlef1701f2006-03-07 14:57:48 +00002635_default_cmp(const DBT *leftKey,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002636 const DBT *rightKey)
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002637{
2638 int res;
2639 int lsize = leftKey->size, rsize = rightKey->size;
2640
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002641 res = memcmp(leftKey->data, rightKey->data,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002642 lsize < rsize ? lsize : rsize);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002643
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002644 if (res == 0) {
2645 if (lsize < rsize) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002646 res = -1;
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002647 }
2648 else if (lsize > rsize) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002649 res = 1;
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002650 }
2651 }
2652 return res;
2653}
2654
2655static int
Jesus Ceaef9764f2008-05-13 18:45:46 +00002656_db_compareCallback(DB* db,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002657 const DBT *leftKey,
2658 const DBT *rightKey)
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002659{
2660 int res = 0;
2661 PyObject *args;
Thomas Woutersb2820ae2006-03-12 00:01:38 +00002662 PyObject *result = NULL;
Georg Brandlef1701f2006-03-07 14:57:48 +00002663 DBObject *self = (DBObject *)db->app_private;
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002664
2665 if (self == NULL || self->btCompareCallback == NULL) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002666 MYDB_BEGIN_BLOCK_THREADS;
2667 PyErr_SetString(PyExc_TypeError,
2668 (self == 0
2669 ? "DB_bt_compare db is NULL."
2670 : "DB_bt_compare callback is NULL."));
2671 /* we're in a callback within the DB code, we can't raise */
2672 PyErr_Print();
2673 res = _default_cmp(leftKey, rightKey);
2674 MYDB_END_BLOCK_THREADS;
Georg Brandlef1701f2006-03-07 14:57:48 +00002675 } else {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002676 MYDB_BEGIN_BLOCK_THREADS;
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002677
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002678 args = BuildValue_SS(leftKey->data, leftKey->size, rightKey->data, rightKey->size);
2679 if (args != NULL) {
2680 result = PyEval_CallObject(self->btCompareCallback, args);
2681 }
2682 if (args == NULL || result == NULL) {
2683 /* we're in a callback within the DB code, we can't raise */
2684 PyErr_Print();
2685 res = _default_cmp(leftKey, rightKey);
2686 } else if (NUMBER_Check(result)) {
2687 res = NUMBER_AsLong(result);
2688 } else {
2689 PyErr_SetString(PyExc_TypeError,
2690 "DB_bt_compare callback MUST return an int.");
2691 /* we're in a callback within the DB code, we can't raise */
2692 PyErr_Print();
2693 res = _default_cmp(leftKey, rightKey);
2694 }
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002695
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002696 Py_XDECREF(args);
2697 Py_XDECREF(result);
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002698
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002699 MYDB_END_BLOCK_THREADS;
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002700 }
2701 return res;
2702}
2703
2704static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002705DB_set_bt_compare(DBObject* self, PyObject* comparator)
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002706{
2707 int err;
Thomas Woutersb3153832006-03-08 01:47:19 +00002708 PyObject *tuple, *result;
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002709
Georg Brandlef1701f2006-03-07 14:57:48 +00002710 CHECK_DB_NOT_CLOSED(self);
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002711
Georg Brandlef1701f2006-03-07 14:57:48 +00002712 if (!PyCallable_Check(comparator)) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002713 makeTypeError("Callable", comparator);
2714 return NULL;
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002715 }
2716
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002717 /*
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002718 * Perform a test call of the comparator function with two empty
2719 * string objects here. verify that it returns an int (0).
2720 * err if not.
2721 */
Thomas Woutersb3153832006-03-08 01:47:19 +00002722 tuple = Py_BuildValue("(ss)", "", "");
Georg Brandlef1701f2006-03-07 14:57:48 +00002723 result = PyEval_CallObject(comparator, tuple);
2724 Py_DECREF(tuple);
Thomas Woutersb3153832006-03-08 01:47:19 +00002725 if (result == NULL)
2726 return NULL;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002727 if (!NUMBER_Check(result)) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002728 Py_DECREF(result);
2729 PyErr_SetString(PyExc_TypeError,
2730 "callback MUST return an int");
2731 return NULL;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002732 } else if (NUMBER_AsLong(result) != 0) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002733 Py_DECREF(result);
2734 PyErr_SetString(PyExc_TypeError,
2735 "callback failed to return 0 on two empty strings");
2736 return NULL;
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002737 }
Thomas Woutersb3153832006-03-08 01:47:19 +00002738 Py_DECREF(result);
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002739
2740 /* We don't accept multiple set_bt_compare operations, in order to
2741 * simplify the code. This would have no real use, as one cannot
2742 * change the function once the db is opened anyway */
2743 if (self->btCompareCallback != NULL) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002744 PyErr_SetString(PyExc_RuntimeError, "set_bt_compare() cannot be called more than once");
2745 return NULL;
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002746 }
2747
Georg Brandlef1701f2006-03-07 14:57:48 +00002748 Py_INCREF(comparator);
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002749 self->btCompareCallback = comparator;
2750
2751 /* This is to workaround a problem with un-initialized threads (see
2752 comment in DB_associate) */
2753#ifdef WITH_THREAD
2754 PyEval_InitThreads();
2755#endif
2756
Thomas Woutersb3153832006-03-08 01:47:19 +00002757 err = self->db->set_bt_compare(self->db, _db_compareCallback);
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002758
2759 if (err) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002760 /* restore the old state in case of error */
2761 Py_DECREF(comparator);
2762 self->btCompareCallback = NULL;
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002763 }
2764
Georg Brandlef1701f2006-03-07 14:57:48 +00002765 RETURN_IF_ERR();
2766 RETURN_NONE();
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002767}
2768
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07002769static int
2770_db_dupCompareCallback(DB* db,
2771 const DBT *leftKey,
2772 const DBT *rightKey)
2773{
2774 int res = 0;
2775 PyObject *args;
2776 PyObject *result = NULL;
2777 DBObject *self = (DBObject *)db->app_private;
2778
2779 if (self == NULL || self->dupCompareCallback == NULL) {
2780 MYDB_BEGIN_BLOCK_THREADS;
2781 PyErr_SetString(PyExc_TypeError,
2782 (self == 0
2783 ? "DB_dup_compare db is NULL."
2784 : "DB_dup_compare callback is NULL."));
2785 /* we're in a callback within the DB code, we can't raise */
2786 PyErr_Print();
2787 res = _default_cmp(leftKey, rightKey);
2788 MYDB_END_BLOCK_THREADS;
2789 } else {
2790 MYDB_BEGIN_BLOCK_THREADS;
2791
2792 args = BuildValue_SS(leftKey->data, leftKey->size, rightKey->data, rightKey->size);
2793 if (args != NULL) {
2794 result = PyEval_CallObject(self->dupCompareCallback, args);
2795 }
2796 if (args == NULL || result == NULL) {
2797 /* we're in a callback within the DB code, we can't raise */
2798 PyErr_Print();
2799 res = _default_cmp(leftKey, rightKey);
2800 } else if (NUMBER_Check(result)) {
2801 res = NUMBER_AsLong(result);
2802 } else {
2803 PyErr_SetString(PyExc_TypeError,
2804 "DB_dup_compare callback MUST return an int.");
2805 /* we're in a callback within the DB code, we can't raise */
2806 PyErr_Print();
2807 res = _default_cmp(leftKey, rightKey);
2808 }
2809
2810 Py_XDECREF(args);
2811 Py_XDECREF(result);
2812
2813 MYDB_END_BLOCK_THREADS;
2814 }
2815 return res;
2816}
2817
2818static PyObject*
2819DB_set_dup_compare(DBObject* self, PyObject* comparator)
2820{
2821 int err;
2822 PyObject *tuple, *result;
2823
2824 CHECK_DB_NOT_CLOSED(self);
2825
2826 if (!PyCallable_Check(comparator)) {
2827 makeTypeError("Callable", comparator);
2828 return NULL;
2829 }
2830
2831 /*
2832 * Perform a test call of the comparator function with two empty
2833 * string objects here. verify that it returns an int (0).
2834 * err if not.
2835 */
2836 tuple = Py_BuildValue("(ss)", "", "");
2837 result = PyEval_CallObject(comparator, tuple);
2838 Py_DECREF(tuple);
2839 if (result == NULL)
2840 return NULL;
2841 if (!NUMBER_Check(result)) {
2842 Py_DECREF(result);
2843 PyErr_SetString(PyExc_TypeError,
2844 "callback MUST return an int");
2845 return NULL;
2846 } else if (NUMBER_AsLong(result) != 0) {
2847 Py_DECREF(result);
2848 PyErr_SetString(PyExc_TypeError,
2849 "callback failed to return 0 on two empty strings");
2850 return NULL;
2851 }
2852 Py_DECREF(result);
2853
2854 /* We don't accept multiple set_dup_compare operations, in order to
2855 * simplify the code. This would have no real use, as one cannot
2856 * change the function once the db is opened anyway */
2857 if (self->dupCompareCallback != NULL) {
2858 PyErr_SetString(PyExc_RuntimeError, "set_dup_compare() cannot be called more than once");
2859 return NULL;
2860 }
2861
2862 Py_INCREF(comparator);
2863 self->dupCompareCallback = comparator;
2864
2865 /* This is to workaround a problem with un-initialized threads (see
2866 comment in DB_associate) */
2867#ifdef WITH_THREAD
2868 PyEval_InitThreads();
2869#endif
2870
2871 err = self->db->set_dup_compare(self->db, _db_dupCompareCallback);
2872
2873 if (err) {
2874 /* restore the old state in case of error */
2875 Py_DECREF(comparator);
2876 self->dupCompareCallback = NULL;
2877 }
2878
2879 RETURN_IF_ERR();
2880 RETURN_NONE();
2881}
2882
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002883
2884static PyObject*
2885DB_set_cachesize(DBObject* self, PyObject* args)
2886{
2887 int err;
2888 int gbytes = 0, bytes = 0, ncache = 0;
2889
2890 if (!PyArg_ParseTuple(args,"ii|i:set_cachesize",
2891 &gbytes,&bytes,&ncache))
2892 return NULL;
2893 CHECK_DB_NOT_CLOSED(self);
2894
2895 MYDB_BEGIN_ALLOW_THREADS;
2896 err = self->db->set_cachesize(self->db, gbytes, bytes, ncache);
2897 MYDB_END_ALLOW_THREADS;
2898 RETURN_IF_ERR();
2899 RETURN_NONE();
2900}
2901
Jesus Cea6557aac2010-03-22 14:22:26 +00002902static PyObject*
2903DB_get_cachesize(DBObject* self)
2904{
2905 int err;
2906 u_int32_t gbytes, bytes;
2907 int ncache;
2908
2909 CHECK_DB_NOT_CLOSED(self);
2910
2911 MYDB_BEGIN_ALLOW_THREADS;
2912 err = self->db->get_cachesize(self->db, &gbytes, &bytes, &ncache);
2913 MYDB_END_ALLOW_THREADS;
2914
2915 RETURN_IF_ERR();
2916
2917 return Py_BuildValue("(iii)", gbytes, bytes, ncache);
2918}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002919
2920static PyObject*
2921DB_set_flags(DBObject* self, PyObject* args)
2922{
2923 int err, flags;
2924
2925 if (!PyArg_ParseTuple(args,"i:set_flags", &flags))
2926 return NULL;
2927 CHECK_DB_NOT_CLOSED(self);
2928
2929 MYDB_BEGIN_ALLOW_THREADS;
2930 err = self->db->set_flags(self->db, flags);
2931 MYDB_END_ALLOW_THREADS;
2932 RETURN_IF_ERR();
2933
2934 self->setflags |= flags;
2935 RETURN_NONE();
2936}
2937
Jesus Cea6557aac2010-03-22 14:22:26 +00002938static PyObject*
2939DB_get_flags(DBObject* self)
2940{
2941 int err;
2942 u_int32_t flags;
2943
2944 CHECK_DB_NOT_CLOSED(self);
2945
2946 MYDB_BEGIN_ALLOW_THREADS;
2947 err = self->db->get_flags(self->db, &flags);
2948 MYDB_END_ALLOW_THREADS;
2949 RETURN_IF_ERR();
2950 return NUMBER_FromLong(flags);
2951}
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07002952
2953static PyObject*
2954DB_get_transactional(DBObject* self)
2955{
2956 int err;
2957
2958 CHECK_DB_NOT_CLOSED(self);
2959
2960 MYDB_BEGIN_ALLOW_THREADS;
2961 err = self->db->get_transactional(self->db);
2962 MYDB_END_ALLOW_THREADS;
2963
2964 if(err == 0) {
2965 Py_INCREF(Py_False);
2966 return Py_False;
2967 } else if(err == 1) {
2968 Py_INCREF(Py_True);
2969 return Py_True;
2970 }
2971
2972 /*
2973 ** If we reach there, there was an error. The
2974 ** "return" should be unreachable.
2975 */
2976 RETURN_IF_ERR();
2977 assert(0); /* This code SHOULD be unreachable */
2978 return NULL;
2979}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002980
2981static PyObject*
2982DB_set_h_ffactor(DBObject* self, PyObject* args)
2983{
2984 int err, ffactor;
2985
2986 if (!PyArg_ParseTuple(args,"i:set_h_ffactor", &ffactor))
2987 return NULL;
2988 CHECK_DB_NOT_CLOSED(self);
2989
2990 MYDB_BEGIN_ALLOW_THREADS;
2991 err = self->db->set_h_ffactor(self->db, ffactor);
2992 MYDB_END_ALLOW_THREADS;
2993 RETURN_IF_ERR();
2994 RETURN_NONE();
2995}
2996
Jesus Cea6557aac2010-03-22 14:22:26 +00002997static PyObject*
2998DB_get_h_ffactor(DBObject* self)
2999{
3000 int err;
3001 u_int32_t ffactor;
3002
3003 CHECK_DB_NOT_CLOSED(self);
3004
3005 MYDB_BEGIN_ALLOW_THREADS;
3006 err = self->db->get_h_ffactor(self->db, &ffactor);
3007 MYDB_END_ALLOW_THREADS;
3008 RETURN_IF_ERR();
3009 return NUMBER_FromLong(ffactor);
3010}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003011
3012static PyObject*
3013DB_set_h_nelem(DBObject* self, PyObject* args)
3014{
3015 int err, nelem;
3016
3017 if (!PyArg_ParseTuple(args,"i:set_h_nelem", &nelem))
3018 return NULL;
3019 CHECK_DB_NOT_CLOSED(self);
3020
3021 MYDB_BEGIN_ALLOW_THREADS;
3022 err = self->db->set_h_nelem(self->db, nelem);
3023 MYDB_END_ALLOW_THREADS;
3024 RETURN_IF_ERR();
3025 RETURN_NONE();
3026}
3027
Jesus Cea6557aac2010-03-22 14:22:26 +00003028static PyObject*
3029DB_get_h_nelem(DBObject* self)
3030{
3031 int err;
3032 u_int32_t nelem;
3033
3034 CHECK_DB_NOT_CLOSED(self);
3035
3036 MYDB_BEGIN_ALLOW_THREADS;
3037 err = self->db->get_h_nelem(self->db, &nelem);
3038 MYDB_END_ALLOW_THREADS;
3039 RETURN_IF_ERR();
3040 return NUMBER_FromLong(nelem);
3041}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003042
3043static PyObject*
3044DB_set_lorder(DBObject* self, PyObject* args)
3045{
3046 int err, lorder;
3047
3048 if (!PyArg_ParseTuple(args,"i:set_lorder", &lorder))
3049 return NULL;
3050 CHECK_DB_NOT_CLOSED(self);
3051
3052 MYDB_BEGIN_ALLOW_THREADS;
3053 err = self->db->set_lorder(self->db, lorder);
3054 MYDB_END_ALLOW_THREADS;
3055 RETURN_IF_ERR();
3056 RETURN_NONE();
3057}
3058
Jesus Cea6557aac2010-03-22 14:22:26 +00003059static PyObject*
3060DB_get_lorder(DBObject* self)
3061{
3062 int err;
3063 int lorder;
3064
3065 CHECK_DB_NOT_CLOSED(self);
3066
3067 MYDB_BEGIN_ALLOW_THREADS;
3068 err = self->db->get_lorder(self->db, &lorder);
3069 MYDB_END_ALLOW_THREADS;
3070 RETURN_IF_ERR();
3071 return NUMBER_FromLong(lorder);
3072}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003073
3074static PyObject*
3075DB_set_pagesize(DBObject* self, PyObject* args)
3076{
3077 int err, pagesize;
3078
3079 if (!PyArg_ParseTuple(args,"i:set_pagesize", &pagesize))
3080 return NULL;
3081 CHECK_DB_NOT_CLOSED(self);
3082
3083 MYDB_BEGIN_ALLOW_THREADS;
3084 err = self->db->set_pagesize(self->db, pagesize);
3085 MYDB_END_ALLOW_THREADS;
3086 RETURN_IF_ERR();
3087 RETURN_NONE();
3088}
3089
Jesus Cea6557aac2010-03-22 14:22:26 +00003090static PyObject*
3091DB_get_pagesize(DBObject* self)
3092{
3093 int err;
3094 u_int32_t pagesize;
3095
3096 CHECK_DB_NOT_CLOSED(self);
3097
3098 MYDB_BEGIN_ALLOW_THREADS;
3099 err = self->db->get_pagesize(self->db, &pagesize);
3100 MYDB_END_ALLOW_THREADS;
3101 RETURN_IF_ERR();
3102 return NUMBER_FromLong(pagesize);
3103}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003104
3105static PyObject*
3106DB_set_re_delim(DBObject* self, PyObject* args)
3107{
3108 int err;
3109 char delim;
3110
3111 if (!PyArg_ParseTuple(args,"b:set_re_delim", &delim)) {
3112 PyErr_Clear();
3113 if (!PyArg_ParseTuple(args,"c:set_re_delim", &delim))
3114 return NULL;
3115 }
3116
3117 CHECK_DB_NOT_CLOSED(self);
3118
3119 MYDB_BEGIN_ALLOW_THREADS;
3120 err = self->db->set_re_delim(self->db, delim);
3121 MYDB_END_ALLOW_THREADS;
3122 RETURN_IF_ERR();
3123 RETURN_NONE();
3124}
3125
Jesus Cea6557aac2010-03-22 14:22:26 +00003126static PyObject*
3127DB_get_re_delim(DBObject* self)
3128{
3129 int err, re_delim;
3130
3131 CHECK_DB_NOT_CLOSED(self);
3132
3133 MYDB_BEGIN_ALLOW_THREADS;
3134 err = self->db->get_re_delim(self->db, &re_delim);
3135 MYDB_END_ALLOW_THREADS;
3136 RETURN_IF_ERR();
3137 return NUMBER_FromLong(re_delim);
3138}
Jesus Cea6557aac2010-03-22 14:22:26 +00003139
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003140static PyObject*
3141DB_set_re_len(DBObject* self, PyObject* args)
3142{
3143 int err, len;
3144
3145 if (!PyArg_ParseTuple(args,"i:set_re_len", &len))
3146 return NULL;
3147 CHECK_DB_NOT_CLOSED(self);
3148
3149 MYDB_BEGIN_ALLOW_THREADS;
3150 err = self->db->set_re_len(self->db, len);
3151 MYDB_END_ALLOW_THREADS;
3152 RETURN_IF_ERR();
3153 RETURN_NONE();
3154}
3155
Jesus Cea6557aac2010-03-22 14:22:26 +00003156static PyObject*
3157DB_get_re_len(DBObject* self)
3158{
3159 int err;
3160 u_int32_t re_len;
3161
3162 CHECK_DB_NOT_CLOSED(self);
3163
3164 MYDB_BEGIN_ALLOW_THREADS;
3165 err = self->db->get_re_len(self->db, &re_len);
3166 MYDB_END_ALLOW_THREADS;
3167 RETURN_IF_ERR();
3168 return NUMBER_FromLong(re_len);
3169}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003170
3171static PyObject*
3172DB_set_re_pad(DBObject* self, PyObject* args)
3173{
3174 int err;
3175 char pad;
3176
3177 if (!PyArg_ParseTuple(args,"b:set_re_pad", &pad)) {
3178 PyErr_Clear();
3179 if (!PyArg_ParseTuple(args,"c:set_re_pad", &pad))
3180 return NULL;
3181 }
3182 CHECK_DB_NOT_CLOSED(self);
3183
3184 MYDB_BEGIN_ALLOW_THREADS;
3185 err = self->db->set_re_pad(self->db, pad);
3186 MYDB_END_ALLOW_THREADS;
3187 RETURN_IF_ERR();
3188 RETURN_NONE();
3189}
3190
Jesus Cea6557aac2010-03-22 14:22:26 +00003191static PyObject*
3192DB_get_re_pad(DBObject* self)
3193{
3194 int err, re_pad;
3195
3196 CHECK_DB_NOT_CLOSED(self);
3197
3198 MYDB_BEGIN_ALLOW_THREADS;
3199 err = self->db->get_re_pad(self->db, &re_pad);
3200 MYDB_END_ALLOW_THREADS;
3201 RETURN_IF_ERR();
3202 return NUMBER_FromLong(re_pad);
3203}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003204
3205static PyObject*
3206DB_set_re_source(DBObject* self, PyObject* args)
3207{
3208 int err;
Jesus Cea6557aac2010-03-22 14:22:26 +00003209 char *source;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003210
Jesus Cea6557aac2010-03-22 14:22:26 +00003211 if (!PyArg_ParseTuple(args,"s:set_re_source", &source))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003212 return NULL;
3213 CHECK_DB_NOT_CLOSED(self);
3214
3215 MYDB_BEGIN_ALLOW_THREADS;
Jesus Cea6557aac2010-03-22 14:22:26 +00003216 err = self->db->set_re_source(self->db, source);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003217 MYDB_END_ALLOW_THREADS;
3218 RETURN_IF_ERR();
3219 RETURN_NONE();
3220}
3221
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003222static PyObject*
Jesus Cea6557aac2010-03-22 14:22:26 +00003223DB_get_re_source(DBObject* self)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003224{
3225 int err;
Jesus Cea6557aac2010-03-22 14:22:26 +00003226 const char *source;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003227
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003228 CHECK_DB_NOT_CLOSED(self);
3229
3230 MYDB_BEGIN_ALLOW_THREADS;
Jesus Cea6557aac2010-03-22 14:22:26 +00003231 err = self->db->get_re_source(self->db, &source);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003232 MYDB_END_ALLOW_THREADS;
3233 RETURN_IF_ERR();
Jesus Cea6557aac2010-03-22 14:22:26 +00003234 return PyBytes_FromString(source);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003235}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003236
3237static PyObject*
Gregory P. Smith8b7e9172004-12-13 09:51:23 +00003238DB_stat(DBObject* self, PyObject* args, PyObject* kwargs)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003239{
3240 int err, flags = 0, type;
3241 void* sp;
3242 PyObject* d;
Gregory P. Smith8b7e9172004-12-13 09:51:23 +00003243 PyObject* txnobj = NULL;
3244 DB_TXN *txn = NULL;
Gregory P. Smith2fa06792006-09-19 17:35:04 +00003245 static char* kwnames[] = { "flags", "txn", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003246
Gregory P. Smith8b7e9172004-12-13 09:51:23 +00003247 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|iO:stat", kwnames,
3248 &flags, &txnobj))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003249 return NULL;
Gregory P. Smith8b7e9172004-12-13 09:51:23 +00003250 if (!checkTxnObj(txnobj, &txn))
3251 return NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003252 CHECK_DB_NOT_CLOSED(self);
3253
3254 MYDB_BEGIN_ALLOW_THREADS;
Gregory P. Smith8b7e9172004-12-13 09:51:23 +00003255 err = self->db->stat(self->db, txn, &sp, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003256 MYDB_END_ALLOW_THREADS;
3257 RETURN_IF_ERR();
3258
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003259 /* Turn the stat structure into a dictionary */
3260 type = _DB_get_type(self);
3261 if ((type == -1) || ((d = PyDict_New()) == NULL)) {
3262 free(sp);
3263 return NULL;
3264 }
3265
3266#define MAKE_HASH_ENTRY(name) _addIntToDict(d, #name, ((DB_HASH_STAT*)sp)->hash_##name)
3267#define MAKE_BT_ENTRY(name) _addIntToDict(d, #name, ((DB_BTREE_STAT*)sp)->bt_##name)
3268#define MAKE_QUEUE_ENTRY(name) _addIntToDict(d, #name, ((DB_QUEUE_STAT*)sp)->qs_##name)
3269
3270 switch (type) {
3271 case DB_HASH:
3272 MAKE_HASH_ENTRY(magic);
3273 MAKE_HASH_ENTRY(version);
3274 MAKE_HASH_ENTRY(nkeys);
3275 MAKE_HASH_ENTRY(ndata);
Jesus Ceaef9764f2008-05-13 18:45:46 +00003276#if (DBVER >= 46)
3277 MAKE_HASH_ENTRY(pagecnt);
3278#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003279 MAKE_HASH_ENTRY(pagesize);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003280 MAKE_HASH_ENTRY(ffactor);
3281 MAKE_HASH_ENTRY(buckets);
3282 MAKE_HASH_ENTRY(free);
3283 MAKE_HASH_ENTRY(bfree);
3284 MAKE_HASH_ENTRY(bigpages);
3285 MAKE_HASH_ENTRY(big_bfree);
3286 MAKE_HASH_ENTRY(overflows);
3287 MAKE_HASH_ENTRY(ovfl_free);
3288 MAKE_HASH_ENTRY(dup);
3289 MAKE_HASH_ENTRY(dup_free);
3290 break;
3291
3292 case DB_BTREE:
3293 case DB_RECNO:
3294 MAKE_BT_ENTRY(magic);
3295 MAKE_BT_ENTRY(version);
3296 MAKE_BT_ENTRY(nkeys);
3297 MAKE_BT_ENTRY(ndata);
Jesus Ceaef9764f2008-05-13 18:45:46 +00003298#if (DBVER >= 46)
3299 MAKE_BT_ENTRY(pagecnt);
3300#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003301 MAKE_BT_ENTRY(pagesize);
3302 MAKE_BT_ENTRY(minkey);
3303 MAKE_BT_ENTRY(re_len);
3304 MAKE_BT_ENTRY(re_pad);
3305 MAKE_BT_ENTRY(levels);
3306 MAKE_BT_ENTRY(int_pg);
3307 MAKE_BT_ENTRY(leaf_pg);
3308 MAKE_BT_ENTRY(dup_pg);
3309 MAKE_BT_ENTRY(over_pg);
Jesus Ceaef9764f2008-05-13 18:45:46 +00003310 MAKE_BT_ENTRY(empty_pg);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003311 MAKE_BT_ENTRY(free);
3312 MAKE_BT_ENTRY(int_pgfree);
3313 MAKE_BT_ENTRY(leaf_pgfree);
3314 MAKE_BT_ENTRY(dup_pgfree);
3315 MAKE_BT_ENTRY(over_pgfree);
3316 break;
3317
3318 case DB_QUEUE:
3319 MAKE_QUEUE_ENTRY(magic);
3320 MAKE_QUEUE_ENTRY(version);
3321 MAKE_QUEUE_ENTRY(nkeys);
3322 MAKE_QUEUE_ENTRY(ndata);
3323 MAKE_QUEUE_ENTRY(pagesize);
Jesus Ceaef9764f2008-05-13 18:45:46 +00003324 MAKE_QUEUE_ENTRY(extentsize);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003325 MAKE_QUEUE_ENTRY(pages);
3326 MAKE_QUEUE_ENTRY(re_len);
3327 MAKE_QUEUE_ENTRY(re_pad);
3328 MAKE_QUEUE_ENTRY(pgfree);
3329#if (DBVER == 31)
3330 MAKE_QUEUE_ENTRY(start);
3331#endif
3332 MAKE_QUEUE_ENTRY(first_recno);
3333 MAKE_QUEUE_ENTRY(cur_recno);
3334 break;
3335
3336 default:
3337 PyErr_SetString(PyExc_TypeError, "Unknown DB type, unable to stat");
3338 Py_DECREF(d);
3339 d = NULL;
3340 }
3341
3342#undef MAKE_HASH_ENTRY
3343#undef MAKE_BT_ENTRY
3344#undef MAKE_QUEUE_ENTRY
3345
3346 free(sp);
3347 return d;
3348}
3349
Jesus Cea6557aac2010-03-22 14:22:26 +00003350static PyObject*
3351DB_stat_print(DBObject* self, PyObject* args, PyObject *kwargs)
3352{
3353 int err;
3354 int flags=0;
3355 static char* kwnames[] = { "flags", NULL };
3356
3357 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:stat_print",
3358 kwnames, &flags))
3359 {
3360 return NULL;
3361 }
3362 CHECK_DB_NOT_CLOSED(self);
3363 MYDB_BEGIN_ALLOW_THREADS;
3364 err = self->db->stat_print(self->db, flags);
3365 MYDB_END_ALLOW_THREADS;
3366 RETURN_IF_ERR();
3367 RETURN_NONE();
3368}
Jesus Cea6557aac2010-03-22 14:22:26 +00003369
3370
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003371static PyObject*
3372DB_sync(DBObject* self, PyObject* args)
3373{
3374 int err;
3375 int flags = 0;
3376
3377 if (!PyArg_ParseTuple(args,"|i:sync", &flags ))
3378 return NULL;
3379 CHECK_DB_NOT_CLOSED(self);
3380
3381 MYDB_BEGIN_ALLOW_THREADS;
3382 err = self->db->sync(self->db, flags);
3383 MYDB_END_ALLOW_THREADS;
3384 RETURN_IF_ERR();
3385 RETURN_NONE();
3386}
3387
3388
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003389static PyObject*
3390DB_truncate(DBObject* self, PyObject* args, PyObject* kwargs)
3391{
3392 int err, flags=0;
3393 u_int32_t count=0;
3394 PyObject* txnobj = NULL;
3395 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003396 static char* kwnames[] = { "txn", "flags", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003397
3398 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Oi:cursor", kwnames,
3399 &txnobj, &flags))
3400 return NULL;
3401 CHECK_DB_NOT_CLOSED(self);
3402 if (!checkTxnObj(txnobj, &txn))
3403 return NULL;
3404
3405 MYDB_BEGIN_ALLOW_THREADS;
3406 err = self->db->truncate(self->db, txn, &count, flags);
3407 MYDB_END_ALLOW_THREADS;
3408 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00003409 return NUMBER_FromLong(count);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003410}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003411
3412
3413static PyObject*
3414DB_upgrade(DBObject* self, PyObject* args)
3415{
3416 int err, flags=0;
3417 char *filename;
3418
3419 if (!PyArg_ParseTuple(args,"s|i:upgrade", &filename, &flags))
3420 return NULL;
3421 CHECK_DB_NOT_CLOSED(self);
3422
3423 MYDB_BEGIN_ALLOW_THREADS;
3424 err = self->db->upgrade(self->db, filename, flags);
3425 MYDB_END_ALLOW_THREADS;
3426 RETURN_IF_ERR();
3427 RETURN_NONE();
3428}
3429
3430
3431static PyObject*
3432DB_verify(DBObject* self, PyObject* args, PyObject* kwargs)
3433{
3434 int err, flags=0;
3435 char* fileName;
3436 char* dbName=NULL;
3437 char* outFileName=NULL;
3438 FILE* outFile=NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003439 static char* kwnames[] = { "filename", "dbname", "outfile", "flags",
Jeremy Hyltonaf68c872005-12-10 18:50:16 +00003440 NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003441
3442 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|zzi:verify", kwnames,
3443 &fileName, &dbName, &outFileName, &flags))
3444 return NULL;
3445
3446 CHECK_DB_NOT_CLOSED(self);
3447 if (outFileName)
3448 outFile = fopen(outFileName, "w");
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003449 /* XXX(nnorwitz): it should probably be an exception if outFile
3450 can't be opened. */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003451
Jesus Ceaef9764f2008-05-13 18:45:46 +00003452 { /* DB.verify acts as a DB handle destructor (like close) */
3453 PyObject *error;
3454
Jesus Cea5cd5f122008-09-23 18:54:08 +00003455 error=DB_close_internal(self, 0, 1);
Jesus Cea6557aac2010-03-22 14:22:26 +00003456 if (error) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00003457 return error;
3458 }
3459 }
Gregory P. Smith41631e82003-09-21 00:08:14 +00003460
Jesus Cea5cd5f122008-09-23 18:54:08 +00003461 MYDB_BEGIN_ALLOW_THREADS;
3462 err = self->db->verify(self->db, fileName, dbName, outFile, flags);
3463 MYDB_END_ALLOW_THREADS;
3464
3465 self->db = NULL; /* Implicit close; related objects already released */
3466
3467 if (outFile)
3468 fclose(outFile);
3469
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003470 RETURN_IF_ERR();
3471 RETURN_NONE();
3472}
3473
3474
3475static PyObject*
3476DB_set_get_returns_none(DBObject* self, PyObject* args)
3477{
3478 int flags=0;
Gregory P. Smith455d46f2003-07-09 04:45:59 +00003479 int oldValue=0;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003480
3481 if (!PyArg_ParseTuple(args,"i:set_get_returns_none", &flags))
3482 return NULL;
3483 CHECK_DB_NOT_CLOSED(self);
3484
Gregory P. Smith455d46f2003-07-09 04:45:59 +00003485 if (self->moduleFlags.getReturnsNone)
3486 ++oldValue;
3487 if (self->moduleFlags.cursorSetReturnsNone)
3488 ++oldValue;
3489 self->moduleFlags.getReturnsNone = (flags >= 1);
3490 self->moduleFlags.cursorSetReturnsNone = (flags >= 2);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00003491 return NUMBER_FromLong(oldValue);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003492}
3493
Barry Warsaw9a0d7792002-12-30 20:53:52 +00003494static PyObject*
3495DB_set_encrypt(DBObject* self, PyObject* args, PyObject* kwargs)
3496{
3497 int err;
3498 u_int32_t flags=0;
3499 char *passwd = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003500 static char* kwnames[] = { "passwd", "flags", NULL };
Barry Warsaw9a0d7792002-12-30 20:53:52 +00003501
3502 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|i:set_encrypt", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003503 &passwd, &flags)) {
3504 return NULL;
Barry Warsaw9a0d7792002-12-30 20:53:52 +00003505 }
3506
3507 MYDB_BEGIN_ALLOW_THREADS;
3508 err = self->db->set_encrypt(self->db, passwd, flags);
3509 MYDB_END_ALLOW_THREADS;
3510
3511 RETURN_IF_ERR();
3512 RETURN_NONE();
3513}
Jesus Cea6557aac2010-03-22 14:22:26 +00003514
Jesus Cea6557aac2010-03-22 14:22:26 +00003515static PyObject*
3516DB_get_encrypt_flags(DBObject* self)
3517{
3518 int err;
3519 u_int32_t flags;
3520
3521 MYDB_BEGIN_ALLOW_THREADS;
3522 err = self->db->get_encrypt_flags(self->db, &flags);
3523 MYDB_END_ALLOW_THREADS;
3524
3525 RETURN_IF_ERR();
3526
3527 return NUMBER_FromLong(flags);
3528}
Jesus Cea6557aac2010-03-22 14:22:26 +00003529
Barry Warsaw9a0d7792002-12-30 20:53:52 +00003530
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003531
3532/*-------------------------------------------------------------- */
3533/* Mapping and Dictionary-like access routines */
3534
Martin v. Löwis70ee3cc2006-06-12 04:26:31 +00003535Py_ssize_t DB_length(PyObject* _self)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003536{
3537 int err;
Gregory P. Smith3c228b12006-06-05 23:59:37 +00003538 Py_ssize_t size = 0;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003539 void* sp;
Martin v. Löwis70ee3cc2006-06-12 04:26:31 +00003540 DBObject* self = (DBObject*)_self;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003541
3542 if (self->db == NULL) {
Thomas Woutersb3153832006-03-08 01:47:19 +00003543 PyObject *t = Py_BuildValue("(is)", 0, "DB object has been closed");
Jesus Ceac5a11fa2008-07-23 11:38:42 +00003544 if (t) {
3545 PyErr_SetObject(DBError, t);
3546 Py_DECREF(t);
3547 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003548 return -1;
3549 }
3550
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003551 MYDB_BEGIN_ALLOW_THREADS;
Jesus Cea6557aac2010-03-22 14:22:26 +00003552 err = self->db->stat(self->db, /*txnid*/ NULL, &sp, 0);
Jesus Cea6557aac2010-03-22 14:22:26 +00003553 MYDB_END_ALLOW_THREADS;
Gregory P. Smith3c228b12006-06-05 23:59:37 +00003554
3555 /* All the stat structures have matching fields upto the ndata field,
3556 so we can use any of them for the type cast */
3557 size = ((DB_BTREE_STAT*)sp)->bt_ndata;
3558
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003559 if (err)
3560 return -1;
3561
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003562 free(sp);
3563 return size;
3564}
3565
3566
3567PyObject* DB_subscript(DBObject* self, PyObject* keyobj)
3568{
3569 int err;
3570 PyObject* retval;
3571 DBT key;
3572 DBT data;
3573
3574 CHECK_DB_NOT_CLOSED(self);
3575 if (!make_key_dbt(self, keyobj, &key, NULL))
3576 return NULL;
3577
3578 CLEAR_DBT(data);
3579 if (CHECK_DBFLAG(self, DB_THREAD)) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00003580 /* Tell Berkeley DB to malloc the return value (thread safe) */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003581 data.flags = DB_DBT_MALLOC;
3582 }
3583 MYDB_BEGIN_ALLOW_THREADS;
3584 err = self->db->get(self->db, NULL, &key, &data, 0);
3585 MYDB_END_ALLOW_THREADS;
3586 if (err == DB_NOTFOUND || err == DB_KEYEMPTY) {
3587 PyErr_SetObject(PyExc_KeyError, keyobj);
3588 retval = NULL;
3589 }
3590 else if (makeDBError(err)) {
3591 retval = NULL;
3592 }
3593 else {
Jesus Ceaef9764f2008-05-13 18:45:46 +00003594 retval = Build_PyString(data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003595 FREE_DBT(data);
3596 }
3597
3598 FREE_DBT(key);
3599 return retval;
3600}
3601
3602
3603static int
3604DB_ass_sub(DBObject* self, PyObject* keyobj, PyObject* dataobj)
3605{
3606 DBT key, data;
3607 int retval;
3608 int flags = 0;
3609
3610 if (self->db == NULL) {
Thomas Woutersb3153832006-03-08 01:47:19 +00003611 PyObject *t = Py_BuildValue("(is)", 0, "DB object has been closed");
Jesus Ceac5a11fa2008-07-23 11:38:42 +00003612 if (t) {
3613 PyErr_SetObject(DBError, t);
3614 Py_DECREF(t);
3615 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003616 return -1;
3617 }
3618
3619 if (!make_key_dbt(self, keyobj, &key, NULL))
3620 return -1;
3621
3622 if (dataobj != NULL) {
3623 if (!make_dbt(dataobj, &data))
3624 retval = -1;
3625 else {
3626 if (self->setflags & (DB_DUP|DB_DUPSORT))
Barry Warsaw9a0d7792002-12-30 20:53:52 +00003627 /* dictionaries shouldn't have duplicate keys */
3628 flags = DB_NOOVERWRITE;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003629 retval = _DB_put(self, NULL, &key, &data, flags);
3630
3631 if ((retval == -1) && (self->setflags & (DB_DUP|DB_DUPSORT))) {
Barry Warsaw9a0d7792002-12-30 20:53:52 +00003632 /* try deleting any old record that matches and then PUT it
3633 * again... */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003634 _DB_delete(self, NULL, &key, 0);
3635 PyErr_Clear();
3636 retval = _DB_put(self, NULL, &key, &data, flags);
3637 }
3638 }
3639 }
3640 else {
3641 /* dataobj == NULL, so delete the key */
3642 retval = _DB_delete(self, NULL, &key, 0);
3643 }
3644 FREE_DBT(key);
3645 return retval;
3646}
3647
3648
3649static PyObject*
Jesus Cea6557aac2010-03-22 14:22:26 +00003650_DB_has_key(DBObject* self, PyObject* keyobj, PyObject* txnobj)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003651{
3652 int err;
Jesus Cea6557aac2010-03-22 14:22:26 +00003653 DBT key;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003654 DB_TXN *txn = NULL;
Jesus Cea4907d272008-08-31 14:00:51 +00003655
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003656 CHECK_DB_NOT_CLOSED(self);
3657 if (!make_key_dbt(self, keyobj, &key, NULL))
3658 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00003659 if (!checkTxnObj(txnobj, &txn)) {
3660 FREE_DBT(key);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003661 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00003662 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003663
Jesus Cea6557aac2010-03-22 14:22:26 +00003664#if (DBVER < 46)
Gregory P. Smith8b7e9172004-12-13 09:51:23 +00003665 /* This causes DB_BUFFER_SMALL to be returned when the db has the key because
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003666 it has a record but can't allocate a buffer for the data. This saves
3667 having to deal with data we won't be using.
3668 */
Jesus Cea6557aac2010-03-22 14:22:26 +00003669 {
3670 DBT data ;
3671 CLEAR_DBT(data);
3672 data.flags = DB_DBT_USERMEM;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003673
Jesus Cea6557aac2010-03-22 14:22:26 +00003674 MYDB_BEGIN_ALLOW_THREADS;
3675 err = self->db->get(self->db, txn, &key, &data, 0);
3676 MYDB_END_ALLOW_THREADS;
3677 }
3678#else
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003679 MYDB_BEGIN_ALLOW_THREADS;
Jesus Cea6557aac2010-03-22 14:22:26 +00003680 err = self->db->exists(self->db, txn, &key, 0);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003681 MYDB_END_ALLOW_THREADS;
Jesus Cea6557aac2010-03-22 14:22:26 +00003682#endif
3683
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003684 FREE_DBT(key);
Gregory P. Smithe9477062005-06-04 06:46:59 +00003685
Jesus Cea6557aac2010-03-22 14:22:26 +00003686 /*
3687 ** DB_BUFFER_SMALL is only used if we use "get".
3688 ** We can drop it when we only use "exists",
3689 ** when we drop suport for Berkeley DB < 4.6.
3690 */
Gregory P. Smithe9477062005-06-04 06:46:59 +00003691 if (err == DB_BUFFER_SMALL || err == 0) {
Jesus Cea6557aac2010-03-22 14:22:26 +00003692 Py_INCREF(Py_True);
3693 return Py_True;
Gregory P. Smithe9477062005-06-04 06:46:59 +00003694 } else if (err == DB_NOTFOUND || err == DB_KEYEMPTY) {
Jesus Cea6557aac2010-03-22 14:22:26 +00003695 Py_INCREF(Py_False);
3696 return Py_False;
Gregory P. Smithe9477062005-06-04 06:46:59 +00003697 }
3698
3699 makeDBError(err);
3700 return NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003701}
3702
Jesus Cea6557aac2010-03-22 14:22:26 +00003703static PyObject*
3704DB_has_key(DBObject* self, PyObject* args, PyObject* kwargs)
3705{
3706 PyObject* keyobj;
3707 PyObject* txnobj = NULL;
3708 static char* kwnames[] = {"key","txn", NULL};
3709
3710 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O:has_key", kwnames,
3711 &keyobj, &txnobj))
3712 return NULL;
3713
3714 return _DB_has_key(self, keyobj, txnobj);
3715}
3716
3717
3718static int DB_contains(DBObject* self, PyObject* keyobj)
3719{
3720 PyObject* result;
3721 int result2 = 0;
3722
3723 result = _DB_has_key(self, keyobj, NULL) ;
3724 if (result == NULL) {
3725 return -1; /* Propague exception */
3726 }
3727 if (result != Py_False) {
3728 result2 = 1;
3729 }
3730
3731 Py_DECREF(result);
3732 return result2;
3733}
3734
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003735
3736#define _KEYS_LIST 1
3737#define _VALUES_LIST 2
3738#define _ITEMS_LIST 3
3739
3740static PyObject*
3741_DB_make_list(DBObject* self, DB_TXN* txn, int type)
3742{
3743 int err, dbtype;
3744 DBT key;
3745 DBT data;
3746 DBC *cursor;
3747 PyObject* list;
3748 PyObject* item = NULL;
3749
3750 CHECK_DB_NOT_CLOSED(self);
3751 CLEAR_DBT(key);
3752 CLEAR_DBT(data);
3753
3754 dbtype = _DB_get_type(self);
3755 if (dbtype == -1)
3756 return NULL;
3757
3758 list = PyList_New(0);
Thomas Woutersb3153832006-03-08 01:47:19 +00003759 if (list == NULL)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003760 return NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003761
3762 /* get a cursor */
3763 MYDB_BEGIN_ALLOW_THREADS;
Gregory P. Smith442c9fc2004-09-04 01:36:59 +00003764 err = self->db->cursor(self->db, txn, &cursor, 0);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003765 MYDB_END_ALLOW_THREADS;
Thomas Woutersb3153832006-03-08 01:47:19 +00003766 if (makeDBError(err)) {
3767 Py_DECREF(list);
3768 return NULL;
3769 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003770
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003771 while (1) { /* use the cursor to traverse the DB, collecting items */
3772 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00003773 err = _DBC_get(cursor, &key, &data, DB_NEXT);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003774 MYDB_END_ALLOW_THREADS;
3775
3776 if (err) {
3777 /* for any error, break out of the loop */
3778 break;
3779 }
3780
3781 switch (type) {
3782 case _KEYS_LIST:
3783 switch(dbtype) {
3784 case DB_BTREE:
3785 case DB_HASH:
3786 default:
Jesus Ceaef9764f2008-05-13 18:45:46 +00003787 item = Build_PyString(key.data, key.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003788 break;
3789 case DB_RECNO:
3790 case DB_QUEUE:
Jesus Ceac5a11fa2008-07-23 11:38:42 +00003791 item = NUMBER_FromLong(*((db_recno_t*)key.data));
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003792 break;
3793 }
3794 break;
3795
3796 case _VALUES_LIST:
Jesus Ceaef9764f2008-05-13 18:45:46 +00003797 item = Build_PyString(data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003798 break;
3799
3800 case _ITEMS_LIST:
3801 switch(dbtype) {
3802 case DB_BTREE:
3803 case DB_HASH:
3804 default:
Jesus Ceaef9764f2008-05-13 18:45:46 +00003805 item = BuildValue_SS(key.data, key.size, data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003806 break;
3807 case DB_RECNO:
3808 case DB_QUEUE:
Jesus Ceaef9764f2008-05-13 18:45:46 +00003809 item = BuildValue_IS(*((db_recno_t*)key.data), data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003810 break;
3811 }
3812 break;
Thomas Woutersb3153832006-03-08 01:47:19 +00003813 default:
3814 PyErr_Format(PyExc_ValueError, "Unknown key type 0x%x", type);
3815 item = NULL;
3816 break;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003817 }
3818 if (item == NULL) {
3819 Py_DECREF(list);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003820 list = NULL;
3821 goto done;
3822 }
Jesus Ceac5a11fa2008-07-23 11:38:42 +00003823 if (PyList_Append(list, item)) {
3824 Py_DECREF(list);
3825 Py_DECREF(item);
3826 list = NULL;
3827 goto done;
3828 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003829 Py_DECREF(item);
3830 }
3831
Gregory P. Smithe9477062005-06-04 06:46:59 +00003832 /* DB_NOTFOUND || DB_KEYEMPTY is okay, it means we got to the end */
3833 if (err != DB_NOTFOUND && err != DB_KEYEMPTY && makeDBError(err)) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003834 Py_DECREF(list);
3835 list = NULL;
3836 }
3837
3838 done:
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003839 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00003840 _DBC_close(cursor);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003841 MYDB_END_ALLOW_THREADS;
3842 return list;
3843}
3844
3845
3846static PyObject*
3847DB_keys(DBObject* self, PyObject* args)
3848{
3849 PyObject* txnobj = NULL;
3850 DB_TXN *txn = NULL;
3851
Georg Brandl96a8c392006-05-29 21:04:52 +00003852 if (!PyArg_UnpackTuple(args, "keys", 0, 1, &txnobj))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003853 return NULL;
3854 if (!checkTxnObj(txnobj, &txn))
3855 return NULL;
3856 return _DB_make_list(self, txn, _KEYS_LIST);
3857}
3858
3859
3860static PyObject*
3861DB_items(DBObject* self, PyObject* args)
3862{
3863 PyObject* txnobj = NULL;
3864 DB_TXN *txn = NULL;
3865
Georg Brandl96a8c392006-05-29 21:04:52 +00003866 if (!PyArg_UnpackTuple(args, "items", 0, 1, &txnobj))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003867 return NULL;
3868 if (!checkTxnObj(txnobj, &txn))
3869 return NULL;
3870 return _DB_make_list(self, txn, _ITEMS_LIST);
3871}
3872
3873
3874static PyObject*
3875DB_values(DBObject* self, PyObject* args)
3876{
3877 PyObject* txnobj = NULL;
3878 DB_TXN *txn = NULL;
3879
Georg Brandl96a8c392006-05-29 21:04:52 +00003880 if (!PyArg_UnpackTuple(args, "values", 0, 1, &txnobj))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003881 return NULL;
3882 if (!checkTxnObj(txnobj, &txn))
3883 return NULL;
3884 return _DB_make_list(self, txn, _VALUES_LIST);
3885}
3886
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003887/* --------------------------------------------------------------------- */
Jesus Cea6557aac2010-03-22 14:22:26 +00003888/* DBLogCursor methods */
3889
3890
3891static PyObject*
3892DBLogCursor_close_internal(DBLogCursorObject* self)
3893{
3894 int err = 0;
3895
3896 if (self->logc != NULL) {
3897 EXTRACT_FROM_DOUBLE_LINKED_LIST(self);
3898
3899 MYDB_BEGIN_ALLOW_THREADS;
3900 err = self->logc->close(self->logc, 0);
3901 MYDB_END_ALLOW_THREADS;
3902 self->logc = NULL;
3903 }
3904 RETURN_IF_ERR();
3905 RETURN_NONE();
3906}
3907
3908static PyObject*
3909DBLogCursor_close(DBLogCursorObject* self)
3910{
3911 return DBLogCursor_close_internal(self);
3912}
3913
3914
3915static PyObject*
3916_DBLogCursor_get(DBLogCursorObject* self, int flag, DB_LSN *lsn2)
3917{
3918 int err;
3919 DBT data;
3920 DB_LSN lsn = {0, 0};
3921 PyObject *dummy, *retval;
3922
3923 CLEAR_DBT(data);
3924 data.flags = DB_DBT_MALLOC; /* Berkeley DB must do the malloc */
3925
3926 CHECK_LOGCURSOR_NOT_CLOSED(self);
3927
3928 if (lsn2)
3929 lsn = *lsn2;
3930
3931 MYDB_BEGIN_ALLOW_THREADS;
3932 err = self->logc->get(self->logc, &lsn, &data, flag);
3933 MYDB_END_ALLOW_THREADS;
3934
3935 if (err == DB_NOTFOUND) {
3936 Py_INCREF(Py_None);
3937 retval = Py_None;
3938 }
3939 else if (makeDBError(err)) {
3940 retval = NULL;
3941 }
3942 else {
3943 retval = dummy = BuildValue_S(data.data, data.size);
3944 if (dummy) {
3945 retval = Py_BuildValue("(ii)O", lsn.file, lsn.offset, dummy);
3946 Py_DECREF(dummy);
3947 }
3948 }
3949
3950 FREE_DBT(data);
3951 return retval;
3952}
3953
3954static PyObject*
3955DBLogCursor_current(DBLogCursorObject* self)
3956{
3957 return _DBLogCursor_get(self, DB_CURRENT, NULL);
3958}
3959
3960static PyObject*
3961DBLogCursor_first(DBLogCursorObject* self)
3962{
3963 return _DBLogCursor_get(self, DB_FIRST, NULL);
3964}
3965
3966static PyObject*
3967DBLogCursor_last(DBLogCursorObject* self)
3968{
3969 return _DBLogCursor_get(self, DB_LAST, NULL);
3970}
3971
3972static PyObject*
3973DBLogCursor_next(DBLogCursorObject* self)
3974{
3975 return _DBLogCursor_get(self, DB_NEXT, NULL);
3976}
3977
3978static PyObject*
3979DBLogCursor_prev(DBLogCursorObject* self)
3980{
3981 return _DBLogCursor_get(self, DB_PREV, NULL);
3982}
3983
3984static PyObject*
3985DBLogCursor_set(DBLogCursorObject* self, PyObject* args)
3986{
3987 DB_LSN lsn;
3988
3989 if (!PyArg_ParseTuple(args, "(ii):set", &lsn.file, &lsn.offset))
3990 return NULL;
3991
3992 return _DBLogCursor_get(self, DB_SET, &lsn);
3993}
3994
3995
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07003996/* --------------------------------------------------------------------- */
3997/* DBSite methods */
3998
3999
4000#if (DBVER >= 52)
4001static PyObject*
4002DBSite_close_internal(DBSiteObject* self)
4003{
4004 int err = 0;
4005
4006 if (self->site != NULL) {
4007 EXTRACT_FROM_DOUBLE_LINKED_LIST(self);
4008
4009 MYDB_BEGIN_ALLOW_THREADS;
4010 err = self->site->close(self->site);
4011 MYDB_END_ALLOW_THREADS;
4012 self->site = NULL;
4013 }
4014 RETURN_IF_ERR();
4015 RETURN_NONE();
4016}
4017
4018static PyObject*
4019DBSite_close(DBSiteObject* self)
4020{
4021 return DBSite_close_internal(self);
4022}
4023
4024static PyObject*
4025DBSite_remove(DBSiteObject* self)
4026{
4027 int err = 0;
4028
4029 CHECK_SITE_NOT_CLOSED(self);
4030
4031 MYDB_BEGIN_ALLOW_THREADS;
4032 err = self->site->remove(self->site);
4033 MYDB_END_ALLOW_THREADS;
4034
4035 RETURN_IF_ERR();
4036 RETURN_NONE();
4037}
4038
4039static PyObject*
4040DBSite_get_eid(DBSiteObject* self)
4041{
4042 int err = 0;
4043 int eid;
4044
4045 CHECK_SITE_NOT_CLOSED(self);
4046
4047 MYDB_BEGIN_ALLOW_THREADS;
4048 err = self->site->get_eid(self->site, &eid);
4049 MYDB_END_ALLOW_THREADS;
4050
4051 RETURN_IF_ERR();
4052 return NUMBER_FromLong(eid);
4053}
4054
4055static PyObject*
4056DBSite_get_address(DBSiteObject* self)
4057{
4058 int err = 0;
4059 const char *host;
4060 u_int port;
4061
4062 CHECK_SITE_NOT_CLOSED(self);
4063
4064 MYDB_BEGIN_ALLOW_THREADS;
4065 err = self->site->get_address(self->site, &host, &port);
4066 MYDB_END_ALLOW_THREADS;
4067
4068 RETURN_IF_ERR();
4069
4070 return Py_BuildValue("(sI)", host, port);
4071}
4072
4073static PyObject*
4074DBSite_get_config(DBSiteObject* self, PyObject* args, PyObject* kwargs)
4075{
4076 int err = 0;
4077 u_int32_t which, value;
4078 static char* kwnames[] = { "which", NULL };
4079
4080 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i:get_config", kwnames,
4081 &which))
4082 return NULL;
4083
4084 CHECK_SITE_NOT_CLOSED(self);
4085
4086 MYDB_BEGIN_ALLOW_THREADS;
4087 err = self->site->get_config(self->site, which, &value);
4088 MYDB_END_ALLOW_THREADS;
4089
4090 RETURN_IF_ERR();
4091
4092 if (value) {
4093 Py_INCREF(Py_True);
4094 return Py_True;
4095 } else {
4096 Py_INCREF(Py_False);
4097 return Py_False;
4098 }
4099}
4100
4101static PyObject*
4102DBSite_set_config(DBSiteObject* self, PyObject* args, PyObject* kwargs)
4103{
4104 int err = 0;
4105 u_int32_t which, value;
4106 PyObject *valueO;
4107 static char* kwnames[] = { "which", "value", NULL };
4108
4109 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "iO:set_config", kwnames,
4110 &which, &valueO))
4111 return NULL;
4112
4113 CHECK_SITE_NOT_CLOSED(self);
4114
4115 value = PyObject_IsTrue(valueO);
4116
4117 MYDB_BEGIN_ALLOW_THREADS;
4118 err = self->site->set_config(self->site, which, value);
4119 MYDB_END_ALLOW_THREADS;
4120
4121 RETURN_IF_ERR();
4122 RETURN_NONE();
4123}
4124#endif
4125
Jesus Cea6557aac2010-03-22 14:22:26 +00004126
4127/* --------------------------------------------------------------------- */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004128/* DBCursor methods */
4129
4130
4131static PyObject*
Jesus Ceaef9764f2008-05-13 18:45:46 +00004132DBC_close_internal(DBCursorObject* self)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004133{
4134 int err = 0;
4135
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004136 if (self->dbc != NULL) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00004137 EXTRACT_FROM_DOUBLE_LINKED_LIST(self);
4138 if (self->txn) {
4139 EXTRACT_FROM_DOUBLE_LINKED_LIST_TXN(self);
4140 self->txn=NULL;
4141 }
4142
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004143 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004144 err = _DBC_close(self->dbc);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004145 MYDB_END_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004146 self->dbc = NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004147 }
4148 RETURN_IF_ERR();
4149 RETURN_NONE();
4150}
4151
Jesus Ceaef9764f2008-05-13 18:45:46 +00004152static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00004153DBC_close(DBCursorObject* self)
Jesus Ceaef9764f2008-05-13 18:45:46 +00004154{
Jesus Ceaef9764f2008-05-13 18:45:46 +00004155 return DBC_close_internal(self);
4156}
4157
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004158
4159static PyObject*
4160DBC_count(DBCursorObject* self, PyObject* args)
4161{
4162 int err = 0;
4163 db_recno_t count;
4164 int flags = 0;
4165
4166 if (!PyArg_ParseTuple(args, "|i:count", &flags))
4167 return NULL;
4168
4169 CHECK_CURSOR_NOT_CLOSED(self);
4170
4171 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004172 err = _DBC_count(self->dbc, &count, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004173 MYDB_END_ALLOW_THREADS;
4174 RETURN_IF_ERR();
4175
Jesus Ceac5a11fa2008-07-23 11:38:42 +00004176 return NUMBER_FromLong(count);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004177}
4178
4179
4180static PyObject*
4181DBC_current(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4182{
4183 return _DBCursor_get(self,DB_CURRENT,args,kwargs,"|iii:current");
4184}
4185
4186
4187static PyObject*
4188DBC_delete(DBCursorObject* self, PyObject* args)
4189{
4190 int err, flags=0;
4191
4192 if (!PyArg_ParseTuple(args, "|i:delete", &flags))
4193 return NULL;
4194
4195 CHECK_CURSOR_NOT_CLOSED(self);
4196
4197 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004198 err = _DBC_del(self->dbc, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004199 MYDB_END_ALLOW_THREADS;
4200 RETURN_IF_ERR();
4201
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004202 RETURN_NONE();
4203}
4204
4205
4206static PyObject*
4207DBC_dup(DBCursorObject* self, PyObject* args)
4208{
4209 int err, flags =0;
4210 DBC* dbc = NULL;
4211
4212 if (!PyArg_ParseTuple(args, "|i:dup", &flags))
4213 return NULL;
4214
4215 CHECK_CURSOR_NOT_CLOSED(self);
4216
4217 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004218 err = _DBC_dup(self->dbc, &dbc, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004219 MYDB_END_ALLOW_THREADS;
4220 RETURN_IF_ERR();
4221
Jesus Ceaef9764f2008-05-13 18:45:46 +00004222 return (PyObject*) newDBCursorObject(dbc, self->txn, self->mydb);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004223}
4224
4225static PyObject*
4226DBC_first(DBCursorObject* self, PyObject* args, PyObject* kwargs)
4227{
4228 return _DBCursor_get(self,DB_FIRST,args,kwargs,"|iii:first");
4229}
4230
4231
4232static PyObject*
4233DBC_get(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4234{
Martin v. Löwisb2c7aff2002-11-23 11:26:07 +00004235 int err, flags=0;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004236 PyObject* keyobj = NULL;
4237 PyObject* dataobj = NULL;
4238 PyObject* retval = NULL;
4239 int dlen = -1;
4240 int doff = -1;
4241 DBT key, data;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00004242 static char* kwnames[] = { "key","data", "flags", "dlen", "doff",
Jeremy Hyltonaf68c872005-12-10 18:50:16 +00004243 NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004244
4245 CLEAR_DBT(key);
4246 CLEAR_DBT(data);
4247 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|ii:get", &kwnames[2],
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004248 &flags, &dlen, &doff))
Barry Warsaw9a0d7792002-12-30 20:53:52 +00004249 {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004250 PyErr_Clear();
Barry Warsaw9a0d7792002-12-30 20:53:52 +00004251 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Oi|ii:get",
Jesus Cea4907d272008-08-31 14:00:51 +00004252 &kwnames[1],
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004253 &keyobj, &flags, &dlen, &doff))
Barry Warsaw9a0d7792002-12-30 20:53:52 +00004254 {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004255 PyErr_Clear();
Barry Warsaw9a0d7792002-12-30 20:53:52 +00004256 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OOi|ii:get",
4257 kwnames, &keyobj, &dataobj,
4258 &flags, &dlen, &doff))
4259 {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004260 return NULL;
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004261 }
4262 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004263 }
4264
4265 CHECK_CURSOR_NOT_CLOSED(self);
4266
4267 if (keyobj && !make_key_dbt(self->mydb, keyobj, &key, NULL))
4268 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004269 if ( (dataobj && !make_dbt(dataobj, &data)) ||
4270 (!add_partial_dbt(&data, dlen, doff)) )
4271 {
Jesus Ceaef9764f2008-05-13 18:45:46 +00004272 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004273 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004274 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004275
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004276 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004277 err = _DBC_get(self->dbc, &key, &data, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004278 MYDB_END_ALLOW_THREADS;
4279
Gregory P. Smithe9477062005-06-04 06:46:59 +00004280 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004281 && self->mydb->moduleFlags.getReturnsNone) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004282 Py_INCREF(Py_None);
4283 retval = Py_None;
4284 }
4285 else if (makeDBError(err)) {
4286 retval = NULL;
4287 }
4288 else {
4289 switch (_DB_get_type(self->mydb)) {
4290 case -1:
4291 retval = NULL;
4292 break;
4293 case DB_BTREE:
4294 case DB_HASH:
4295 default:
Jesus Ceaef9764f2008-05-13 18:45:46 +00004296 retval = BuildValue_SS(key.data, key.size, data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004297 break;
4298 case DB_RECNO:
4299 case DB_QUEUE:
Jesus Ceaef9764f2008-05-13 18:45:46 +00004300 retval = BuildValue_IS(*((db_recno_t*)key.data), data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004301 break;
4302 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004303 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00004304 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004305 return retval;
4306}
4307
Gregory P. Smith19699a92004-06-28 04:06:49 +00004308static PyObject*
4309DBC_pget(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4310{
4311 int err, flags=0;
4312 PyObject* keyobj = NULL;
4313 PyObject* dataobj = NULL;
4314 PyObject* retval = NULL;
4315 int dlen = -1;
4316 int doff = -1;
4317 DBT key, pkey, data;
Gregory P. Smith372b5832006-06-05 18:48:21 +00004318 static char* kwnames_keyOnly[] = { "key", "flags", "dlen", "doff", NULL };
4319 static char* kwnames[] = { "key", "data", "flags", "dlen", "doff", NULL };
Gregory P. Smith19699a92004-06-28 04:06:49 +00004320
4321 CLEAR_DBT(key);
4322 CLEAR_DBT(data);
4323 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|ii:pget", &kwnames[2],
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004324 &flags, &dlen, &doff))
Gregory P. Smith19699a92004-06-28 04:06:49 +00004325 {
4326 PyErr_Clear();
4327 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Oi|ii:pget",
Jesus Cea6557aac2010-03-22 14:22:26 +00004328 kwnames_keyOnly,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004329 &keyobj, &flags, &dlen, &doff))
Gregory P. Smith19699a92004-06-28 04:06:49 +00004330 {
4331 PyErr_Clear();
4332 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OOi|ii:pget",
4333 kwnames, &keyobj, &dataobj,
4334 &flags, &dlen, &doff))
4335 {
4336 return NULL;
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004337 }
4338 }
Gregory P. Smith19699a92004-06-28 04:06:49 +00004339 }
4340
4341 CHECK_CURSOR_NOT_CLOSED(self);
4342
4343 if (keyobj && !make_key_dbt(self->mydb, keyobj, &key, NULL))
4344 return NULL;
4345 if ( (dataobj && !make_dbt(dataobj, &data)) ||
4346 (!add_partial_dbt(&data, dlen, doff)) ) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00004347 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Gregory P. Smith19699a92004-06-28 04:06:49 +00004348 return NULL;
4349 }
4350
Gregory P. Smith19699a92004-06-28 04:06:49 +00004351 CLEAR_DBT(pkey);
4352 pkey.flags = DB_DBT_MALLOC;
4353
4354 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004355 err = _DBC_pget(self->dbc, &key, &pkey, &data, flags);
Gregory P. Smith19699a92004-06-28 04:06:49 +00004356 MYDB_END_ALLOW_THREADS;
4357
Gregory P. Smithe9477062005-06-04 06:46:59 +00004358 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004359 && self->mydb->moduleFlags.getReturnsNone) {
Gregory P. Smith19699a92004-06-28 04:06:49 +00004360 Py_INCREF(Py_None);
4361 retval = Py_None;
4362 }
4363 else if (makeDBError(err)) {
4364 retval = NULL;
4365 }
4366 else {
4367 PyObject *pkeyObj;
4368 PyObject *dataObj;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004369 dataObj = Build_PyString(data.data, data.size);
Gregory P. Smith19699a92004-06-28 04:06:49 +00004370
4371 if (self->mydb->primaryDBType == DB_RECNO ||
4372 self->mydb->primaryDBType == DB_QUEUE)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00004373 pkeyObj = NUMBER_FromLong(*(int *)pkey.data);
Gregory P. Smith19699a92004-06-28 04:06:49 +00004374 else
Jesus Ceaef9764f2008-05-13 18:45:46 +00004375 pkeyObj = Build_PyString(pkey.data, pkey.size);
Gregory P. Smith19699a92004-06-28 04:06:49 +00004376
Gregory P. Smith4e414d82006-01-24 19:55:02 +00004377 if (key.data && key.size) /* return key, pkey and data */
Gregory P. Smith19699a92004-06-28 04:06:49 +00004378 {
4379 PyObject *keyObj;
4380 int type = _DB_get_type(self->mydb);
4381 if (type == DB_RECNO || type == DB_QUEUE)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00004382 keyObj = NUMBER_FromLong(*(int *)key.data);
Gregory P. Smith19699a92004-06-28 04:06:49 +00004383 else
Jesus Ceaef9764f2008-05-13 18:45:46 +00004384 keyObj = Build_PyString(key.data, key.size);
Gregory P. Smith4e414d82006-01-24 19:55:02 +00004385 retval = PyTuple_Pack(3, keyObj, pkeyObj, dataObj);
Thomas Woutersb3153832006-03-08 01:47:19 +00004386 Py_DECREF(keyObj);
Jesus Ceaef9764f2008-05-13 18:45:46 +00004387 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Gregory P. Smith19699a92004-06-28 04:06:49 +00004388 }
4389 else /* return just the pkey and data */
4390 {
Gregory P. Smith4e414d82006-01-24 19:55:02 +00004391 retval = PyTuple_Pack(2, pkeyObj, dataObj);
Gregory P. Smith19699a92004-06-28 04:06:49 +00004392 }
Thomas Woutersb3153832006-03-08 01:47:19 +00004393 Py_DECREF(dataObj);
4394 Py_DECREF(pkeyObj);
Gregory P. Smith19699a92004-06-28 04:06:49 +00004395 FREE_DBT(pkey);
Gregory P. Smith19699a92004-06-28 04:06:49 +00004396 }
4397 /* the only time REALLOC should be set is if we used an integer
4398 * key that make_key_dbt malloc'd for us. always free these. */
Jesus Ceaef9764f2008-05-13 18:45:46 +00004399 if (key.flags & DB_DBT_REALLOC) { /* 'make_key_dbt' could do a 'malloc' */
Gregory P. Smith19699a92004-06-28 04:06:49 +00004400 FREE_DBT(key);
4401 }
4402 return retval;
4403}
4404
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004405
4406static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00004407DBC_get_recno(DBCursorObject* self)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004408{
4409 int err;
4410 db_recno_t recno;
4411 DBT key;
4412 DBT data;
4413
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004414 CHECK_CURSOR_NOT_CLOSED(self);
4415
4416 CLEAR_DBT(key);
4417 CLEAR_DBT(data);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004418
4419 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004420 err = _DBC_get(self->dbc, &key, &data, DB_GET_RECNO);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004421 MYDB_END_ALLOW_THREADS;
4422 RETURN_IF_ERR();
4423
4424 recno = *((db_recno_t*)data.data);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00004425 return NUMBER_FromLong(recno);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004426}
4427
4428
4429static PyObject*
4430DBC_last(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4431{
4432 return _DBCursor_get(self,DB_LAST,args,kwargs,"|iii:last");
4433}
4434
4435
4436static PyObject*
4437DBC_next(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4438{
4439 return _DBCursor_get(self,DB_NEXT,args,kwargs,"|iii:next");
4440}
4441
4442
4443static PyObject*
4444DBC_prev(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4445{
4446 return _DBCursor_get(self,DB_PREV,args,kwargs,"|iii:prev");
4447}
4448
4449
4450static PyObject*
4451DBC_put(DBCursorObject* self, PyObject* args, PyObject* kwargs)
4452{
4453 int err, flags = 0;
4454 PyObject* keyobj, *dataobj;
4455 DBT key, data;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00004456 static char* kwnames[] = { "key", "data", "flags", "dlen", "doff",
Jeremy Hyltonaf68c872005-12-10 18:50:16 +00004457 NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004458 int dlen = -1;
4459 int doff = -1;
4460
4461 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|iii:put", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004462 &keyobj, &dataobj, &flags, &dlen, &doff))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004463 return NULL;
4464
4465 CHECK_CURSOR_NOT_CLOSED(self);
4466
4467 if (!make_key_dbt(self->mydb, keyobj, &key, NULL))
4468 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004469 if (!make_dbt(dataobj, &data) ||
4470 !add_partial_dbt(&data, dlen, doff) )
4471 {
Jesus Ceaef9764f2008-05-13 18:45:46 +00004472 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004473 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004474 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004475
4476 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004477 err = _DBC_put(self->dbc, &key, &data, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004478 MYDB_END_ALLOW_THREADS;
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_IF_ERR();
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004481 RETURN_NONE();
4482}
4483
4484
4485static PyObject*
4486DBC_set(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4487{
4488 int err, flags = 0;
4489 DBT key, data;
4490 PyObject* retval, *keyobj;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00004491 static char* kwnames[] = { "key", "flags", "dlen", "doff", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004492 int dlen = -1;
4493 int doff = -1;
4494
4495 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|iii:set", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004496 &keyobj, &flags, &dlen, &doff))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004497 return NULL;
4498
4499 CHECK_CURSOR_NOT_CLOSED(self);
4500
4501 if (!make_key_dbt(self->mydb, keyobj, &key, NULL))
4502 return NULL;
4503
4504 CLEAR_DBT(data);
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004505 if (!add_partial_dbt(&data, dlen, doff)) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00004506 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004507 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004508 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004509
4510 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004511 err = _DBC_get(self->dbc, &key, &data, flags|DB_SET);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004512 MYDB_END_ALLOW_THREADS;
Gregory P. Smithe9477062005-06-04 06:46:59 +00004513 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004514 && self->mydb->moduleFlags.cursorSetReturnsNone) {
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004515 Py_INCREF(Py_None);
4516 retval = Py_None;
4517 }
4518 else if (makeDBError(err)) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004519 retval = NULL;
4520 }
4521 else {
4522 switch (_DB_get_type(self->mydb)) {
4523 case -1:
4524 retval = NULL;
4525 break;
4526 case DB_BTREE:
4527 case DB_HASH:
4528 default:
Jesus Ceaef9764f2008-05-13 18:45:46 +00004529 retval = BuildValue_SS(key.data, key.size, data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004530 break;
4531 case DB_RECNO:
4532 case DB_QUEUE:
Jesus Ceaef9764f2008-05-13 18:45:46 +00004533 retval = BuildValue_IS(*((db_recno_t*)key.data), data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004534 break;
4535 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00004536 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004537 }
Gregory P. Smith19699a92004-06-28 04:06:49 +00004538 /* the only time REALLOC should be set is if we used an integer
4539 * key that make_key_dbt malloc'd for us. always free these. */
4540 if (key.flags & DB_DBT_REALLOC) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00004541 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Gregory P. Smith19699a92004-06-28 04:06:49 +00004542 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004543
4544 return retval;
4545}
4546
4547
4548static PyObject*
4549DBC_set_range(DBCursorObject* self, PyObject* args, PyObject* kwargs)
4550{
4551 int err, flags = 0;
4552 DBT key, data;
4553 PyObject* retval, *keyobj;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00004554 static char* kwnames[] = { "key", "flags", "dlen", "doff", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004555 int dlen = -1;
4556 int doff = -1;
4557
4558 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|iii:set_range", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004559 &keyobj, &flags, &dlen, &doff))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004560 return NULL;
4561
4562 CHECK_CURSOR_NOT_CLOSED(self);
4563
4564 if (!make_key_dbt(self->mydb, keyobj, &key, NULL))
4565 return NULL;
4566
4567 CLEAR_DBT(data);
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004568 if (!add_partial_dbt(&data, dlen, doff)) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00004569 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004570 return NULL;
4571 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004572 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004573 err = _DBC_get(self->dbc, &key, &data, flags|DB_SET_RANGE);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004574 MYDB_END_ALLOW_THREADS;
Gregory P. Smithe9477062005-06-04 06:46:59 +00004575 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004576 && self->mydb->moduleFlags.cursorSetReturnsNone) {
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004577 Py_INCREF(Py_None);
4578 retval = Py_None;
4579 }
4580 else if (makeDBError(err)) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004581 retval = NULL;
4582 }
4583 else {
4584 switch (_DB_get_type(self->mydb)) {
4585 case -1:
4586 retval = NULL;
4587 break;
4588 case DB_BTREE:
4589 case DB_HASH:
4590 default:
Jesus Ceaef9764f2008-05-13 18:45:46 +00004591 retval = BuildValue_SS(key.data, key.size, data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004592 break;
4593 case DB_RECNO:
4594 case DB_QUEUE:
Jesus Ceaef9764f2008-05-13 18:45:46 +00004595 retval = BuildValue_IS(*((db_recno_t*)key.data), data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004596 break;
4597 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00004598 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004599 }
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004600 /* the only time REALLOC should be set is if we used an integer
Gregory P. Smith19699a92004-06-28 04:06:49 +00004601 * key that make_key_dbt malloc'd for us. always free these. */
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004602 if (key.flags & DB_DBT_REALLOC) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00004603 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004604 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004605
4606 return retval;
4607}
4608
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004609static PyObject*
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004610_DBC_get_set_both(DBCursorObject* self, PyObject* keyobj, PyObject* dataobj,
4611 int flags, unsigned int returnsNone)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004612{
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004613 int err;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004614 DBT key, data;
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004615 PyObject* retval;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004616
Gregory P. Smith7441e652003-11-03 21:35:31 +00004617 /* the caller did this: CHECK_CURSOR_NOT_CLOSED(self); */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004618 if (!make_key_dbt(self->mydb, keyobj, &key, NULL))
4619 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004620 if (!make_dbt(dataobj, &data)) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00004621 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004622 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004623 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004624
4625 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004626 err = _DBC_get(self->dbc, &key, &data, flags|DB_GET_BOTH);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004627 MYDB_END_ALLOW_THREADS;
Gregory P. Smithe9477062005-06-04 06:46:59 +00004628 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY) && returnsNone) {
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004629 Py_INCREF(Py_None);
4630 retval = Py_None;
4631 }
4632 else if (makeDBError(err)) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004633 retval = NULL;
4634 }
4635 else {
4636 switch (_DB_get_type(self->mydb)) {
4637 case -1:
4638 retval = NULL;
4639 break;
4640 case DB_BTREE:
4641 case DB_HASH:
4642 default:
Jesus Ceaef9764f2008-05-13 18:45:46 +00004643 retval = BuildValue_SS(key.data, key.size, data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004644 break;
4645 case DB_RECNO:
4646 case DB_QUEUE:
Jesus Ceaef9764f2008-05-13 18:45:46 +00004647 retval = BuildValue_IS(*((db_recno_t*)key.data), data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004648 break;
4649 }
4650 }
4651
Jesus Ceaef9764f2008-05-13 18:45:46 +00004652 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004653 return retval;
4654}
4655
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004656static PyObject*
4657DBC_get_both(DBCursorObject* self, PyObject* args)
4658{
4659 int flags=0;
4660 PyObject *keyobj, *dataobj;
4661
4662 if (!PyArg_ParseTuple(args, "OO|i:get_both", &keyobj, &dataobj, &flags))
4663 return NULL;
4664
Gregory P. Smith7441e652003-11-03 21:35:31 +00004665 /* if the cursor is closed, self->mydb may be invalid */
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004666 CHECK_CURSOR_NOT_CLOSED(self);
4667
4668 return _DBC_get_set_both(self, keyobj, dataobj, flags,
4669 self->mydb->moduleFlags.getReturnsNone);
4670}
4671
Gregory P. Smithbe0db8b2003-10-01 06:48:51 +00004672/* Return size of entry */
4673static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00004674DBC_get_current_size(DBCursorObject* self)
Gregory P. Smithbe0db8b2003-10-01 06:48:51 +00004675{
4676 int err, flags=DB_CURRENT;
4677 PyObject* retval = NULL;
4678 DBT key, data;
4679
Gregory P. Smithbe0db8b2003-10-01 06:48:51 +00004680 CHECK_CURSOR_NOT_CLOSED(self);
4681 CLEAR_DBT(key);
4682 CLEAR_DBT(data);
4683
Gregory P. Smith8b7e9172004-12-13 09:51:23 +00004684 /* We don't allocate any memory, forcing a DB_BUFFER_SMALL error and thus
Gregory P. Smithbe0db8b2003-10-01 06:48:51 +00004685 getting the record size. */
4686 data.flags = DB_DBT_USERMEM;
4687 data.ulen = 0;
4688 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004689 err = _DBC_get(self->dbc, &key, &data, flags);
Gregory P. Smithbe0db8b2003-10-01 06:48:51 +00004690 MYDB_END_ALLOW_THREADS;
Gregory P. Smith8b7e9172004-12-13 09:51:23 +00004691 if (err == DB_BUFFER_SMALL || !err) {
4692 /* DB_BUFFER_SMALL means positive size, !err means zero length value */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00004693 retval = NUMBER_FromLong((long)data.size);
Gregory P. Smithbe0db8b2003-10-01 06:48:51 +00004694 err = 0;
4695 }
4696
Gregory P. Smithbe0db8b2003-10-01 06:48:51 +00004697 RETURN_IF_ERR();
4698 return retval;
4699}
4700
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004701static PyObject*
4702DBC_set_both(DBCursorObject* self, PyObject* args)
4703{
4704 int flags=0;
4705 PyObject *keyobj, *dataobj;
4706
4707 if (!PyArg_ParseTuple(args, "OO|i:set_both", &keyobj, &dataobj, &flags))
4708 return NULL;
4709
Gregory P. Smith7441e652003-11-03 21:35:31 +00004710 /* if the cursor is closed, self->mydb may be invalid */
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004711 CHECK_CURSOR_NOT_CLOSED(self);
4712
4713 return _DBC_get_set_both(self, keyobj, dataobj, flags,
4714 self->mydb->moduleFlags.cursorSetReturnsNone);
4715}
4716
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004717
4718static PyObject*
4719DBC_set_recno(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4720{
4721 int err, irecno, flags=0;
4722 db_recno_t recno;
4723 DBT key, data;
4724 PyObject* retval;
4725 int dlen = -1;
4726 int doff = -1;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00004727 static char* kwnames[] = { "recno","flags", "dlen", "doff", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004728
4729 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|iii:set_recno", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004730 &irecno, &flags, &dlen, &doff))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004731 return NULL;
4732
4733 CHECK_CURSOR_NOT_CLOSED(self);
4734
4735 CLEAR_DBT(key);
4736 recno = (db_recno_t) irecno;
Barry Warsaw9a0d7792002-12-30 20:53:52 +00004737 /* use allocated space so DB will be able to realloc room for the real
4738 * key */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004739 key.data = malloc(sizeof(db_recno_t));
4740 if (key.data == NULL) {
4741 PyErr_SetString(PyExc_MemoryError, "Key memory allocation failed");
4742 return NULL;
4743 }
4744 key.size = sizeof(db_recno_t);
4745 key.ulen = key.size;
4746 memcpy(key.data, &recno, sizeof(db_recno_t));
4747 key.flags = DB_DBT_REALLOC;
4748
4749 CLEAR_DBT(data);
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004750 if (!add_partial_dbt(&data, dlen, doff)) {
4751 FREE_DBT(key);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004752 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004753 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004754
4755 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004756 err = _DBC_get(self->dbc, &key, &data, flags|DB_SET_RECNO);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004757 MYDB_END_ALLOW_THREADS;
Gregory P. Smithe9477062005-06-04 06:46:59 +00004758 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004759 && self->mydb->moduleFlags.cursorSetReturnsNone) {
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004760 Py_INCREF(Py_None);
4761 retval = Py_None;
4762 }
4763 else if (makeDBError(err)) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004764 retval = NULL;
4765 }
4766 else { /* Can only be used for BTrees, so no need to return int key */
Jesus Ceaef9764f2008-05-13 18:45:46 +00004767 retval = BuildValue_SS(key.data, key.size, data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004768 }
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004769 FREE_DBT(key);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004770
4771 return retval;
4772}
4773
4774
4775static PyObject*
4776DBC_consume(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4777{
4778 return _DBCursor_get(self,DB_CONSUME,args,kwargs,"|iii:consume");
4779}
4780
4781
4782static PyObject*
4783DBC_next_dup(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4784{
4785 return _DBCursor_get(self,DB_NEXT_DUP,args,kwargs,"|iii:next_dup");
4786}
4787
4788
4789static PyObject*
4790DBC_next_nodup(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4791{
4792 return _DBCursor_get(self,DB_NEXT_NODUP,args,kwargs,"|iii:next_nodup");
4793}
4794
Jesus Cea6557aac2010-03-22 14:22:26 +00004795#if (DBVER >= 46)
4796static PyObject*
4797DBC_prev_dup(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4798{
4799 return _DBCursor_get(self,DB_PREV_DUP,args,kwargs,"|iii:prev_dup");
4800}
4801#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004802
4803static PyObject*
4804DBC_prev_nodup(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4805{
4806 return _DBCursor_get(self,DB_PREV_NODUP,args,kwargs,"|iii:prev_nodup");
4807}
4808
4809
4810static PyObject*
4811DBC_join_item(DBCursorObject* self, PyObject* args)
4812{
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004813 int err, flags=0;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004814 DBT key, data;
4815 PyObject* retval;
4816
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004817 if (!PyArg_ParseTuple(args, "|i:join_item", &flags))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004818 return NULL;
4819
4820 CHECK_CURSOR_NOT_CLOSED(self);
4821
4822 CLEAR_DBT(key);
4823 CLEAR_DBT(data);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004824
4825 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004826 err = _DBC_get(self->dbc, &key, &data, flags | DB_JOIN_ITEM);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004827 MYDB_END_ALLOW_THREADS;
Gregory P. Smithe9477062005-06-04 06:46:59 +00004828 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004829 && self->mydb->moduleFlags.getReturnsNone) {
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004830 Py_INCREF(Py_None);
4831 retval = Py_None;
4832 }
4833 else if (makeDBError(err)) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004834 retval = NULL;
4835 }
4836 else {
Jesus Ceaef9764f2008-05-13 18:45:46 +00004837 retval = BuildValue_S(key.data, key.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004838 }
4839
4840 return retval;
4841}
4842
4843
Jesus Cea6557aac2010-03-22 14:22:26 +00004844#if (DBVER >= 46)
4845static PyObject*
4846DBC_set_priority(DBCursorObject* self, PyObject* args, PyObject* kwargs)
4847{
4848 int err, priority;
4849 static char* kwnames[] = { "priority", NULL };
4850
4851 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i:set_priority", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004852 &priority))
Jesus Cea6557aac2010-03-22 14:22:26 +00004853 return NULL;
4854
4855 CHECK_CURSOR_NOT_CLOSED(self);
4856
4857 MYDB_BEGIN_ALLOW_THREADS;
4858 err = self->dbc->set_priority(self->dbc, priority);
4859 MYDB_END_ALLOW_THREADS;
4860 RETURN_IF_ERR();
4861 RETURN_NONE();
4862}
4863
4864
4865static PyObject*
4866DBC_get_priority(DBCursorObject* self)
4867{
4868 int err;
4869 DB_CACHE_PRIORITY priority;
4870
4871 CHECK_CURSOR_NOT_CLOSED(self);
4872
4873 MYDB_BEGIN_ALLOW_THREADS;
4874 err = self->dbc->get_priority(self->dbc, &priority);
4875 MYDB_END_ALLOW_THREADS;
4876 RETURN_IF_ERR();
4877 return NUMBER_FromLong(priority);
4878}
4879#endif
4880
4881
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004882
4883/* --------------------------------------------------------------------- */
4884/* DBEnv methods */
4885
4886
4887static PyObject*
Jesus Ceaef9764f2008-05-13 18:45:46 +00004888DBEnv_close_internal(DBEnvObject* self, int flags)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004889{
Jesus Ceaef9764f2008-05-13 18:45:46 +00004890 PyObject *dummy;
4891 int err;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004892
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004893 if (!self->closed) { /* Don't close more than once */
Jesus Ceaef9764f2008-05-13 18:45:46 +00004894 while(self->children_txns) {
Jesus Cea6557aac2010-03-22 14:22:26 +00004895 dummy = DBTxn_abort_discard_internal(self->children_txns, 0);
4896 Py_XDECREF(dummy);
Jesus Ceaef9764f2008-05-13 18:45:46 +00004897 }
4898 while(self->children_dbs) {
Jesus Cea6557aac2010-03-22 14:22:26 +00004899 dummy = DB_close_internal(self->children_dbs, 0, 0);
4900 Py_XDECREF(dummy);
4901 }
4902 while(self->children_logcursors) {
4903 dummy = DBLogCursor_close_internal(self->children_logcursors);
4904 Py_XDECREF(dummy);
Jesus Ceaef9764f2008-05-13 18:45:46 +00004905 }
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07004906#if (DBVER >= 52)
4907 while(self->children_sites) {
4908 dummy = DBSite_close_internal(self->children_sites);
4909 Py_XDECREF(dummy);
4910 }
4911#endif
Jesus Ceaac25fab2008-09-03 17:50:32 +00004912 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00004913
Jesus Ceaac25fab2008-09-03 17:50:32 +00004914 self->closed = 1;
4915 if (self->db_env) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004916 MYDB_BEGIN_ALLOW_THREADS;
4917 err = self->db_env->close(self->db_env, flags);
4918 MYDB_END_ALLOW_THREADS;
4919 /* after calling DBEnv->close, regardless of error, this DBEnv
Jesus Ceaef9764f2008-05-13 18:45:46 +00004920 * may not be accessed again (Berkeley DB docs). */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004921 self->db_env = NULL;
4922 RETURN_IF_ERR();
4923 }
4924 RETURN_NONE();
4925}
4926
Jesus Ceaef9764f2008-05-13 18:45:46 +00004927static PyObject*
4928DBEnv_close(DBEnvObject* self, PyObject* args)
4929{
4930 int flags = 0;
4931
4932 if (!PyArg_ParseTuple(args, "|i:close", &flags))
4933 return NULL;
Jesus Cea5cd5f122008-09-23 18:54:08 +00004934 return DBEnv_close_internal(self, flags);
Jesus Ceaef9764f2008-05-13 18:45:46 +00004935}
4936
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004937
4938static PyObject*
4939DBEnv_open(DBEnvObject* self, PyObject* args)
4940{
4941 int err, flags=0, mode=0660;
4942 char *db_home;
4943
4944 if (!PyArg_ParseTuple(args, "z|ii:open", &db_home, &flags, &mode))
4945 return NULL;
4946
4947 CHECK_ENV_NOT_CLOSED(self);
4948
4949 MYDB_BEGIN_ALLOW_THREADS;
4950 err = self->db_env->open(self->db_env, db_home, flags, mode);
4951 MYDB_END_ALLOW_THREADS;
4952 RETURN_IF_ERR();
4953 self->closed = 0;
4954 self->flags = flags;
4955 RETURN_NONE();
4956}
4957
4958
4959static PyObject*
Jesus Cea6557aac2010-03-22 14:22:26 +00004960DBEnv_memp_stat(DBEnvObject* self, PyObject* args, PyObject *kwargs)
4961{
4962 int err;
4963 DB_MPOOL_STAT *gsp;
4964 DB_MPOOL_FSTAT **fsp, **fsp2;
4965 PyObject* d = NULL, *d2, *d3, *r;
4966 u_int32_t flags = 0;
4967 static char* kwnames[] = { "flags", NULL };
4968
4969 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:memp_stat",
4970 kwnames, &flags))
4971 return NULL;
4972
4973 CHECK_ENV_NOT_CLOSED(self);
4974
4975 MYDB_BEGIN_ALLOW_THREADS;
4976 err = self->db_env->memp_stat(self->db_env, &gsp, &fsp, flags);
4977 MYDB_END_ALLOW_THREADS;
4978 RETURN_IF_ERR();
4979
4980 /* Turn the stat structure into a dictionary */
4981 d = PyDict_New();
4982 if (d == NULL) {
4983 if (gsp)
4984 free(gsp);
4985 return NULL;
4986 }
4987
4988#define MAKE_ENTRY(name) _addIntToDict(d, #name, gsp->st_##name)
4989
4990 MAKE_ENTRY(gbytes);
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07004991 MAKE_ENTRY(bytes);
Jesus Cea6557aac2010-03-22 14:22:26 +00004992 MAKE_ENTRY(ncache);
4993#if (DBVER >= 46)
4994 MAKE_ENTRY(max_ncache);
4995#endif
4996 MAKE_ENTRY(regsize);
Jesus Cea6557aac2010-03-22 14:22:26 +00004997 MAKE_ENTRY(mmapsize);
4998 MAKE_ENTRY(maxopenfd);
4999 MAKE_ENTRY(maxwrite);
5000 MAKE_ENTRY(maxwrite_sleep);
Jesus Cea6557aac2010-03-22 14:22:26 +00005001 MAKE_ENTRY(map);
5002 MAKE_ENTRY(cache_hit);
5003 MAKE_ENTRY(cache_miss);
5004 MAKE_ENTRY(page_create);
5005 MAKE_ENTRY(page_in);
5006 MAKE_ENTRY(page_out);
5007 MAKE_ENTRY(ro_evict);
5008 MAKE_ENTRY(rw_evict);
5009 MAKE_ENTRY(page_trickle);
5010 MAKE_ENTRY(pages);
5011 MAKE_ENTRY(page_clean);
5012 MAKE_ENTRY(page_dirty);
5013 MAKE_ENTRY(hash_buckets);
5014 MAKE_ENTRY(hash_searches);
5015 MAKE_ENTRY(hash_longest);
5016 MAKE_ENTRY(hash_examined);
5017 MAKE_ENTRY(hash_nowait);
5018 MAKE_ENTRY(hash_wait);
5019#if (DBVER >= 45)
5020 MAKE_ENTRY(hash_max_nowait);
5021#endif
5022 MAKE_ENTRY(hash_max_wait);
5023 MAKE_ENTRY(region_wait);
5024 MAKE_ENTRY(region_nowait);
5025#if (DBVER >= 45)
5026 MAKE_ENTRY(mvcc_frozen);
5027 MAKE_ENTRY(mvcc_thawed);
5028 MAKE_ENTRY(mvcc_freed);
5029#endif
5030 MAKE_ENTRY(alloc);
5031 MAKE_ENTRY(alloc_buckets);
5032 MAKE_ENTRY(alloc_max_buckets);
5033 MAKE_ENTRY(alloc_pages);
5034 MAKE_ENTRY(alloc_max_pages);
5035#if (DBVER >= 45)
5036 MAKE_ENTRY(io_wait);
5037#endif
5038#if (DBVER >= 48)
5039 MAKE_ENTRY(sync_interrupted);
5040#endif
5041
5042#undef MAKE_ENTRY
5043 free(gsp);
5044
5045 d2 = PyDict_New();
5046 if (d2 == NULL) {
5047 Py_DECREF(d);
5048 if (fsp)
5049 free(fsp);
5050 return NULL;
5051 }
5052#define MAKE_ENTRY(name) _addIntToDict(d3, #name, (*fsp2)->st_##name)
5053 for(fsp2=fsp;*fsp2; fsp2++) {
5054 d3 = PyDict_New();
5055 if (d3 == NULL) {
5056 Py_DECREF(d);
5057 Py_DECREF(d2);
5058 if (fsp)
5059 free(fsp);
5060 return NULL;
5061 }
5062 MAKE_ENTRY(pagesize);
5063 MAKE_ENTRY(cache_hit);
5064 MAKE_ENTRY(cache_miss);
5065 MAKE_ENTRY(map);
5066 MAKE_ENTRY(page_create);
5067 MAKE_ENTRY(page_in);
5068 MAKE_ENTRY(page_out);
5069 if(PyDict_SetItemString(d2, (*fsp2)->file_name, d3)) {
5070 Py_DECREF(d);
5071 Py_DECREF(d2);
5072 Py_DECREF(d3);
5073 if (fsp)
5074 free(fsp);
5075 return NULL;
5076 }
5077 Py_DECREF(d3);
5078 }
5079
5080#undef MAKE_ENTRY
5081 free(fsp);
5082
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07005083 r = PyTuple_Pack(2, d, d2);
Jesus Cea6557aac2010-03-22 14:22:26 +00005084 Py_DECREF(d);
5085 Py_DECREF(d2);
5086 return r;
5087}
5088
Jesus Cea6557aac2010-03-22 14:22:26 +00005089static PyObject*
5090DBEnv_memp_stat_print(DBEnvObject* self, PyObject* args, PyObject *kwargs)
5091{
5092 int err;
5093 int flags=0;
5094 static char* kwnames[] = { "flags", NULL };
5095
5096 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:memp_stat_print",
5097 kwnames, &flags))
5098 {
5099 return NULL;
5100 }
5101 CHECK_ENV_NOT_CLOSED(self);
5102 MYDB_BEGIN_ALLOW_THREADS;
5103 err = self->db_env->memp_stat_print(self->db_env, flags);
5104 MYDB_END_ALLOW_THREADS;
5105 RETURN_IF_ERR();
5106 RETURN_NONE();
5107}
Jesus Cea6557aac2010-03-22 14:22:26 +00005108
5109
5110static PyObject*
5111DBEnv_memp_trickle(DBEnvObject* self, PyObject* args)
5112{
5113 int err, percent, nwrotep;
5114
5115 if (!PyArg_ParseTuple(args, "i:memp_trickle", &percent))
5116 return NULL;
5117 CHECK_ENV_NOT_CLOSED(self);
5118 MYDB_BEGIN_ALLOW_THREADS;
5119 err = self->db_env->memp_trickle(self->db_env, percent, &nwrotep);
5120 MYDB_END_ALLOW_THREADS;
5121 RETURN_IF_ERR();
5122 return NUMBER_FromLong(nwrotep);
5123}
5124
5125static PyObject*
5126DBEnv_memp_sync(DBEnvObject* self, PyObject* args)
5127{
5128 int err;
5129 DB_LSN lsn = {0, 0};
5130 DB_LSN *lsn_p = NULL;
5131
5132 if (!PyArg_ParseTuple(args, "|(ii):memp_sync", &lsn.file, &lsn.offset))
5133 return NULL;
5134 if ((lsn.file!=0) || (lsn.offset!=0)) {
5135 lsn_p = &lsn;
5136 }
5137 CHECK_ENV_NOT_CLOSED(self);
5138 MYDB_BEGIN_ALLOW_THREADS;
5139 err = self->db_env->memp_sync(self->db_env, lsn_p);
5140 MYDB_END_ALLOW_THREADS;
5141 RETURN_IF_ERR();
5142 RETURN_NONE();
5143}
5144
5145static PyObject*
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005146DBEnv_remove(DBEnvObject* self, PyObject* args)
5147{
5148 int err, flags=0;
5149 char *db_home;
5150
5151 if (!PyArg_ParseTuple(args, "s|i:remove", &db_home, &flags))
5152 return NULL;
5153 CHECK_ENV_NOT_CLOSED(self);
5154 MYDB_BEGIN_ALLOW_THREADS;
5155 err = self->db_env->remove(self->db_env, db_home, flags);
5156 MYDB_END_ALLOW_THREADS;
5157 RETURN_IF_ERR();
5158 RETURN_NONE();
5159}
5160
Barry Warsaw9a0d7792002-12-30 20:53:52 +00005161static PyObject*
5162DBEnv_dbremove(DBEnvObject* self, PyObject* args, PyObject* kwargs)
5163{
5164 int err;
5165 u_int32_t flags=0;
5166 char *file = NULL;
5167 char *database = NULL;
5168 PyObject *txnobj = NULL;
5169 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00005170 static char* kwnames[] = { "file", "database", "txn", "flags",
Jeremy Hyltonaf68c872005-12-10 18:50:16 +00005171 NULL };
Barry Warsaw9a0d7792002-12-30 20:53:52 +00005172
Gregory P. Smith641cddf2006-07-28 01:35:25 +00005173 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|zOi:dbremove", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00005174 &file, &database, &txnobj, &flags)) {
5175 return NULL;
Barry Warsaw9a0d7792002-12-30 20:53:52 +00005176 }
5177 if (!checkTxnObj(txnobj, &txn)) {
5178 return NULL;
5179 }
5180 CHECK_ENV_NOT_CLOSED(self);
5181 MYDB_BEGIN_ALLOW_THREADS;
5182 err = self->db_env->dbremove(self->db_env, txn, file, database, flags);
5183 MYDB_END_ALLOW_THREADS;
5184 RETURN_IF_ERR();
5185 RETURN_NONE();
5186}
5187
5188static PyObject*
5189DBEnv_dbrename(DBEnvObject* self, PyObject* args, PyObject* kwargs)
5190{
5191 int err;
5192 u_int32_t flags=0;
5193 char *file = NULL;
5194 char *database = NULL;
5195 char *newname = NULL;
5196 PyObject *txnobj = NULL;
5197 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00005198 static char* kwnames[] = { "file", "database", "newname", "txn",
Jeremy Hyltonaf68c872005-12-10 18:50:16 +00005199 "flags", NULL };
Barry Warsaw9a0d7792002-12-30 20:53:52 +00005200
Gregory P. Smith641cddf2006-07-28 01:35:25 +00005201 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "szs|Oi:dbrename", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00005202 &file, &database, &newname, &txnobj, &flags)) {
5203 return NULL;
Barry Warsaw9a0d7792002-12-30 20:53:52 +00005204 }
5205 if (!checkTxnObj(txnobj, &txn)) {
5206 return NULL;
5207 }
5208 CHECK_ENV_NOT_CLOSED(self);
5209 MYDB_BEGIN_ALLOW_THREADS;
5210 err = self->db_env->dbrename(self->db_env, txn, file, database, newname,
5211 flags);
5212 MYDB_END_ALLOW_THREADS;
5213 RETURN_IF_ERR();
5214 RETURN_NONE();
5215}
5216
Jesus Cea6557aac2010-03-22 14:22:26 +00005217
5218
Barry Warsaw9a0d7792002-12-30 20:53:52 +00005219static PyObject*
5220DBEnv_set_encrypt(DBEnvObject* self, PyObject* args, PyObject* kwargs)
5221{
5222 int err;
5223 u_int32_t flags=0;
5224 char *passwd = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00005225 static char* kwnames[] = { "passwd", "flags", NULL };
Barry Warsaw9a0d7792002-12-30 20:53:52 +00005226
5227 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|i:set_encrypt", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00005228 &passwd, &flags)) {
5229 return NULL;
Barry Warsaw9a0d7792002-12-30 20:53:52 +00005230 }
5231
5232 MYDB_BEGIN_ALLOW_THREADS;
5233 err = self->db_env->set_encrypt(self->db_env, passwd, flags);
5234 MYDB_END_ALLOW_THREADS;
5235
5236 RETURN_IF_ERR();
5237 RETURN_NONE();
5238}
Jesus Cea6557aac2010-03-22 14:22:26 +00005239
Jesus Cea6557aac2010-03-22 14:22:26 +00005240static PyObject*
5241DBEnv_get_encrypt_flags(DBEnvObject* self)
5242{
5243 int err;
5244 u_int32_t flags;
5245
5246 CHECK_ENV_NOT_CLOSED(self);
5247
5248 MYDB_BEGIN_ALLOW_THREADS;
5249 err = self->db_env->get_encrypt_flags(self->db_env, &flags);
5250 MYDB_END_ALLOW_THREADS;
5251
5252 RETURN_IF_ERR();
5253
5254 return NUMBER_FromLong(flags);
5255}
5256
5257static PyObject*
5258DBEnv_get_timeout(DBEnvObject* self, PyObject* args, PyObject* kwargs)
5259{
5260 int err;
5261 int flag;
5262 u_int32_t timeout;
5263 static char* kwnames[] = {"flag", NULL };
5264
5265 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i:get_timeout", kwnames,
5266 &flag)) {
5267 return NULL;
5268 }
5269 CHECK_ENV_NOT_CLOSED(self);
5270
5271 MYDB_BEGIN_ALLOW_THREADS;
5272 err = self->db_env->get_timeout(self->db_env, &timeout, flag);
5273 MYDB_END_ALLOW_THREADS;
5274 RETURN_IF_ERR();
5275 return NUMBER_FromLong(timeout);
5276}
Jesus Cea6557aac2010-03-22 14:22:26 +00005277
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005278
Gregory P. Smithfe11d3e2003-03-27 17:23:29 +00005279static PyObject*
5280DBEnv_set_timeout(DBEnvObject* self, PyObject* args, PyObject* kwargs)
5281{
5282 int err;
5283 u_int32_t flags=0;
5284 u_int32_t timeout = 0;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00005285 static char* kwnames[] = { "timeout", "flags", NULL };
Gregory P. Smithfe11d3e2003-03-27 17:23:29 +00005286
5287 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ii:set_timeout", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00005288 &timeout, &flags)) {
5289 return NULL;
Gregory P. Smithfe11d3e2003-03-27 17:23:29 +00005290 }
5291
5292 MYDB_BEGIN_ALLOW_THREADS;
5293 err = self->db_env->set_timeout(self->db_env, (db_timeout_t)timeout, flags);
5294 MYDB_END_ALLOW_THREADS;
5295
5296 RETURN_IF_ERR();
5297 RETURN_NONE();
5298}
Gregory P. Smithfe11d3e2003-03-27 17:23:29 +00005299
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005300static PyObject*
Gregory P. Smith6676f6e2003-08-28 21:50:30 +00005301DBEnv_set_shm_key(DBEnvObject* self, PyObject* args)
5302{
5303 int err;
5304 long shm_key = 0;
5305
5306 if (!PyArg_ParseTuple(args, "l:set_shm_key", &shm_key))
5307 return NULL;
5308 CHECK_ENV_NOT_CLOSED(self);
5309
5310 err = self->db_env->set_shm_key(self->db_env, shm_key);
5311 RETURN_IF_ERR();
5312 RETURN_NONE();
5313}
5314
Jesus Cea6557aac2010-03-22 14:22:26 +00005315static PyObject*
5316DBEnv_get_shm_key(DBEnvObject* self)
5317{
5318 int err;
5319 long shm_key;
5320
5321 CHECK_ENV_NOT_CLOSED(self);
5322
5323 MYDB_BEGIN_ALLOW_THREADS;
5324 err = self->db_env->get_shm_key(self->db_env, &shm_key);
5325 MYDB_END_ALLOW_THREADS;
5326
5327 RETURN_IF_ERR();
5328
5329 return NUMBER_FromLong(shm_key);
5330}
Jesus Cea6557aac2010-03-22 14:22:26 +00005331
5332#if (DBVER >= 46)
5333static PyObject*
5334DBEnv_set_cache_max(DBEnvObject* self, PyObject* args)
5335{
5336 int err, gbytes, bytes;
5337
5338 if (!PyArg_ParseTuple(args, "ii:set_cache_max",
5339 &gbytes, &bytes))
5340 return NULL;
5341 CHECK_ENV_NOT_CLOSED(self);
5342
5343 MYDB_BEGIN_ALLOW_THREADS;
5344 err = self->db_env->set_cache_max(self->db_env, gbytes, bytes);
5345 MYDB_END_ALLOW_THREADS;
5346 RETURN_IF_ERR();
5347 RETURN_NONE();
5348}
5349
5350static PyObject*
5351DBEnv_get_cache_max(DBEnvObject* self)
5352{
5353 int err;
5354 u_int32_t gbytes, bytes;
5355
5356 CHECK_ENV_NOT_CLOSED(self);
5357
5358 MYDB_BEGIN_ALLOW_THREADS;
5359 err = self->db_env->get_cache_max(self->db_env, &gbytes, &bytes);
5360 MYDB_END_ALLOW_THREADS;
5361
5362 RETURN_IF_ERR();
5363
5364 return Py_BuildValue("(ii)", gbytes, bytes);
5365}
5366#endif
5367
5368#if (DBVER >= 46)
5369static PyObject*
5370DBEnv_set_thread_count(DBEnvObject* self, PyObject* args)
5371{
5372 int err;
5373 u_int32_t count;
5374
5375 if (!PyArg_ParseTuple(args, "i:set_thread_count", &count))
5376 return NULL;
5377 CHECK_ENV_NOT_CLOSED(self);
5378
5379 MYDB_BEGIN_ALLOW_THREADS;
5380 err = self->db_env->set_thread_count(self->db_env, count);
5381 MYDB_END_ALLOW_THREADS;
5382 RETURN_IF_ERR();
5383 RETURN_NONE();
5384}
5385
5386static PyObject*
5387DBEnv_get_thread_count(DBEnvObject* self)
5388{
5389 int err;
5390 u_int32_t count;
5391
5392 CHECK_ENV_NOT_CLOSED(self);
5393
5394 MYDB_BEGIN_ALLOW_THREADS;
5395 err = self->db_env->get_thread_count(self->db_env, &count);
5396 MYDB_END_ALLOW_THREADS;
5397 RETURN_IF_ERR();
5398 return NUMBER_FromLong(count);
5399}
5400#endif
5401
Gregory P. Smith6676f6e2003-08-28 21:50:30 +00005402static PyObject*
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005403DBEnv_set_cachesize(DBEnvObject* self, PyObject* args)
5404{
5405 int err, gbytes=0, bytes=0, ncache=0;
5406
5407 if (!PyArg_ParseTuple(args, "ii|i:set_cachesize",
5408 &gbytes, &bytes, &ncache))
5409 return NULL;
5410 CHECK_ENV_NOT_CLOSED(self);
5411
5412 MYDB_BEGIN_ALLOW_THREADS;
5413 err = self->db_env->set_cachesize(self->db_env, gbytes, bytes, ncache);
5414 MYDB_END_ALLOW_THREADS;
5415 RETURN_IF_ERR();
5416 RETURN_NONE();
5417}
5418
Jesus Cea6557aac2010-03-22 14:22:26 +00005419static PyObject*
5420DBEnv_get_cachesize(DBEnvObject* self)
5421{
5422 int err;
5423 u_int32_t gbytes, bytes;
5424 int ncache;
5425
5426 CHECK_ENV_NOT_CLOSED(self);
5427
5428 MYDB_BEGIN_ALLOW_THREADS;
5429 err = self->db_env->get_cachesize(self->db_env, &gbytes, &bytes, &ncache);
5430 MYDB_END_ALLOW_THREADS;
5431
5432 RETURN_IF_ERR();
5433
5434 return Py_BuildValue("(iii)", gbytes, bytes, ncache);
5435}
Jesus Cea6557aac2010-03-22 14:22:26 +00005436
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005437
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005438static PyObject*
5439DBEnv_set_flags(DBEnvObject* self, PyObject* args)
5440{
5441 int err, flags=0, onoff=0;
5442
5443 if (!PyArg_ParseTuple(args, "ii:set_flags",
5444 &flags, &onoff))
5445 return NULL;
5446 CHECK_ENV_NOT_CLOSED(self);
5447
5448 MYDB_BEGIN_ALLOW_THREADS;
5449 err = self->db_env->set_flags(self->db_env, flags, onoff);
5450 MYDB_END_ALLOW_THREADS;
5451 RETURN_IF_ERR();
5452 RETURN_NONE();
5453}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005454
Jesus Cea6557aac2010-03-22 14:22:26 +00005455static PyObject*
5456DBEnv_get_flags(DBEnvObject* self)
5457{
5458 int err;
5459 u_int32_t flags;
5460
5461 CHECK_ENV_NOT_CLOSED(self);
5462
5463 MYDB_BEGIN_ALLOW_THREADS;
5464 err = self->db_env->get_flags(self->db_env, &flags);
5465 MYDB_END_ALLOW_THREADS;
5466 RETURN_IF_ERR();
5467 return NUMBER_FromLong(flags);
5468}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005469
Jesus Ceaca3939c2008-05-22 15:27:38 +00005470#if (DBVER >= 47)
5471static PyObject*
5472DBEnv_log_set_config(DBEnvObject* self, PyObject* args)
5473{
5474 int err, flags, onoff;
5475
5476 if (!PyArg_ParseTuple(args, "ii:log_set_config",
5477 &flags, &onoff))
5478 return NULL;
5479 CHECK_ENV_NOT_CLOSED(self);
5480
5481 MYDB_BEGIN_ALLOW_THREADS;
5482 err = self->db_env->log_set_config(self->db_env, flags, onoff);
5483 MYDB_END_ALLOW_THREADS;
5484 RETURN_IF_ERR();
5485 RETURN_NONE();
5486}
Jesus Cea6557aac2010-03-22 14:22:26 +00005487
5488static PyObject*
5489DBEnv_log_get_config(DBEnvObject* self, PyObject* args)
5490{
5491 int err, flag, onoff;
5492
5493 if (!PyArg_ParseTuple(args, "i:log_get_config", &flag))
5494 return NULL;
5495 CHECK_ENV_NOT_CLOSED(self);
5496
5497 MYDB_BEGIN_ALLOW_THREADS;
5498 err = self->db_env->log_get_config(self->db_env, flag, &onoff);
5499 MYDB_END_ALLOW_THREADS;
5500 RETURN_IF_ERR();
5501 return PyBool_FromLong(onoff);
5502}
Jesus Ceaca3939c2008-05-22 15:27:38 +00005503#endif /* DBVER >= 47 */
5504
Jesus Cea6557aac2010-03-22 14:22:26 +00005505#if (DBVER >= 44)
5506static PyObject*
5507DBEnv_mutex_set_max(DBEnvObject* self, PyObject* args)
5508{
5509 int err;
5510 int value;
5511
5512 if (!PyArg_ParseTuple(args, "i:mutex_set_max", &value))
5513 return NULL;
5514
5515 CHECK_ENV_NOT_CLOSED(self);
5516
5517 MYDB_BEGIN_ALLOW_THREADS;
5518 err = self->db_env->mutex_set_max(self->db_env, value);
5519 MYDB_END_ALLOW_THREADS;
5520
5521 RETURN_IF_ERR();
5522 RETURN_NONE();
5523}
5524
5525static PyObject*
5526DBEnv_mutex_get_max(DBEnvObject* self)
5527{
5528 int err;
5529 u_int32_t value;
5530
5531 CHECK_ENV_NOT_CLOSED(self);
5532
5533 MYDB_BEGIN_ALLOW_THREADS;
5534 err = self->db_env->mutex_get_max(self->db_env, &value);
5535 MYDB_END_ALLOW_THREADS;
5536
5537 RETURN_IF_ERR();
5538
5539 return NUMBER_FromLong(value);
5540}
5541
5542static PyObject*
5543DBEnv_mutex_set_align(DBEnvObject* self, PyObject* args)
5544{
5545 int err;
5546 int align;
5547
5548 if (!PyArg_ParseTuple(args, "i:mutex_set_align", &align))
5549 return NULL;
5550
5551 CHECK_ENV_NOT_CLOSED(self);
5552
5553 MYDB_BEGIN_ALLOW_THREADS;
5554 err = self->db_env->mutex_set_align(self->db_env, align);
5555 MYDB_END_ALLOW_THREADS;
5556
5557 RETURN_IF_ERR();
5558 RETURN_NONE();
5559}
5560
5561static PyObject*
5562DBEnv_mutex_get_align(DBEnvObject* self)
5563{
5564 int err;
5565 u_int32_t align;
5566
5567 CHECK_ENV_NOT_CLOSED(self);
5568
5569 MYDB_BEGIN_ALLOW_THREADS;
5570 err = self->db_env->mutex_get_align(self->db_env, &align);
5571 MYDB_END_ALLOW_THREADS;
5572
5573 RETURN_IF_ERR();
5574
5575 return NUMBER_FromLong(align);
5576}
5577
5578static PyObject*
5579DBEnv_mutex_set_increment(DBEnvObject* self, PyObject* args)
5580{
5581 int err;
5582 int increment;
5583
5584 if (!PyArg_ParseTuple(args, "i:mutex_set_increment", &increment))
5585 return NULL;
5586
5587 CHECK_ENV_NOT_CLOSED(self);
5588
5589 MYDB_BEGIN_ALLOW_THREADS;
5590 err = self->db_env->mutex_set_increment(self->db_env, increment);
5591 MYDB_END_ALLOW_THREADS;
5592
5593 RETURN_IF_ERR();
5594 RETURN_NONE();
5595}
5596
5597static PyObject*
5598DBEnv_mutex_get_increment(DBEnvObject* self)
5599{
5600 int err;
5601 u_int32_t increment;
5602
5603 CHECK_ENV_NOT_CLOSED(self);
5604
5605 MYDB_BEGIN_ALLOW_THREADS;
5606 err = self->db_env->mutex_get_increment(self->db_env, &increment);
5607 MYDB_END_ALLOW_THREADS;
5608
5609 RETURN_IF_ERR();
5610
5611 return NUMBER_FromLong(increment);
5612}
5613
5614static PyObject*
5615DBEnv_mutex_set_tas_spins(DBEnvObject* self, PyObject* args)
5616{
5617 int err;
5618 int tas_spins;
5619
5620 if (!PyArg_ParseTuple(args, "i:mutex_set_tas_spins", &tas_spins))
5621 return NULL;
5622
5623 CHECK_ENV_NOT_CLOSED(self);
5624
5625 MYDB_BEGIN_ALLOW_THREADS;
5626 err = self->db_env->mutex_set_tas_spins(self->db_env, tas_spins);
5627 MYDB_END_ALLOW_THREADS;
5628
5629 RETURN_IF_ERR();
5630 RETURN_NONE();
5631}
5632
5633static PyObject*
5634DBEnv_mutex_get_tas_spins(DBEnvObject* self)
5635{
5636 int err;
5637 u_int32_t tas_spins;
5638
5639 CHECK_ENV_NOT_CLOSED(self);
5640
5641 MYDB_BEGIN_ALLOW_THREADS;
5642 err = self->db_env->mutex_get_tas_spins(self->db_env, &tas_spins);
5643 MYDB_END_ALLOW_THREADS;
5644
5645 RETURN_IF_ERR();
5646
5647 return NUMBER_FromLong(tas_spins);
5648}
5649#endif
Jesus Ceaca3939c2008-05-22 15:27:38 +00005650
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005651static PyObject*
5652DBEnv_set_data_dir(DBEnvObject* self, PyObject* args)
5653{
5654 int err;
5655 char *dir;
5656
5657 if (!PyArg_ParseTuple(args, "s:set_data_dir", &dir))
5658 return NULL;
5659 CHECK_ENV_NOT_CLOSED(self);
5660
5661 MYDB_BEGIN_ALLOW_THREADS;
5662 err = self->db_env->set_data_dir(self->db_env, dir);
5663 MYDB_END_ALLOW_THREADS;
5664 RETURN_IF_ERR();
5665 RETURN_NONE();
5666}
5667
Jesus Cea6557aac2010-03-22 14:22:26 +00005668static PyObject*
5669DBEnv_get_data_dirs(DBEnvObject* self)
5670{
5671 int err;
5672 PyObject *tuple;
5673 PyObject *item;
5674 const char **dirpp;
5675 int size, i;
5676
5677 CHECK_ENV_NOT_CLOSED(self);
5678
5679 MYDB_BEGIN_ALLOW_THREADS;
5680 err = self->db_env->get_data_dirs(self->db_env, &dirpp);
5681 MYDB_END_ALLOW_THREADS;
5682
5683 RETURN_IF_ERR();
5684
5685 /*
5686 ** Calculate size. Python C API
5687 ** actually allows for tuple resizing,
5688 ** but this is simple enough.
5689 */
5690 for (size=0; *(dirpp+size) ; size++);
5691
5692 tuple = PyTuple_New(size);
5693 if (!tuple)
5694 return NULL;
5695
5696 for (i=0; i<size; i++) {
5697 item = PyBytes_FromString (*(dirpp+i));
5698 if (item == NULL) {
5699 Py_DECREF(tuple);
5700 tuple = NULL;
5701 break;
5702 }
5703 PyTuple_SET_ITEM(tuple, i, item);
5704 }
5705 return tuple;
5706}
Jesus Cea6557aac2010-03-22 14:22:26 +00005707
5708#if (DBVER >= 44)
5709static PyObject*
5710DBEnv_set_lg_filemode(DBEnvObject* self, PyObject* args)
5711{
5712 int err, filemode;
5713
5714 if (!PyArg_ParseTuple(args, "i:set_lg_filemode", &filemode))
5715 return NULL;
5716 CHECK_ENV_NOT_CLOSED(self);
5717
5718 MYDB_BEGIN_ALLOW_THREADS;
5719 err = self->db_env->set_lg_filemode(self->db_env, filemode);
5720 MYDB_END_ALLOW_THREADS;
5721 RETURN_IF_ERR();
5722 RETURN_NONE();
5723}
5724
5725static PyObject*
5726DBEnv_get_lg_filemode(DBEnvObject* self)
5727{
5728 int err, filemode;
5729
5730 CHECK_ENV_NOT_CLOSED(self);
5731
5732 MYDB_BEGIN_ALLOW_THREADS;
5733 err = self->db_env->get_lg_filemode(self->db_env, &filemode);
5734 MYDB_END_ALLOW_THREADS;
5735 RETURN_IF_ERR();
5736 return NUMBER_FromLong(filemode);
5737}
5738#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005739
5740static PyObject*
5741DBEnv_set_lg_bsize(DBEnvObject* self, PyObject* args)
5742{
5743 int err, lg_bsize;
5744
5745 if (!PyArg_ParseTuple(args, "i:set_lg_bsize", &lg_bsize))
5746 return NULL;
5747 CHECK_ENV_NOT_CLOSED(self);
5748
5749 MYDB_BEGIN_ALLOW_THREADS;
5750 err = self->db_env->set_lg_bsize(self->db_env, lg_bsize);
5751 MYDB_END_ALLOW_THREADS;
5752 RETURN_IF_ERR();
5753 RETURN_NONE();
5754}
5755
Jesus Cea6557aac2010-03-22 14:22:26 +00005756static PyObject*
5757DBEnv_get_lg_bsize(DBEnvObject* self)
5758{
5759 int err;
5760 u_int32_t lg_bsize;
5761
5762 CHECK_ENV_NOT_CLOSED(self);
5763
5764 MYDB_BEGIN_ALLOW_THREADS;
5765 err = self->db_env->get_lg_bsize(self->db_env, &lg_bsize);
5766 MYDB_END_ALLOW_THREADS;
5767 RETURN_IF_ERR();
5768 return NUMBER_FromLong(lg_bsize);
5769}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005770
5771static PyObject*
5772DBEnv_set_lg_dir(DBEnvObject* self, PyObject* args)
5773{
5774 int err;
5775 char *dir;
5776
5777 if (!PyArg_ParseTuple(args, "s:set_lg_dir", &dir))
5778 return NULL;
5779 CHECK_ENV_NOT_CLOSED(self);
5780
5781 MYDB_BEGIN_ALLOW_THREADS;
5782 err = self->db_env->set_lg_dir(self->db_env, dir);
5783 MYDB_END_ALLOW_THREADS;
5784 RETURN_IF_ERR();
5785 RETURN_NONE();
5786}
5787
Jesus Cea6557aac2010-03-22 14:22:26 +00005788static PyObject*
5789DBEnv_get_lg_dir(DBEnvObject* self)
5790{
5791 int err;
5792 const char *dirp;
5793
5794 CHECK_ENV_NOT_CLOSED(self);
5795
5796 MYDB_BEGIN_ALLOW_THREADS;
5797 err = self->db_env->get_lg_dir(self->db_env, &dirp);
5798 MYDB_END_ALLOW_THREADS;
5799 RETURN_IF_ERR();
5800 return PyBytes_FromString(dirp);
5801}
Jesus Cea6557aac2010-03-22 14:22:26 +00005802
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005803static PyObject*
5804DBEnv_set_lg_max(DBEnvObject* self, PyObject* args)
5805{
5806 int err, lg_max;
5807
5808 if (!PyArg_ParseTuple(args, "i:set_lg_max", &lg_max))
5809 return NULL;
5810 CHECK_ENV_NOT_CLOSED(self);
5811
5812 MYDB_BEGIN_ALLOW_THREADS;
5813 err = self->db_env->set_lg_max(self->db_env, lg_max);
5814 MYDB_END_ALLOW_THREADS;
5815 RETURN_IF_ERR();
5816 RETURN_NONE();
5817}
5818
Jesus Ceaef9764f2008-05-13 18:45:46 +00005819static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00005820DBEnv_get_lg_max(DBEnvObject* self)
Jesus Ceaef9764f2008-05-13 18:45:46 +00005821{
5822 int err;
5823 u_int32_t lg_max;
5824
Jesus Ceaef9764f2008-05-13 18:45:46 +00005825 CHECK_ENV_NOT_CLOSED(self);
5826
5827 MYDB_BEGIN_ALLOW_THREADS;
5828 err = self->db_env->get_lg_max(self->db_env, &lg_max);
5829 MYDB_END_ALLOW_THREADS;
5830 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00005831 return NUMBER_FromLong(lg_max);
Jesus Ceaef9764f2008-05-13 18:45:46 +00005832}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005833
5834static PyObject*
Gregory P. Smithe9477062005-06-04 06:46:59 +00005835DBEnv_set_lg_regionmax(DBEnvObject* self, PyObject* args)
5836{
5837 int err, lg_max;
5838
5839 if (!PyArg_ParseTuple(args, "i:set_lg_regionmax", &lg_max))
5840 return NULL;
5841 CHECK_ENV_NOT_CLOSED(self);
5842
5843 MYDB_BEGIN_ALLOW_THREADS;
5844 err = self->db_env->set_lg_regionmax(self->db_env, lg_max);
5845 MYDB_END_ALLOW_THREADS;
5846 RETURN_IF_ERR();
5847 RETURN_NONE();
5848}
5849
Jesus Cea6557aac2010-03-22 14:22:26 +00005850static PyObject*
5851DBEnv_get_lg_regionmax(DBEnvObject* self)
5852{
5853 int err;
5854 u_int32_t lg_regionmax;
5855
5856 CHECK_ENV_NOT_CLOSED(self);
5857
5858 MYDB_BEGIN_ALLOW_THREADS;
5859 err = self->db_env->get_lg_regionmax(self->db_env, &lg_regionmax);
5860 MYDB_END_ALLOW_THREADS;
5861 RETURN_IF_ERR();
5862 return NUMBER_FromLong(lg_regionmax);
5863}
Jesus Cea6557aac2010-03-22 14:22:26 +00005864
5865#if (DBVER >= 47)
5866static PyObject*
5867DBEnv_set_lk_partitions(DBEnvObject* self, PyObject* args)
5868{
5869 int err, lk_partitions;
5870
5871 if (!PyArg_ParseTuple(args, "i:set_lk_partitions", &lk_partitions))
5872 return NULL;
5873 CHECK_ENV_NOT_CLOSED(self);
5874
5875 MYDB_BEGIN_ALLOW_THREADS;
5876 err = self->db_env->set_lk_partitions(self->db_env, lk_partitions);
5877 MYDB_END_ALLOW_THREADS;
5878 RETURN_IF_ERR();
5879 RETURN_NONE();
5880}
5881
5882static PyObject*
5883DBEnv_get_lk_partitions(DBEnvObject* self)
5884{
5885 int err;
5886 u_int32_t lk_partitions;
5887
5888 CHECK_ENV_NOT_CLOSED(self);
5889
5890 MYDB_BEGIN_ALLOW_THREADS;
5891 err = self->db_env->get_lk_partitions(self->db_env, &lk_partitions);
5892 MYDB_END_ALLOW_THREADS;
5893 RETURN_IF_ERR();
5894 return NUMBER_FromLong(lk_partitions);
5895}
5896#endif
Gregory P. Smithe9477062005-06-04 06:46:59 +00005897
5898static PyObject*
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005899DBEnv_set_lk_detect(DBEnvObject* self, PyObject* args)
5900{
5901 int err, lk_detect;
5902
5903 if (!PyArg_ParseTuple(args, "i:set_lk_detect", &lk_detect))
5904 return NULL;
5905 CHECK_ENV_NOT_CLOSED(self);
5906
5907 MYDB_BEGIN_ALLOW_THREADS;
5908 err = self->db_env->set_lk_detect(self->db_env, lk_detect);
5909 MYDB_END_ALLOW_THREADS;
5910 RETURN_IF_ERR();
5911 RETURN_NONE();
5912}
5913
Jesus Cea6557aac2010-03-22 14:22:26 +00005914static PyObject*
5915DBEnv_get_lk_detect(DBEnvObject* self)
5916{
5917 int err;
5918 u_int32_t lk_detect;
5919
5920 CHECK_ENV_NOT_CLOSED(self);
5921
5922 MYDB_BEGIN_ALLOW_THREADS;
5923 err = self->db_env->get_lk_detect(self->db_env, &lk_detect);
5924 MYDB_END_ALLOW_THREADS;
5925 RETURN_IF_ERR();
5926 return NUMBER_FromLong(lk_detect);
5927}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005928
Gregory P. Smith8b96a352007-01-05 01:59:42 +00005929#if (DBVER < 45)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005930static PyObject*
5931DBEnv_set_lk_max(DBEnvObject* self, PyObject* args)
5932{
5933 int err, max;
5934
5935 if (!PyArg_ParseTuple(args, "i:set_lk_max", &max))
5936 return NULL;
5937 CHECK_ENV_NOT_CLOSED(self);
5938
5939 MYDB_BEGIN_ALLOW_THREADS;
5940 err = self->db_env->set_lk_max(self->db_env, max);
5941 MYDB_END_ALLOW_THREADS;
5942 RETURN_IF_ERR();
5943 RETURN_NONE();
5944}
Gregory P. Smith8b96a352007-01-05 01:59:42 +00005945#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005946
5947
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005948
5949static PyObject*
5950DBEnv_set_lk_max_locks(DBEnvObject* self, PyObject* args)
5951{
5952 int err, max;
5953
5954 if (!PyArg_ParseTuple(args, "i:set_lk_max_locks", &max))
5955 return NULL;
5956 CHECK_ENV_NOT_CLOSED(self);
5957
5958 MYDB_BEGIN_ALLOW_THREADS;
5959 err = self->db_env->set_lk_max_locks(self->db_env, max);
5960 MYDB_END_ALLOW_THREADS;
5961 RETURN_IF_ERR();
5962 RETURN_NONE();
5963}
5964
Jesus Cea6557aac2010-03-22 14:22:26 +00005965static PyObject*
5966DBEnv_get_lk_max_locks(DBEnvObject* self)
5967{
5968 int err;
5969 u_int32_t lk_max;
5970
5971 CHECK_ENV_NOT_CLOSED(self);
5972
5973 MYDB_BEGIN_ALLOW_THREADS;
5974 err = self->db_env->get_lk_max_locks(self->db_env, &lk_max);
5975 MYDB_END_ALLOW_THREADS;
5976 RETURN_IF_ERR();
5977 return NUMBER_FromLong(lk_max);
5978}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005979
5980static PyObject*
5981DBEnv_set_lk_max_lockers(DBEnvObject* self, PyObject* args)
5982{
5983 int err, max;
5984
5985 if (!PyArg_ParseTuple(args, "i:set_lk_max_lockers", &max))
5986 return NULL;
5987 CHECK_ENV_NOT_CLOSED(self);
5988
5989 MYDB_BEGIN_ALLOW_THREADS;
5990 err = self->db_env->set_lk_max_lockers(self->db_env, max);
5991 MYDB_END_ALLOW_THREADS;
5992 RETURN_IF_ERR();
5993 RETURN_NONE();
5994}
5995
Jesus Cea6557aac2010-03-22 14:22:26 +00005996static PyObject*
5997DBEnv_get_lk_max_lockers(DBEnvObject* self)
5998{
5999 int err;
6000 u_int32_t lk_max;
6001
6002 CHECK_ENV_NOT_CLOSED(self);
6003
6004 MYDB_BEGIN_ALLOW_THREADS;
6005 err = self->db_env->get_lk_max_lockers(self->db_env, &lk_max);
6006 MYDB_END_ALLOW_THREADS;
6007 RETURN_IF_ERR();
6008 return NUMBER_FromLong(lk_max);
6009}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006010
6011static PyObject*
6012DBEnv_set_lk_max_objects(DBEnvObject* self, PyObject* args)
6013{
6014 int err, max;
6015
6016 if (!PyArg_ParseTuple(args, "i:set_lk_max_objects", &max))
6017 return NULL;
6018 CHECK_ENV_NOT_CLOSED(self);
6019
6020 MYDB_BEGIN_ALLOW_THREADS;
6021 err = self->db_env->set_lk_max_objects(self->db_env, max);
6022 MYDB_END_ALLOW_THREADS;
6023 RETURN_IF_ERR();
6024 RETURN_NONE();
6025}
6026
Jesus Cea6557aac2010-03-22 14:22:26 +00006027static PyObject*
6028DBEnv_get_lk_max_objects(DBEnvObject* self)
6029{
6030 int err;
6031 u_int32_t lk_max;
6032
6033 CHECK_ENV_NOT_CLOSED(self);
6034
6035 MYDB_BEGIN_ALLOW_THREADS;
6036 err = self->db_env->get_lk_max_objects(self->db_env, &lk_max);
6037 MYDB_END_ALLOW_THREADS;
6038 RETURN_IF_ERR();
6039 return NUMBER_FromLong(lk_max);
6040}
Jesus Cea6557aac2010-03-22 14:22:26 +00006041
Jesus Cea6557aac2010-03-22 14:22:26 +00006042static PyObject*
6043DBEnv_get_mp_mmapsize(DBEnvObject* self)
6044{
6045 int err;
6046 size_t mmapsize;
6047
6048 CHECK_ENV_NOT_CLOSED(self);
6049
6050 MYDB_BEGIN_ALLOW_THREADS;
6051 err = self->db_env->get_mp_mmapsize(self->db_env, &mmapsize);
6052 MYDB_END_ALLOW_THREADS;
6053 RETURN_IF_ERR();
6054 return NUMBER_FromLong(mmapsize);
6055}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006056
6057static PyObject*
6058DBEnv_set_mp_mmapsize(DBEnvObject* self, PyObject* args)
6059{
6060 int err, mp_mmapsize;
6061
6062 if (!PyArg_ParseTuple(args, "i:set_mp_mmapsize", &mp_mmapsize))
6063 return NULL;
6064 CHECK_ENV_NOT_CLOSED(self);
6065
6066 MYDB_BEGIN_ALLOW_THREADS;
6067 err = self->db_env->set_mp_mmapsize(self->db_env, mp_mmapsize);
6068 MYDB_END_ALLOW_THREADS;
6069 RETURN_IF_ERR();
6070 RETURN_NONE();
6071}
6072
6073
6074static PyObject*
6075DBEnv_set_tmp_dir(DBEnvObject* self, PyObject* args)
6076{
6077 int err;
6078 char *dir;
6079
6080 if (!PyArg_ParseTuple(args, "s:set_tmp_dir", &dir))
6081 return NULL;
6082 CHECK_ENV_NOT_CLOSED(self);
6083
6084 MYDB_BEGIN_ALLOW_THREADS;
6085 err = self->db_env->set_tmp_dir(self->db_env, dir);
6086 MYDB_END_ALLOW_THREADS;
6087 RETURN_IF_ERR();
6088 RETURN_NONE();
6089}
6090
Jesus Cea6557aac2010-03-22 14:22:26 +00006091static PyObject*
6092DBEnv_get_tmp_dir(DBEnvObject* self)
6093{
6094 int err;
6095 const char *dirpp;
6096
6097 CHECK_ENV_NOT_CLOSED(self);
6098
6099 MYDB_BEGIN_ALLOW_THREADS;
6100 err = self->db_env->get_tmp_dir(self->db_env, &dirpp);
6101 MYDB_END_ALLOW_THREADS;
6102
6103 RETURN_IF_ERR();
6104
6105 return PyBytes_FromString(dirpp);
6106}
Jesus Cea6557aac2010-03-22 14:22:26 +00006107
Jesus Ceaef9764f2008-05-13 18:45:46 +00006108static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00006109DBEnv_txn_recover(DBEnvObject* self)
Jesus Ceaef9764f2008-05-13 18:45:46 +00006110{
6111 int flags = DB_FIRST;
6112 int err, i;
6113 PyObject *list, *tuple, *gid;
6114 DBTxnObject *txn;
6115#define PREPLIST_LEN 16
6116 DB_PREPLIST preplist[PREPLIST_LEN];
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07006117#if (DBVER < 48) || (DBVER >= 52)
Jesus Ceaef9764f2008-05-13 18:45:46 +00006118 long retp;
Matthias Klose54cc5392010-03-15 12:46:18 +00006119#else
6120 u_int32_t retp;
6121#endif
Jesus Ceaef9764f2008-05-13 18:45:46 +00006122
Jesus Ceaef9764f2008-05-13 18:45:46 +00006123 CHECK_ENV_NOT_CLOSED(self);
6124
6125 list=PyList_New(0);
6126 if (!list)
6127 return NULL;
6128 while (!0) {
6129 MYDB_BEGIN_ALLOW_THREADS
6130 err=self->db_env->txn_recover(self->db_env,
6131 preplist, PREPLIST_LEN, &retp, flags);
6132#undef PREPLIST_LEN
6133 MYDB_END_ALLOW_THREADS
6134 if (err) {
6135 Py_DECREF(list);
6136 RETURN_IF_ERR();
6137 }
6138 if (!retp) break;
6139 flags=DB_NEXT; /* Prepare for next loop pass */
6140 for (i=0; i<retp; i++) {
Christian Heimes593daf52008-05-26 12:51:38 +00006141 gid=PyBytes_FromStringAndSize((char *)(preplist[i].gid),
Matthias Klose54cc5392010-03-15 12:46:18 +00006142 DB_GID_SIZE);
Jesus Ceaef9764f2008-05-13 18:45:46 +00006143 if (!gid) {
6144 Py_DECREF(list);
6145 return NULL;
6146 }
Jesus Cea6557aac2010-03-22 14:22:26 +00006147 txn=newDBTxnObject(self, NULL, preplist[i].txn, 0);
Jesus Ceaef9764f2008-05-13 18:45:46 +00006148 if (!txn) {
6149 Py_DECREF(list);
6150 Py_DECREF(gid);
6151 return NULL;
6152 }
6153 txn->flag_prepare=1; /* Recover state */
6154 tuple=PyTuple_New(2);
6155 if (!tuple) {
6156 Py_DECREF(list);
6157 Py_DECREF(gid);
6158 Py_DECREF(txn);
6159 return NULL;
6160 }
6161 if (PyTuple_SetItem(tuple, 0, gid)) {
6162 Py_DECREF(list);
6163 Py_DECREF(gid);
6164 Py_DECREF(txn);
6165 Py_DECREF(tuple);
6166 return NULL;
6167 }
6168 if (PyTuple_SetItem(tuple, 1, (PyObject *)txn)) {
6169 Py_DECREF(list);
6170 Py_DECREF(txn);
6171 Py_DECREF(tuple); /* This delete the "gid" also */
6172 return NULL;
6173 }
6174 if (PyList_Append(list, tuple)) {
6175 Py_DECREF(list);
6176 Py_DECREF(tuple);/* This delete the "gid" and the "txn" also */
6177 return NULL;
6178 }
6179 Py_DECREF(tuple);
6180 }
6181 }
6182 return list;
6183}
Jesus Ceaef9764f2008-05-13 18:45:46 +00006184
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006185static PyObject*
6186DBEnv_txn_begin(DBEnvObject* self, PyObject* args, PyObject* kwargs)
6187{
6188 int flags = 0;
6189 PyObject* txnobj = NULL;
6190 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00006191 static char* kwnames[] = { "parent", "flags", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006192
6193 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Oi:txn_begin", kwnames,
6194 &txnobj, &flags))
6195 return NULL;
6196
6197 if (!checkTxnObj(txnobj, &txn))
6198 return NULL;
6199 CHECK_ENV_NOT_CLOSED(self);
6200
Jesus Ceaef9764f2008-05-13 18:45:46 +00006201 return (PyObject*)newDBTxnObject(self, (DBTxnObject *)txnobj, NULL, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006202}
6203
6204
6205static PyObject*
6206DBEnv_txn_checkpoint(DBEnvObject* self, PyObject* args)
6207{
6208 int err, kbyte=0, min=0, flags=0;
6209
6210 if (!PyArg_ParseTuple(args, "|iii:txn_checkpoint", &kbyte, &min, &flags))
6211 return NULL;
6212 CHECK_ENV_NOT_CLOSED(self);
6213
6214 MYDB_BEGIN_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006215 err = self->db_env->txn_checkpoint(self->db_env, kbyte, min, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006216 MYDB_END_ALLOW_THREADS;
6217 RETURN_IF_ERR();
6218 RETURN_NONE();
6219}
6220
Jesus Cea6557aac2010-03-22 14:22:26 +00006221static PyObject*
6222DBEnv_get_tx_max(DBEnvObject* self)
6223{
6224 int err;
6225 u_int32_t max;
6226
6227 CHECK_ENV_NOT_CLOSED(self);
6228
6229 MYDB_BEGIN_ALLOW_THREADS;
6230 err = self->db_env->get_tx_max(self->db_env, &max);
6231 MYDB_END_ALLOW_THREADS;
6232 RETURN_IF_ERR();
6233 return PyLong_FromUnsignedLong(max);
6234}
Jesus Cea6557aac2010-03-22 14:22:26 +00006235
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006236static PyObject*
6237DBEnv_set_tx_max(DBEnvObject* self, PyObject* args)
6238{
6239 int err, max;
6240
6241 if (!PyArg_ParseTuple(args, "i:set_tx_max", &max))
6242 return NULL;
6243 CHECK_ENV_NOT_CLOSED(self);
6244
Jesus Cea6557aac2010-03-22 14:22:26 +00006245 MYDB_BEGIN_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006246 err = self->db_env->set_tx_max(self->db_env, max);
Jesus Cea6557aac2010-03-22 14:22:26 +00006247 MYDB_END_ALLOW_THREADS;
Gregory P. Smith8a474042006-01-27 07:05:40 +00006248 RETURN_IF_ERR();
6249 RETURN_NONE();
6250}
6251
Jesus Cea6557aac2010-03-22 14:22:26 +00006252static PyObject*
6253DBEnv_get_tx_timestamp(DBEnvObject* self)
6254{
6255 int err;
6256 time_t timestamp;
6257
6258 CHECK_ENV_NOT_CLOSED(self);
6259
6260 MYDB_BEGIN_ALLOW_THREADS;
6261 err = self->db_env->get_tx_timestamp(self->db_env, &timestamp);
6262 MYDB_END_ALLOW_THREADS;
6263 RETURN_IF_ERR();
6264 return NUMBER_FromLong(timestamp);
6265}
Jesus Cea6557aac2010-03-22 14:22:26 +00006266
Gregory P. Smith8a474042006-01-27 07:05:40 +00006267static PyObject*
6268DBEnv_set_tx_timestamp(DBEnvObject* self, PyObject* args)
6269{
6270 int err;
Thomas Wouters9d63cca2006-03-01 01:01:55 +00006271 long stamp;
6272 time_t timestamp;
Gregory P. Smith8a474042006-01-27 07:05:40 +00006273
Thomas Wouters9d63cca2006-03-01 01:01:55 +00006274 if (!PyArg_ParseTuple(args, "l:set_tx_timestamp", &stamp))
Gregory P. Smith8a474042006-01-27 07:05:40 +00006275 return NULL;
6276 CHECK_ENV_NOT_CLOSED(self);
Thomas Wouters9d63cca2006-03-01 01:01:55 +00006277 timestamp = (time_t)stamp;
Jesus Cea6557aac2010-03-22 14:22:26 +00006278 MYDB_BEGIN_ALLOW_THREADS;
Thomas Wouters9d63cca2006-03-01 01:01:55 +00006279 err = self->db_env->set_tx_timestamp(self->db_env, &timestamp);
Jesus Cea6557aac2010-03-22 14:22:26 +00006280 MYDB_END_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006281 RETURN_IF_ERR();
6282 RETURN_NONE();
6283}
6284
6285
6286static PyObject*
6287DBEnv_lock_detect(DBEnvObject* self, PyObject* args)
6288{
6289 int err, atype, flags=0;
6290 int aborted = 0;
6291
6292 if (!PyArg_ParseTuple(args, "i|i:lock_detect", &atype, &flags))
6293 return NULL;
6294 CHECK_ENV_NOT_CLOSED(self);
6295
6296 MYDB_BEGIN_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006297 err = self->db_env->lock_detect(self->db_env, flags, atype, &aborted);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006298 MYDB_END_ALLOW_THREADS;
6299 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00006300 return NUMBER_FromLong(aborted);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006301}
6302
6303
6304static PyObject*
6305DBEnv_lock_get(DBEnvObject* self, PyObject* args)
6306{
6307 int flags=0;
6308 int locker, lock_mode;
6309 DBT obj;
6310 PyObject* objobj;
6311
6312 if (!PyArg_ParseTuple(args, "iOi|i:lock_get", &locker, &objobj, &lock_mode, &flags))
6313 return NULL;
6314
6315
6316 if (!make_dbt(objobj, &obj))
6317 return NULL;
6318
6319 return (PyObject*)newDBLockObject(self, locker, &obj, lock_mode, flags);
6320}
6321
6322
6323static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00006324DBEnv_lock_id(DBEnvObject* self)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006325{
6326 int err;
6327 u_int32_t theID;
6328
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006329 CHECK_ENV_NOT_CLOSED(self);
6330 MYDB_BEGIN_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006331 err = self->db_env->lock_id(self->db_env, &theID);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006332 MYDB_END_ALLOW_THREADS;
6333 RETURN_IF_ERR();
6334
Jesus Ceac5a11fa2008-07-23 11:38:42 +00006335 return NUMBER_FromLong((long)theID);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006336}
6337
Gregory P. Smithac11e022007-11-05 02:56:31 +00006338static PyObject*
6339DBEnv_lock_id_free(DBEnvObject* self, PyObject* args)
6340{
6341 int err;
6342 u_int32_t theID;
6343
6344 if (!PyArg_ParseTuple(args, "I:lock_id_free", &theID))
6345 return NULL;
6346
6347 CHECK_ENV_NOT_CLOSED(self);
6348 MYDB_BEGIN_ALLOW_THREADS;
6349 err = self->db_env->lock_id_free(self->db_env, theID);
6350 MYDB_END_ALLOW_THREADS;
6351 RETURN_IF_ERR();
6352 RETURN_NONE();
6353}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006354
6355static PyObject*
6356DBEnv_lock_put(DBEnvObject* self, PyObject* args)
6357{
6358 int err;
6359 DBLockObject* dblockobj;
6360
6361 if (!PyArg_ParseTuple(args, "O!:lock_put", &DBLock_Type, &dblockobj))
6362 return NULL;
6363
6364 CHECK_ENV_NOT_CLOSED(self);
6365 MYDB_BEGIN_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006366 err = self->db_env->lock_put(self->db_env, &dblockobj->lock);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006367 MYDB_END_ALLOW_THREADS;
6368 RETURN_IF_ERR();
6369 RETURN_NONE();
6370}
6371
Gregory P. Smithdb8a8072006-06-05 01:56:15 +00006372#if (DBVER >= 44)
6373static PyObject*
Jesus Cea6557aac2010-03-22 14:22:26 +00006374DBEnv_fileid_reset(DBEnvObject* self, PyObject* args, PyObject* kwargs)
6375{
6376 int err;
6377 char *file;
6378 u_int32_t flags = 0;
6379 static char* kwnames[] = { "file", "flags", NULL};
6380
6381 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "z|i:fileid_reset", kwnames,
6382 &file, &flags))
6383 return NULL;
6384 CHECK_ENV_NOT_CLOSED(self);
6385
6386 MYDB_BEGIN_ALLOW_THREADS;
6387 err = self->db_env->fileid_reset(self->db_env, file, flags);
6388 MYDB_END_ALLOW_THREADS;
6389 RETURN_IF_ERR();
6390 RETURN_NONE();
6391}
6392
6393static PyObject*
Gregory P. Smithdb8a8072006-06-05 01:56:15 +00006394DBEnv_lsn_reset(DBEnvObject* self, PyObject* args, PyObject* kwargs)
6395{
6396 int err;
6397 char *file;
6398 u_int32_t flags = 0;
6399 static char* kwnames[] = { "file", "flags", NULL};
6400
6401 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "z|i:lsn_reset", kwnames,
6402 &file, &flags))
6403 return NULL;
6404 CHECK_ENV_NOT_CLOSED(self);
6405
6406 MYDB_BEGIN_ALLOW_THREADS;
6407 err = self->db_env->lsn_reset(self->db_env, file, flags);
6408 MYDB_END_ALLOW_THREADS;
6409 RETURN_IF_ERR();
6410 RETURN_NONE();
6411}
6412#endif /* DBVER >= 4.4 */
6413
Jesus Cea6557aac2010-03-22 14:22:26 +00006414
Jesus Cea6557aac2010-03-22 14:22:26 +00006415static PyObject*
6416DBEnv_stat_print(DBEnvObject* self, PyObject* args, PyObject *kwargs)
6417{
6418 int err;
6419 int flags=0;
6420 static char* kwnames[] = { "flags", NULL };
6421
6422 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:stat_print",
6423 kwnames, &flags))
6424 {
6425 return NULL;
6426 }
6427 CHECK_ENV_NOT_CLOSED(self);
6428 MYDB_BEGIN_ALLOW_THREADS;
6429 err = self->db_env->stat_print(self->db_env, flags);
6430 MYDB_END_ALLOW_THREADS;
6431 RETURN_IF_ERR();
6432 RETURN_NONE();
6433}
Jesus Cea6557aac2010-03-22 14:22:26 +00006434
6435
Gregory P. Smith76a82e82006-06-05 01:39:52 +00006436static PyObject*
6437DBEnv_log_stat(DBEnvObject* self, PyObject* args)
6438{
6439 int err;
6440 DB_LOG_STAT* statp = NULL;
6441 PyObject* d = NULL;
6442 u_int32_t flags = 0;
6443
6444 if (!PyArg_ParseTuple(args, "|i:log_stat", &flags))
6445 return NULL;
6446 CHECK_ENV_NOT_CLOSED(self);
6447
6448 MYDB_BEGIN_ALLOW_THREADS;
6449 err = self->db_env->log_stat(self->db_env, &statp, flags);
6450 MYDB_END_ALLOW_THREADS;
6451 RETURN_IF_ERR();
6452
6453 /* Turn the stat structure into a dictionary */
6454 d = PyDict_New();
6455 if (d == NULL) {
6456 if (statp)
6457 free(statp);
6458 return NULL;
6459 }
6460
6461#define MAKE_ENTRY(name) _addIntToDict(d, #name, statp->st_##name)
6462
6463 MAKE_ENTRY(magic);
6464 MAKE_ENTRY(version);
6465 MAKE_ENTRY(mode);
6466 MAKE_ENTRY(lg_bsize);
6467#if (DBVER >= 44)
6468 MAKE_ENTRY(lg_size);
6469 MAKE_ENTRY(record);
6470#endif
Gregory P. Smith76a82e82006-06-05 01:39:52 +00006471 MAKE_ENTRY(w_mbytes);
6472 MAKE_ENTRY(w_bytes);
6473 MAKE_ENTRY(wc_mbytes);
6474 MAKE_ENTRY(wc_bytes);
6475 MAKE_ENTRY(wcount);
6476 MAKE_ENTRY(wcount_fill);
6477#if (DBVER >= 44)
6478 MAKE_ENTRY(rcount);
6479#endif
6480 MAKE_ENTRY(scount);
6481 MAKE_ENTRY(cur_file);
6482 MAKE_ENTRY(cur_offset);
6483 MAKE_ENTRY(disk_file);
6484 MAKE_ENTRY(disk_offset);
6485 MAKE_ENTRY(maxcommitperflush);
6486 MAKE_ENTRY(mincommitperflush);
6487 MAKE_ENTRY(regsize);
6488 MAKE_ENTRY(region_wait);
6489 MAKE_ENTRY(region_nowait);
6490
6491#undef MAKE_ENTRY
6492 free(statp);
6493 return d;
6494} /* DBEnv_log_stat */
Gregory P. Smith76a82e82006-06-05 01:39:52 +00006495
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006496
Jesus Cea6557aac2010-03-22 14:22:26 +00006497static PyObject*
6498DBEnv_log_stat_print(DBEnvObject* self, PyObject* args, PyObject *kwargs)
6499{
6500 int err;
6501 int flags=0;
6502 static char* kwnames[] = { "flags", NULL };
6503
6504 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:log_stat_print",
6505 kwnames, &flags))
6506 {
6507 return NULL;
6508 }
6509 CHECK_ENV_NOT_CLOSED(self);
6510 MYDB_BEGIN_ALLOW_THREADS;
6511 err = self->db_env->log_stat_print(self->db_env, flags);
6512 MYDB_END_ALLOW_THREADS;
6513 RETURN_IF_ERR();
6514 RETURN_NONE();
6515}
Jesus Cea6557aac2010-03-22 14:22:26 +00006516
6517
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006518static PyObject*
6519DBEnv_lock_stat(DBEnvObject* self, PyObject* args)
6520{
6521 int err;
6522 DB_LOCK_STAT* sp;
6523 PyObject* d = NULL;
Martin v. Löwisb2c7aff2002-11-23 11:26:07 +00006524 u_int32_t flags = 0;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006525
6526 if (!PyArg_ParseTuple(args, "|i:lock_stat", &flags))
6527 return NULL;
6528 CHECK_ENV_NOT_CLOSED(self);
6529
6530 MYDB_BEGIN_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006531 err = self->db_env->lock_stat(self->db_env, &sp, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006532 MYDB_END_ALLOW_THREADS;
6533 RETURN_IF_ERR();
6534
6535 /* Turn the stat structure into a dictionary */
6536 d = PyDict_New();
6537 if (d == NULL) {
6538 free(sp);
6539 return NULL;
6540 }
6541
6542#define MAKE_ENTRY(name) _addIntToDict(d, #name, sp->st_##name)
6543
Jesus Ceaef9764f2008-05-13 18:45:46 +00006544 MAKE_ENTRY(id);
6545 MAKE_ENTRY(cur_maxid);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006546 MAKE_ENTRY(nmodes);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006547 MAKE_ENTRY(maxlocks);
6548 MAKE_ENTRY(maxlockers);
6549 MAKE_ENTRY(maxobjects);
6550 MAKE_ENTRY(nlocks);
6551 MAKE_ENTRY(maxnlocks);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006552 MAKE_ENTRY(nlockers);
6553 MAKE_ENTRY(maxnlockers);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006554 MAKE_ENTRY(nobjects);
6555 MAKE_ENTRY(maxnobjects);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006556 MAKE_ENTRY(nrequests);
6557 MAKE_ENTRY(nreleases);
Jesus Ceaef9764f2008-05-13 18:45:46 +00006558#if (DBVER >= 44)
6559 MAKE_ENTRY(nupgrade);
6560 MAKE_ENTRY(ndowngrade);
6561#endif
Gregory P. Smith29602d22006-01-24 09:46:48 +00006562#if (DBVER < 44)
6563 MAKE_ENTRY(nnowaits); /* these were renamed in 4.4 */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006564 MAKE_ENTRY(nconflicts);
Gregory P. Smith29602d22006-01-24 09:46:48 +00006565#else
6566 MAKE_ENTRY(lock_nowait);
6567 MAKE_ENTRY(lock_wait);
6568#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006569 MAKE_ENTRY(ndeadlocks);
Jesus Ceaef9764f2008-05-13 18:45:46 +00006570 MAKE_ENTRY(locktimeout);
6571 MAKE_ENTRY(txntimeout);
Jesus Ceaef9764f2008-05-13 18:45:46 +00006572 MAKE_ENTRY(nlocktimeouts);
6573 MAKE_ENTRY(ntxntimeouts);
Jesus Ceaef9764f2008-05-13 18:45:46 +00006574#if (DBVER >= 46)
6575 MAKE_ENTRY(objs_wait);
6576 MAKE_ENTRY(objs_nowait);
6577 MAKE_ENTRY(lockers_wait);
6578 MAKE_ENTRY(lockers_nowait);
Jesus Ceaca3939c2008-05-22 15:27:38 +00006579#if (DBVER >= 47)
6580 MAKE_ENTRY(lock_wait);
6581 MAKE_ENTRY(lock_nowait);
6582#else
Jesus Ceaef9764f2008-05-13 18:45:46 +00006583 MAKE_ENTRY(locks_wait);
6584 MAKE_ENTRY(locks_nowait);
Jesus Ceaca3939c2008-05-22 15:27:38 +00006585#endif
Jesus Ceaef9764f2008-05-13 18:45:46 +00006586 MAKE_ENTRY(hash_len);
6587#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006588 MAKE_ENTRY(regsize);
6589 MAKE_ENTRY(region_wait);
6590 MAKE_ENTRY(region_nowait);
6591
6592#undef MAKE_ENTRY
6593 free(sp);
6594 return d;
6595}
6596
Jesus Cea6557aac2010-03-22 14:22:26 +00006597static PyObject*
6598DBEnv_lock_stat_print(DBEnvObject* self, PyObject* args, PyObject *kwargs)
6599{
6600 int err;
6601 int flags=0;
6602 static char* kwnames[] = { "flags", NULL };
6603
6604 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:lock_stat_print",
6605 kwnames, &flags))
6606 {
6607 return NULL;
6608 }
6609 CHECK_ENV_NOT_CLOSED(self);
6610 MYDB_BEGIN_ALLOW_THREADS;
6611 err = self->db_env->lock_stat_print(self->db_env, flags);
6612 MYDB_END_ALLOW_THREADS;
6613 RETURN_IF_ERR();
6614 RETURN_NONE();
6615}
Jesus Cea6557aac2010-03-22 14:22:26 +00006616
6617
6618static PyObject*
6619DBEnv_log_cursor(DBEnvObject* self)
6620{
6621 int err;
6622 DB_LOGC* dblogc;
6623
6624 CHECK_ENV_NOT_CLOSED(self);
6625
6626 MYDB_BEGIN_ALLOW_THREADS;
6627 err = self->db_env->log_cursor(self->db_env, &dblogc, 0);
6628 MYDB_END_ALLOW_THREADS;
6629 RETURN_IF_ERR();
6630 return (PyObject*) newDBLogCursorObject(dblogc, self);
6631}
6632
6633
Jesus Ceaef9764f2008-05-13 18:45:46 +00006634static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00006635DBEnv_log_flush(DBEnvObject* self)
Jesus Ceaef9764f2008-05-13 18:45:46 +00006636{
6637 int err;
6638
Jesus Ceaef9764f2008-05-13 18:45:46 +00006639 CHECK_ENV_NOT_CLOSED(self);
6640
6641 MYDB_BEGIN_ALLOW_THREADS
6642 err = self->db_env->log_flush(self->db_env, NULL);
6643 MYDB_END_ALLOW_THREADS
6644
6645 RETURN_IF_ERR();
6646 RETURN_NONE();
6647}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006648
6649static PyObject*
Jesus Cea6557aac2010-03-22 14:22:26 +00006650DBEnv_log_file(DBEnvObject* self, PyObject* args)
6651{
6652 int err;
6653 DB_LSN lsn = {0, 0};
6654 int size = 20;
6655 char *name = NULL;
6656 PyObject *retval;
6657
6658 if (!PyArg_ParseTuple(args, "(ii):log_file", &lsn.file, &lsn.offset))
6659 return NULL;
6660
6661 CHECK_ENV_NOT_CLOSED(self);
6662
6663 do {
6664 name = malloc(size);
6665 if (!name) {
6666 PyErr_NoMemory();
6667 return NULL;
6668 }
6669 MYDB_BEGIN_ALLOW_THREADS;
6670 err = self->db_env->log_file(self->db_env, &lsn, name, size);
6671 MYDB_END_ALLOW_THREADS;
6672 if (err == EINVAL) {
6673 free(name);
6674 size *= 2;
6675 } else if (err) {
6676 free(name);
6677 RETURN_IF_ERR();
6678 assert(0); /* Unreachable... supposely */
6679 return NULL;
6680 }
6681/*
6682** If the final buffer we try is too small, we will
6683** get this exception:
6684** DBInvalidArgError:
6685** (22, 'Invalid argument -- DB_ENV->log_file: name buffer is too short')
6686*/
6687 } while ((err == EINVAL) && (size<(1<<17)));
6688
6689 RETURN_IF_ERR(); /* Maybe the size is not the problem */
6690
6691 retval = Py_BuildValue("s", name);
6692 free(name);
6693 return retval;
6694}
6695
6696
6697#if (DBVER >= 44)
6698static PyObject*
6699DBEnv_log_printf(DBEnvObject* self, PyObject* args, PyObject *kwargs)
6700{
6701 int err;
6702 char *string;
6703 PyObject *txnobj = NULL;
6704 DB_TXN *txn = NULL;
6705 static char* kwnames[] = {"string", "txn", NULL };
6706
6707 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|O:log_printf", kwnames,
6708 &string, &txnobj))
6709 return NULL;
6710
6711 CHECK_ENV_NOT_CLOSED(self);
6712
6713 if (!checkTxnObj(txnobj, &txn))
6714 return NULL;
6715
6716 /*
6717 ** Do not use the format string directly, to avoid attacks.
6718 */
6719 MYDB_BEGIN_ALLOW_THREADS;
6720 err = self->db_env->log_printf(self->db_env, txn, "%s", string);
6721 MYDB_END_ALLOW_THREADS;
6722
6723 RETURN_IF_ERR();
6724 RETURN_NONE();
6725}
6726#endif
6727
6728
6729static PyObject*
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006730DBEnv_log_archive(DBEnvObject* self, PyObject* args)
6731{
6732 int flags=0;
6733 int err;
Gregory P. Smith3dd20022006-06-05 00:31:01 +00006734 char **log_list = NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006735 PyObject* list;
6736 PyObject* item = NULL;
6737
6738 if (!PyArg_ParseTuple(args, "|i:log_archive", &flags))
6739 return NULL;
6740
6741 CHECK_ENV_NOT_CLOSED(self);
6742 MYDB_BEGIN_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006743 err = self->db_env->log_archive(self->db_env, &log_list, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006744 MYDB_END_ALLOW_THREADS;
6745 RETURN_IF_ERR();
6746
Gregory P. Smithbad47452006-06-05 00:33:35 +00006747 list = PyList_New(0);
6748 if (list == NULL) {
6749 if (log_list)
6750 free(log_list);
6751 return NULL;
6752 }
6753
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006754 if (log_list) {
Gregory P. Smith3dd20022006-06-05 00:31:01 +00006755 char **log_list_start;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006756 for (log_list_start = log_list; *log_list != NULL; ++log_list) {
Christian Heimes593daf52008-05-26 12:51:38 +00006757 item = PyBytes_FromString (*log_list);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006758 if (item == NULL) {
6759 Py_DECREF(list);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006760 list = NULL;
6761 break;
6762 }
Jesus Ceac5a11fa2008-07-23 11:38:42 +00006763 if (PyList_Append(list, item)) {
6764 Py_DECREF(list);
6765 list = NULL;
6766 Py_DECREF(item);
6767 break;
6768 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006769 Py_DECREF(item);
6770 }
6771 free(log_list_start);
6772 }
6773 return list;
6774}
6775
6776
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07006777#if (DBVER >= 52)
6778static PyObject*
6779DBEnv_repmgr_site(DBEnvObject* self, PyObject* args, PyObject *kwargs)
6780{
6781 int err;
6782 DB_SITE* site;
6783 char *host;
6784 u_int port;
6785 static char* kwnames[] = {"host", "port", NULL};
6786
6787 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "si:repmgr_site", kwnames,
6788 &host, &port))
6789 return NULL;
6790
6791 CHECK_ENV_NOT_CLOSED(self);
6792
6793 MYDB_BEGIN_ALLOW_THREADS;
6794 err = self->db_env->repmgr_site(self->db_env, host, port, &site, 0);
6795 MYDB_END_ALLOW_THREADS;
6796 RETURN_IF_ERR();
6797 return (PyObject*) newDBSiteObject(site, self);
6798}
6799
6800static PyObject*
6801DBEnv_repmgr_site_by_eid(DBEnvObject* self, PyObject* args, PyObject *kwargs)
6802{
6803 int err;
6804 DB_SITE* site;
6805 int eid;
6806 static char* kwnames[] = {"eid", NULL};
6807
6808 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i:repmgr_site_by_eid",
6809 kwnames, &eid))
6810 return NULL;
6811
6812 CHECK_ENV_NOT_CLOSED(self);
6813
6814 MYDB_BEGIN_ALLOW_THREADS;
6815 err = self->db_env->repmgr_site_by_eid(self->db_env, eid, &site);
6816 MYDB_END_ALLOW_THREADS;
6817 RETURN_IF_ERR();
6818 return (PyObject*) newDBSiteObject(site, self);
6819}
6820#endif
6821
6822
Jesus Cea6557aac2010-03-22 14:22:26 +00006823#if (DBVER >= 44)
6824static PyObject*
6825DBEnv_mutex_stat(DBEnvObject* self, PyObject* args)
6826{
6827 int err;
6828 DB_MUTEX_STAT* statp = NULL;
6829 PyObject* d = NULL;
6830 u_int32_t flags = 0;
6831
6832 if (!PyArg_ParseTuple(args, "|i:mutex_stat", &flags))
6833 return NULL;
6834 CHECK_ENV_NOT_CLOSED(self);
6835
6836 MYDB_BEGIN_ALLOW_THREADS;
6837 err = self->db_env->mutex_stat(self->db_env, &statp, flags);
6838 MYDB_END_ALLOW_THREADS;
6839 RETURN_IF_ERR();
6840
6841 /* Turn the stat structure into a dictionary */
6842 d = PyDict_New();
6843 if (d == NULL) {
6844 if (statp)
6845 free(statp);
6846 return NULL;
6847 }
6848
6849#define MAKE_ENTRY(name) _addIntToDict(d, #name, statp->st_##name)
6850
6851 MAKE_ENTRY(mutex_align);
6852 MAKE_ENTRY(mutex_tas_spins);
6853 MAKE_ENTRY(mutex_cnt);
6854 MAKE_ENTRY(mutex_free);
6855 MAKE_ENTRY(mutex_inuse);
6856 MAKE_ENTRY(mutex_inuse_max);
6857 MAKE_ENTRY(regsize);
6858 MAKE_ENTRY(region_wait);
6859 MAKE_ENTRY(region_nowait);
6860
6861#undef MAKE_ENTRY
6862 free(statp);
6863 return d;
6864}
6865#endif
6866
6867
6868#if (DBVER >= 44)
6869static PyObject*
6870DBEnv_mutex_stat_print(DBEnvObject* self, PyObject* args, PyObject *kwargs)
6871{
6872 int err;
6873 int flags=0;
6874 static char* kwnames[] = { "flags", NULL };
6875
6876 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:mutex_stat_print",
6877 kwnames, &flags))
6878 {
6879 return NULL;
6880 }
6881 CHECK_ENV_NOT_CLOSED(self);
6882 MYDB_BEGIN_ALLOW_THREADS;
6883 err = self->db_env->mutex_stat_print(self->db_env, flags);
6884 MYDB_END_ALLOW_THREADS;
6885 RETURN_IF_ERR();
6886 RETURN_NONE();
6887}
6888#endif
6889
6890
Jesus Cea6557aac2010-03-22 14:22:26 +00006891static PyObject*
6892DBEnv_txn_stat_print(DBEnvObject* self, PyObject* args, PyObject *kwargs)
6893{
6894 int err;
6895 int flags=0;
6896 static char* kwnames[] = { "flags", NULL };
6897
6898 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:stat_print",
6899 kwnames, &flags))
6900 {
6901 return NULL;
6902 }
6903
6904 CHECK_ENV_NOT_CLOSED(self);
6905
6906 MYDB_BEGIN_ALLOW_THREADS;
6907 err = self->db_env->txn_stat_print(self->db_env, flags);
6908 MYDB_END_ALLOW_THREADS;
6909 RETURN_IF_ERR();
6910 RETURN_NONE();
6911}
Jesus Cea6557aac2010-03-22 14:22:26 +00006912
6913
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006914static PyObject*
6915DBEnv_txn_stat(DBEnvObject* self, PyObject* args)
6916{
6917 int err;
6918 DB_TXN_STAT* sp;
6919 PyObject* d = NULL;
Martin v. Löwisb2c7aff2002-11-23 11:26:07 +00006920 u_int32_t flags=0;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006921
6922 if (!PyArg_ParseTuple(args, "|i:txn_stat", &flags))
6923 return NULL;
6924 CHECK_ENV_NOT_CLOSED(self);
6925
6926 MYDB_BEGIN_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006927 err = self->db_env->txn_stat(self->db_env, &sp, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006928 MYDB_END_ALLOW_THREADS;
6929 RETURN_IF_ERR();
6930
6931 /* Turn the stat structure into a dictionary */
6932 d = PyDict_New();
6933 if (d == NULL) {
6934 free(sp);
6935 return NULL;
6936 }
6937
Jesus Ceaef9764f2008-05-13 18:45:46 +00006938#define MAKE_ENTRY(name) _addIntToDict(d, #name, sp->st_##name)
6939#define MAKE_TIME_T_ENTRY(name) _addTimeTToDict(d, #name, sp->st_##name)
6940#define MAKE_DB_LSN_ENTRY(name) _addDB_lsnToDict(d, #name, sp->st_##name)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006941
Jesus Ceaef9764f2008-05-13 18:45:46 +00006942 MAKE_DB_LSN_ENTRY(last_ckp);
Kristján Valur Jónssonbd77c032007-04-26 15:24:54 +00006943 MAKE_TIME_T_ENTRY(time_ckp);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006944 MAKE_ENTRY(last_txnid);
6945 MAKE_ENTRY(maxtxns);
6946 MAKE_ENTRY(nactive);
6947 MAKE_ENTRY(maxnactive);
Jesus Ceaef9764f2008-05-13 18:45:46 +00006948#if (DBVER >= 45)
6949 MAKE_ENTRY(nsnapshot);
6950 MAKE_ENTRY(maxnsnapshot);
6951#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006952 MAKE_ENTRY(nbegins);
6953 MAKE_ENTRY(naborts);
6954 MAKE_ENTRY(ncommits);
Jesus Ceaef9764f2008-05-13 18:45:46 +00006955 MAKE_ENTRY(nrestores);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006956 MAKE_ENTRY(regsize);
6957 MAKE_ENTRY(region_wait);
6958 MAKE_ENTRY(region_nowait);
6959
Jesus Ceaef9764f2008-05-13 18:45:46 +00006960#undef MAKE_DB_LSN_ENTRY
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006961#undef MAKE_ENTRY
Kristján Valur Jónssonbd77c032007-04-26 15:24:54 +00006962#undef MAKE_TIME_T_ENTRY
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006963 free(sp);
6964 return d;
6965}
6966
6967
6968static PyObject*
6969DBEnv_set_get_returns_none(DBEnvObject* self, PyObject* args)
6970{
6971 int flags=0;
Gregory P. Smith455d46f2003-07-09 04:45:59 +00006972 int oldValue=0;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006973
6974 if (!PyArg_ParseTuple(args,"i:set_get_returns_none", &flags))
6975 return NULL;
6976 CHECK_ENV_NOT_CLOSED(self);
6977
Gregory P. Smith455d46f2003-07-09 04:45:59 +00006978 if (self->moduleFlags.getReturnsNone)
6979 ++oldValue;
6980 if (self->moduleFlags.cursorSetReturnsNone)
6981 ++oldValue;
6982 self->moduleFlags.getReturnsNone = (flags >= 1);
6983 self->moduleFlags.cursorSetReturnsNone = (flags >= 2);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00006984 return NUMBER_FromLong(oldValue);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006985}
6986
Jesus Ceac5a11fa2008-07-23 11:38:42 +00006987static PyObject*
6988DBEnv_get_private(DBEnvObject* self)
6989{
6990 /* We can give out the private field even if dbenv is closed */
Jesus Cea4907d272008-08-31 14:00:51 +00006991 Py_INCREF(self->private_obj);
6992 return self->private_obj;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00006993}
6994
6995static PyObject*
Jesus Cea4907d272008-08-31 14:00:51 +00006996DBEnv_set_private(DBEnvObject* self, PyObject* private_obj)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00006997{
6998 /* We can set the private field even if dbenv is closed */
Jesus Cea4907d272008-08-31 14:00:51 +00006999 Py_DECREF(self->private_obj);
7000 Py_INCREF(private_obj);
7001 self->private_obj = private_obj;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007002 RETURN_NONE();
7003}
7004
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07007005#if (DBVER >= 47)
7006static PyObject*
7007DBEnv_set_intermediate_dir_mode(DBEnvObject* self, PyObject* args)
7008{
7009 int err;
7010 const char *mode;
7011
7012 if (!PyArg_ParseTuple(args,"s:set_intermediate_dir_mode", &mode))
7013 return NULL;
7014
7015 CHECK_ENV_NOT_CLOSED(self);
7016
7017 MYDB_BEGIN_ALLOW_THREADS;
7018 err = self->db_env->set_intermediate_dir_mode(self->db_env, mode);
7019 MYDB_END_ALLOW_THREADS;
7020 RETURN_IF_ERR();
7021 RETURN_NONE();
7022}
7023
7024static PyObject*
7025DBEnv_get_intermediate_dir_mode(DBEnvObject* self)
7026{
7027 int err;
7028 const char *mode;
7029
7030 CHECK_ENV_NOT_CLOSED(self);
7031
7032 MYDB_BEGIN_ALLOW_THREADS;
7033 err = self->db_env->get_intermediate_dir_mode(self->db_env, &mode);
7034 MYDB_END_ALLOW_THREADS;
7035 RETURN_IF_ERR();
7036 return Py_BuildValue("s", mode);
7037}
7038#endif
7039
7040#if (DBVER < 47)
7041static PyObject*
7042DBEnv_set_intermediate_dir(DBEnvObject* self, PyObject* args)
7043{
7044 int err;
7045 int mode;
7046 u_int32_t flags;
7047
7048 if (!PyArg_ParseTuple(args, "iI:set_intermediate_dir", &mode, &flags))
7049 return NULL;
7050
7051 CHECK_ENV_NOT_CLOSED(self);
7052
7053 MYDB_BEGIN_ALLOW_THREADS;
7054 err = self->db_env->set_intermediate_dir(self->db_env, mode, flags);
7055 MYDB_END_ALLOW_THREADS;
7056 RETURN_IF_ERR();
7057 RETURN_NONE();
7058}
7059#endif
7060
7061static PyObject*
7062DBEnv_get_open_flags(DBEnvObject* self)
7063{
7064 int err;
7065 unsigned int flags;
7066
7067 CHECK_ENV_NOT_CLOSED(self);
7068
7069 MYDB_BEGIN_ALLOW_THREADS;
7070 err = self->db_env->get_open_flags(self->db_env, &flags);
7071 MYDB_END_ALLOW_THREADS;
7072 RETURN_IF_ERR();
7073 return NUMBER_FromLong(flags);
7074}
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007075
Matthias Klose54cc5392010-03-15 12:46:18 +00007076#if (DBVER < 48)
Jesus Ceaef9764f2008-05-13 18:45:46 +00007077static PyObject*
Jesus Ceaca3939c2008-05-22 15:27:38 +00007078DBEnv_set_rpc_server(DBEnvObject* self, PyObject* args, PyObject* kwargs)
7079{
7080 int err;
7081 char *host;
7082 long cl_timeout=0, sv_timeout=0;
7083
7084 static char* kwnames[] = { "host", "cl_timeout", "sv_timeout", NULL};
7085
7086 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|ll:set_rpc_server", kwnames,
7087 &host, &cl_timeout, &sv_timeout))
7088 return NULL;
7089 CHECK_ENV_NOT_CLOSED(self);
7090
7091 MYDB_BEGIN_ALLOW_THREADS;
7092 err = self->db_env->set_rpc_server(self->db_env, NULL, host, cl_timeout,
7093 sv_timeout, 0);
7094 MYDB_END_ALLOW_THREADS;
7095 RETURN_IF_ERR();
7096 RETURN_NONE();
7097}
Matthias Klose54cc5392010-03-15 12:46:18 +00007098#endif
Jesus Ceaca3939c2008-05-22 15:27:38 +00007099
Jesus Cea6557aac2010-03-22 14:22:26 +00007100static PyObject*
7101DBEnv_set_mp_max_openfd(DBEnvObject* self, PyObject* args)
7102{
7103 int err;
7104 int maxopenfd;
7105
7106 if (!PyArg_ParseTuple(args, "i:set_mp_max_openfd", &maxopenfd)) {
7107 return NULL;
7108 }
7109 CHECK_ENV_NOT_CLOSED(self);
7110 MYDB_BEGIN_ALLOW_THREADS;
7111 err = self->db_env->set_mp_max_openfd(self->db_env, maxopenfd);
7112 MYDB_END_ALLOW_THREADS;
7113 RETURN_IF_ERR();
7114 RETURN_NONE();
7115}
7116
7117static PyObject*
7118DBEnv_get_mp_max_openfd(DBEnvObject* self)
7119{
7120 int err;
7121 int maxopenfd;
7122
7123 CHECK_ENV_NOT_CLOSED(self);
7124
7125 MYDB_BEGIN_ALLOW_THREADS;
7126 err = self->db_env->get_mp_max_openfd(self->db_env, &maxopenfd);
7127 MYDB_END_ALLOW_THREADS;
7128 RETURN_IF_ERR();
7129 return NUMBER_FromLong(maxopenfd);
7130}
7131
7132
7133static PyObject*
7134DBEnv_set_mp_max_write(DBEnvObject* self, PyObject* args)
7135{
7136 int err;
7137 int maxwrite, maxwrite_sleep;
7138
7139 if (!PyArg_ParseTuple(args, "ii:set_mp_max_write", &maxwrite,
7140 &maxwrite_sleep)) {
7141 return NULL;
7142 }
7143 CHECK_ENV_NOT_CLOSED(self);
7144 MYDB_BEGIN_ALLOW_THREADS;
7145 err = self->db_env->set_mp_max_write(self->db_env, maxwrite,
7146 maxwrite_sleep);
7147 MYDB_END_ALLOW_THREADS;
7148 RETURN_IF_ERR();
7149 RETURN_NONE();
7150}
7151
7152static PyObject*
7153DBEnv_get_mp_max_write(DBEnvObject* self)
7154{
7155 int err;
7156 int maxwrite;
7157#if (DBVER >= 46)
7158 db_timeout_t maxwrite_sleep;
7159#else
7160 int maxwrite_sleep;
7161#endif
7162
7163 CHECK_ENV_NOT_CLOSED(self);
7164
7165 MYDB_BEGIN_ALLOW_THREADS;
7166 err = self->db_env->get_mp_max_write(self->db_env, &maxwrite,
7167 &maxwrite_sleep);
7168 MYDB_END_ALLOW_THREADS;
7169 RETURN_IF_ERR();
7170
7171 return Py_BuildValue("(ii)", maxwrite, (int)maxwrite_sleep);
7172}
Jesus Cea6557aac2010-03-22 14:22:26 +00007173
7174
Jesus Ceaca3939c2008-05-22 15:27:38 +00007175static PyObject*
Jesus Ceaef9764f2008-05-13 18:45:46 +00007176DBEnv_set_verbose(DBEnvObject* self, PyObject* args)
7177{
7178 int err;
7179 int which, onoff;
7180
7181 if (!PyArg_ParseTuple(args, "ii:set_verbose", &which, &onoff)) {
7182 return NULL;
7183 }
7184 CHECK_ENV_NOT_CLOSED(self);
7185 MYDB_BEGIN_ALLOW_THREADS;
7186 err = self->db_env->set_verbose(self->db_env, which, onoff);
7187 MYDB_END_ALLOW_THREADS;
7188 RETURN_IF_ERR();
7189 RETURN_NONE();
7190}
7191
Jesus Ceaef9764f2008-05-13 18:45:46 +00007192static PyObject*
7193DBEnv_get_verbose(DBEnvObject* self, PyObject* args)
7194{
7195 int err;
7196 int which;
7197 int verbose;
7198
7199 if (!PyArg_ParseTuple(args, "i:get_verbose", &which)) {
7200 return NULL;
7201 }
7202 CHECK_ENV_NOT_CLOSED(self);
7203 MYDB_BEGIN_ALLOW_THREADS;
7204 err = self->db_env->get_verbose(self->db_env, which, &verbose);
7205 MYDB_END_ALLOW_THREADS;
7206 RETURN_IF_ERR();
7207 return PyBool_FromLong(verbose);
7208}
Jesus Ceaef9764f2008-05-13 18:45:46 +00007209
7210#if (DBVER >= 45)
7211static void
7212_dbenv_event_notifyCallback(DB_ENV* db_env, u_int32_t event, void *event_info)
7213{
7214 DBEnvObject *dbenv;
7215 PyObject* callback;
7216 PyObject* args;
7217 PyObject* result = NULL;
7218
7219 MYDB_BEGIN_BLOCK_THREADS;
7220 dbenv = (DBEnvObject *)db_env->app_private;
7221 callback = dbenv->event_notifyCallback;
7222 if (callback) {
7223 if (event == DB_EVENT_REP_NEWMASTER) {
7224 args = Py_BuildValue("(Oii)", dbenv, event, *((int *)event_info));
7225 } else {
7226 args = Py_BuildValue("(OiO)", dbenv, event, Py_None);
7227 }
7228 if (args) {
7229 result = PyEval_CallObject(callback, args);
7230 }
7231 if ((!args) || (!result)) {
7232 PyErr_Print();
7233 }
7234 Py_XDECREF(args);
7235 Py_XDECREF(result);
7236 }
7237 MYDB_END_BLOCK_THREADS;
7238}
7239#endif
7240
7241#if (DBVER >= 45)
7242static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007243DBEnv_set_event_notify(DBEnvObject* self, PyObject* notifyFunc)
Jesus Ceaef9764f2008-05-13 18:45:46 +00007244{
7245 int err;
Jesus Ceaef9764f2008-05-13 18:45:46 +00007246
7247 CHECK_ENV_NOT_CLOSED(self);
7248
7249 if (!PyCallable_Check(notifyFunc)) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00007250 makeTypeError("Callable", notifyFunc);
7251 return NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00007252 }
7253
7254 Py_XDECREF(self->event_notifyCallback);
7255 Py_INCREF(notifyFunc);
7256 self->event_notifyCallback = notifyFunc;
7257
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007258 /* This is to workaround a problem with un-initialized threads (see
7259 comment in DB_associate) */
7260#ifdef WITH_THREAD
7261 PyEval_InitThreads();
7262#endif
7263
Jesus Ceaef9764f2008-05-13 18:45:46 +00007264 MYDB_BEGIN_ALLOW_THREADS;
7265 err = self->db_env->set_event_notify(self->db_env, _dbenv_event_notifyCallback);
7266 MYDB_END_ALLOW_THREADS;
7267
7268 if (err) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00007269 Py_DECREF(notifyFunc);
7270 self->event_notifyCallback = NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00007271 }
7272
7273 RETURN_IF_ERR();
7274 RETURN_NONE();
7275}
7276#endif
7277
7278
7279/* --------------------------------------------------------------------- */
7280/* REPLICATION METHODS: Base Replication */
7281
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007282
7283static PyObject*
7284DBEnv_rep_process_message(DBEnvObject* self, PyObject* args)
7285{
7286 int err;
7287 PyObject *control_py, *rec_py;
7288 DBT control, rec;
7289 int envid;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007290 DB_LSN lsn;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007291
7292 if (!PyArg_ParseTuple(args, "OOi:rep_process_message", &control_py,
7293 &rec_py, &envid))
7294 return NULL;
7295 CHECK_ENV_NOT_CLOSED(self);
7296
7297 if (!make_dbt(control_py, &control))
7298 return NULL;
7299 if (!make_dbt(rec_py, &rec))
7300 return NULL;
7301
7302 MYDB_BEGIN_ALLOW_THREADS;
7303#if (DBVER >= 46)
7304 err = self->db_env->rep_process_message(self->db_env, &control, &rec,
7305 envid, &lsn);
7306#else
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007307 err = self->db_env->rep_process_message(self->db_env, &control, &rec,
7308 &envid, &lsn);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007309#endif
7310 MYDB_END_ALLOW_THREADS;
7311 switch (err) {
7312 case DB_REP_NEWMASTER :
7313 return Py_BuildValue("(iO)", envid, Py_None);
7314 break;
7315
7316 case DB_REP_DUPMASTER :
7317 case DB_REP_HOLDELECTION :
7318#if (DBVER >= 44)
7319 case DB_REP_IGNORE :
7320 case DB_REP_JOIN_FAILURE :
7321#endif
7322 return Py_BuildValue("(iO)", err, Py_None);
7323 break;
7324 case DB_REP_NEWSITE :
Jesus Cea4907d272008-08-31 14:00:51 +00007325 {
7326 PyObject *tmp, *r;
7327
7328 if (!(tmp = PyBytes_FromStringAndSize(rec.data, rec.size))) {
7329 return NULL;
7330 }
7331
7332 r = Py_BuildValue("(iO)", err, tmp);
7333 Py_DECREF(tmp);
7334 return r;
7335 break;
7336 }
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007337 case DB_REP_NOTPERM :
7338 case DB_REP_ISPERM :
7339 return Py_BuildValue("(i(ll))", err, lsn.file, lsn.offset);
7340 break;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007341 }
7342 RETURN_IF_ERR();
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07007343 return PyTuple_Pack(2, Py_None, Py_None);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007344}
7345
7346static int
7347_DBEnv_rep_transportCallback(DB_ENV* db_env, const DBT* control, const DBT* rec,
7348 const DB_LSN *lsn, int envid, u_int32_t flags)
7349{
7350 DBEnvObject *dbenv;
7351 PyObject* rep_transport;
7352 PyObject* args;
Jesus Cea4907d272008-08-31 14:00:51 +00007353 PyObject *a, *b;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007354 PyObject* result = NULL;
7355 int ret=0;
7356
7357 MYDB_BEGIN_BLOCK_THREADS;
7358 dbenv = (DBEnvObject *)db_env->app_private;
7359 rep_transport = dbenv->rep_transport;
7360
Jesus Cea4907d272008-08-31 14:00:51 +00007361 /*
7362 ** The errors in 'a' or 'b' are detected in "Py_BuildValue".
7363 */
7364 a = PyBytes_FromStringAndSize(control->data, control->size);
7365 b = PyBytes_FromStringAndSize(rec->data, rec->size);
7366
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007367 args = Py_BuildValue(
Jesus Cea4907d272008-08-31 14:00:51 +00007368 "(OOO(ll)iI)",
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007369 dbenv,
Jesus Cea4907d272008-08-31 14:00:51 +00007370 a, b,
7371 lsn->file, lsn->offset, envid, flags);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007372 if (args) {
7373 result = PyEval_CallObject(rep_transport, args);
7374 }
7375
7376 if ((!args) || (!result)) {
7377 PyErr_Print();
7378 ret = -1;
7379 }
Jesus Cea4907d272008-08-31 14:00:51 +00007380 Py_XDECREF(a);
7381 Py_XDECREF(b);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007382 Py_XDECREF(args);
7383 Py_XDECREF(result);
7384 MYDB_END_BLOCK_THREADS;
7385 return ret;
7386}
7387
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007388static PyObject*
7389DBEnv_rep_set_transport(DBEnvObject* self, PyObject* args)
7390{
7391 int err;
7392 int envid;
7393 PyObject *rep_transport;
7394
7395 if (!PyArg_ParseTuple(args, "iO:rep_set_transport", &envid, &rep_transport))
7396 return NULL;
7397 CHECK_ENV_NOT_CLOSED(self);
7398 if (!PyCallable_Check(rep_transport)) {
7399 makeTypeError("Callable", rep_transport);
7400 return NULL;
7401 }
7402
7403 MYDB_BEGIN_ALLOW_THREADS;
7404#if (DBVER >=45)
7405 err = self->db_env->rep_set_transport(self->db_env, envid,
7406 &_DBEnv_rep_transportCallback);
7407#else
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007408 err = self->db_env->set_rep_transport(self->db_env, envid,
7409 &_DBEnv_rep_transportCallback);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007410#endif
7411 MYDB_END_ALLOW_THREADS;
7412 RETURN_IF_ERR();
7413
7414 Py_DECREF(self->rep_transport);
7415 Py_INCREF(rep_transport);
7416 self->rep_transport = rep_transport;
7417 RETURN_NONE();
7418}
7419
7420#if (DBVER >= 47)
7421static PyObject*
7422DBEnv_rep_set_request(DBEnvObject* self, PyObject* args)
7423{
7424 int err;
7425 unsigned int minimum, maximum;
7426
7427 if (!PyArg_ParseTuple(args,"II:rep_set_request", &minimum, &maximum))
7428 return NULL;
7429 CHECK_ENV_NOT_CLOSED(self);
7430
7431 MYDB_BEGIN_ALLOW_THREADS;
7432 err = self->db_env->rep_set_request(self->db_env, minimum, maximum);
7433 MYDB_END_ALLOW_THREADS;
7434 RETURN_IF_ERR();
7435 RETURN_NONE();
7436}
7437
7438static PyObject*
7439DBEnv_rep_get_request(DBEnvObject* self)
7440{
7441 int err;
7442 u_int32_t minimum, maximum;
7443
7444 CHECK_ENV_NOT_CLOSED(self);
7445 MYDB_BEGIN_ALLOW_THREADS;
7446 err = self->db_env->rep_get_request(self->db_env, &minimum, &maximum);
7447 MYDB_END_ALLOW_THREADS;
7448 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007449 return Py_BuildValue("II", minimum, maximum);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007450}
7451#endif
7452
7453#if (DBVER >= 45)
7454static PyObject*
7455DBEnv_rep_set_limit(DBEnvObject* self, PyObject* args)
7456{
7457 int err;
7458 int limit;
7459
7460 if (!PyArg_ParseTuple(args,"i:rep_set_limit", &limit))
7461 return NULL;
7462 CHECK_ENV_NOT_CLOSED(self);
7463
7464 MYDB_BEGIN_ALLOW_THREADS;
7465 err = self->db_env->rep_set_limit(self->db_env, 0, limit);
7466 MYDB_END_ALLOW_THREADS;
7467 RETURN_IF_ERR();
7468 RETURN_NONE();
7469}
7470
7471static PyObject*
7472DBEnv_rep_get_limit(DBEnvObject* self)
7473{
7474 int err;
7475 u_int32_t gbytes, bytes;
7476
7477 CHECK_ENV_NOT_CLOSED(self);
7478 MYDB_BEGIN_ALLOW_THREADS;
7479 err = self->db_env->rep_get_limit(self->db_env, &gbytes, &bytes);
7480 MYDB_END_ALLOW_THREADS;
7481 RETURN_IF_ERR();
7482 return NUMBER_FromLong(bytes);
7483}
7484#endif
7485
7486#if (DBVER >= 44)
7487static PyObject*
7488DBEnv_rep_set_config(DBEnvObject* self, PyObject* args)
7489{
7490 int err;
7491 int which;
7492 int onoff;
7493
7494 if (!PyArg_ParseTuple(args,"ii:rep_set_config", &which, &onoff))
7495 return NULL;
7496 CHECK_ENV_NOT_CLOSED(self);
7497
7498 MYDB_BEGIN_ALLOW_THREADS;
7499 err = self->db_env->rep_set_config(self->db_env, which, onoff);
7500 MYDB_END_ALLOW_THREADS;
7501 RETURN_IF_ERR();
7502 RETURN_NONE();
7503}
7504
7505static PyObject*
7506DBEnv_rep_get_config(DBEnvObject* self, PyObject* args)
7507{
7508 int err;
7509 int which;
7510 int onoff;
7511
7512 if (!PyArg_ParseTuple(args, "i:rep_get_config", &which)) {
7513 return NULL;
7514 }
7515 CHECK_ENV_NOT_CLOSED(self);
7516 MYDB_BEGIN_ALLOW_THREADS;
7517 err = self->db_env->rep_get_config(self->db_env, which, &onoff);
7518 MYDB_END_ALLOW_THREADS;
7519 RETURN_IF_ERR();
7520 return PyBool_FromLong(onoff);
7521}
7522#endif
7523
7524#if (DBVER >= 46)
7525static PyObject*
7526DBEnv_rep_elect(DBEnvObject* self, PyObject* args)
7527{
7528 int err;
7529 u_int32_t nsites, nvotes;
7530
7531 if (!PyArg_ParseTuple(args, "II:rep_elect", &nsites, &nvotes)) {
7532 return NULL;
7533 }
7534 CHECK_ENV_NOT_CLOSED(self);
7535 MYDB_BEGIN_ALLOW_THREADS;
Jesus Cea2ab4a912012-01-16 23:57:34 +01007536 err = self->db_env->rep_elect(self->db_env, nsites, nvotes, 0);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007537 MYDB_END_ALLOW_THREADS;
7538 RETURN_IF_ERR();
7539 RETURN_NONE();
7540}
7541#endif
7542
7543static PyObject*
7544DBEnv_rep_start(DBEnvObject* self, PyObject* args, PyObject* kwargs)
7545{
7546 int err;
7547 PyObject *cdata_py = Py_None;
7548 DBT cdata;
7549 int flags;
7550 static char* kwnames[] = {"flags","cdata", NULL};
7551
7552 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
7553 "i|O:rep_start", kwnames, &flags, &cdata_py))
7554 {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00007555 return NULL;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007556 }
7557 CHECK_ENV_NOT_CLOSED(self);
7558
7559 if (!make_dbt(cdata_py, &cdata))
7560 return NULL;
7561
7562 MYDB_BEGIN_ALLOW_THREADS;
7563 err = self->db_env->rep_start(self->db_env, cdata.size ? &cdata : NULL,
7564 flags);
7565 MYDB_END_ALLOW_THREADS;
7566 RETURN_IF_ERR();
7567 RETURN_NONE();
7568}
7569
7570#if (DBVER >= 44)
7571static PyObject*
7572DBEnv_rep_sync(DBEnvObject* self)
7573{
7574 int err;
7575
7576 CHECK_ENV_NOT_CLOSED(self);
7577 MYDB_BEGIN_ALLOW_THREADS;
7578 err = self->db_env->rep_sync(self->db_env, 0);
7579 MYDB_END_ALLOW_THREADS;
7580 RETURN_IF_ERR();
7581 RETURN_NONE();
7582}
7583#endif
7584
7585
Jesus Ceaef9764f2008-05-13 18:45:46 +00007586#if (DBVER >= 45)
7587static PyObject*
7588DBEnv_rep_set_nsites(DBEnvObject* self, PyObject* args)
7589{
7590 int err;
7591 int nsites;
7592
7593 if (!PyArg_ParseTuple(args, "i:rep_set_nsites", &nsites)) {
7594 return NULL;
7595 }
7596 CHECK_ENV_NOT_CLOSED(self);
7597 MYDB_BEGIN_ALLOW_THREADS;
7598 err = self->db_env->rep_set_nsites(self->db_env, nsites);
7599 MYDB_END_ALLOW_THREADS;
7600 RETURN_IF_ERR();
7601 RETURN_NONE();
7602}
7603
7604static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007605DBEnv_rep_get_nsites(DBEnvObject* self)
Jesus Ceaef9764f2008-05-13 18:45:46 +00007606{
7607 int err;
Jesus Ceaca3939c2008-05-22 15:27:38 +00007608#if (DBVER >= 47)
7609 u_int32_t nsites;
7610#else
Jesus Ceaef9764f2008-05-13 18:45:46 +00007611 int nsites;
Jesus Ceaca3939c2008-05-22 15:27:38 +00007612#endif
Jesus Ceaef9764f2008-05-13 18:45:46 +00007613
Jesus Ceaef9764f2008-05-13 18:45:46 +00007614 CHECK_ENV_NOT_CLOSED(self);
7615 MYDB_BEGIN_ALLOW_THREADS;
7616 err = self->db_env->rep_get_nsites(self->db_env, &nsites);
7617 MYDB_END_ALLOW_THREADS;
7618 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007619 return NUMBER_FromLong(nsites);
Jesus Ceaef9764f2008-05-13 18:45:46 +00007620}
7621
7622static PyObject*
7623DBEnv_rep_set_priority(DBEnvObject* self, PyObject* args)
7624{
7625 int err;
7626 int priority;
7627
7628 if (!PyArg_ParseTuple(args, "i:rep_set_priority", &priority)) {
7629 return NULL;
7630 }
7631 CHECK_ENV_NOT_CLOSED(self);
7632 MYDB_BEGIN_ALLOW_THREADS;
7633 err = self->db_env->rep_set_priority(self->db_env, priority);
7634 MYDB_END_ALLOW_THREADS;
7635 RETURN_IF_ERR();
7636 RETURN_NONE();
7637}
7638
7639static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007640DBEnv_rep_get_priority(DBEnvObject* self)
Jesus Ceaef9764f2008-05-13 18:45:46 +00007641{
7642 int err;
Jesus Ceaca3939c2008-05-22 15:27:38 +00007643#if (DBVER >= 47)
7644 u_int32_t priority;
7645#else
Jesus Ceaef9764f2008-05-13 18:45:46 +00007646 int priority;
Jesus Ceaca3939c2008-05-22 15:27:38 +00007647#endif
Jesus Ceaef9764f2008-05-13 18:45:46 +00007648
Jesus Ceaef9764f2008-05-13 18:45:46 +00007649 CHECK_ENV_NOT_CLOSED(self);
7650 MYDB_BEGIN_ALLOW_THREADS;
7651 err = self->db_env->rep_get_priority(self->db_env, &priority);
7652 MYDB_END_ALLOW_THREADS;
7653 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007654 return NUMBER_FromLong(priority);
Jesus Ceaef9764f2008-05-13 18:45:46 +00007655}
7656
7657static PyObject*
7658DBEnv_rep_set_timeout(DBEnvObject* self, PyObject* args)
7659{
7660 int err;
7661 int which, timeout;
7662
7663 if (!PyArg_ParseTuple(args, "ii:rep_set_timeout", &which, &timeout)) {
7664 return NULL;
7665 }
7666 CHECK_ENV_NOT_CLOSED(self);
7667 MYDB_BEGIN_ALLOW_THREADS;
7668 err = self->db_env->rep_set_timeout(self->db_env, which, timeout);
7669 MYDB_END_ALLOW_THREADS;
7670 RETURN_IF_ERR();
7671 RETURN_NONE();
7672}
7673
7674static PyObject*
7675DBEnv_rep_get_timeout(DBEnvObject* self, PyObject* args)
7676{
7677 int err;
7678 int which;
7679 u_int32_t timeout;
7680
7681 if (!PyArg_ParseTuple(args, "i:rep_get_timeout", &which)) {
7682 return NULL;
7683 }
7684 CHECK_ENV_NOT_CLOSED(self);
7685 MYDB_BEGIN_ALLOW_THREADS;
7686 err = self->db_env->rep_get_timeout(self->db_env, which, &timeout);
7687 MYDB_END_ALLOW_THREADS;
7688 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007689 return NUMBER_FromLong(timeout);
Jesus Ceaef9764f2008-05-13 18:45:46 +00007690}
7691#endif
7692
Jesus Cea6557aac2010-03-22 14:22:26 +00007693
7694#if (DBVER >= 47)
7695static PyObject*
7696DBEnv_rep_set_clockskew(DBEnvObject* self, PyObject* args)
7697{
7698 int err;
7699 unsigned int fast, slow;
7700
Jesus Cea6557aac2010-03-22 14:22:26 +00007701 if (!PyArg_ParseTuple(args,"II:rep_set_clockskew", &fast, &slow))
7702 return NULL;
Jesus Cea6557aac2010-03-22 14:22:26 +00007703
7704 CHECK_ENV_NOT_CLOSED(self);
7705
7706 MYDB_BEGIN_ALLOW_THREADS;
7707 err = self->db_env->rep_set_clockskew(self->db_env, fast, slow);
7708 MYDB_END_ALLOW_THREADS;
7709 RETURN_IF_ERR();
7710 RETURN_NONE();
7711}
7712
7713static PyObject*
7714DBEnv_rep_get_clockskew(DBEnvObject* self)
7715{
7716 int err;
7717 unsigned int fast, slow;
7718
7719 CHECK_ENV_NOT_CLOSED(self);
7720 MYDB_BEGIN_ALLOW_THREADS;
7721 err = self->db_env->rep_get_clockskew(self->db_env, &fast, &slow);
7722 MYDB_END_ALLOW_THREADS;
7723 RETURN_IF_ERR();
Jesus Cea6557aac2010-03-22 14:22:26 +00007724 return Py_BuildValue("(II)", fast, slow);
Jesus Cea6557aac2010-03-22 14:22:26 +00007725}
7726#endif
7727
Jesus Cea6557aac2010-03-22 14:22:26 +00007728static PyObject*
7729DBEnv_rep_stat_print(DBEnvObject* self, PyObject* args, PyObject *kwargs)
7730{
7731 int err;
7732 int flags=0;
7733 static char* kwnames[] = { "flags", NULL };
7734
7735 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:rep_stat_print",
7736 kwnames, &flags))
7737 {
7738 return NULL;
7739 }
7740 CHECK_ENV_NOT_CLOSED(self);
7741 MYDB_BEGIN_ALLOW_THREADS;
7742 err = self->db_env->rep_stat_print(self->db_env, flags);
7743 MYDB_END_ALLOW_THREADS;
7744 RETURN_IF_ERR();
7745 RETURN_NONE();
7746}
Jesus Cea6557aac2010-03-22 14:22:26 +00007747
7748static PyObject*
7749DBEnv_rep_stat(DBEnvObject* self, PyObject* args, PyObject *kwargs)
7750{
7751 int err;
7752 int flags=0;
7753 DB_REP_STAT *statp;
7754 PyObject *stats;
7755 static char* kwnames[] = { "flags", NULL };
7756
7757 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:rep_stat",
7758 kwnames, &flags))
7759 {
7760 return NULL;
7761 }
7762 CHECK_ENV_NOT_CLOSED(self);
7763 MYDB_BEGIN_ALLOW_THREADS;
7764 err = self->db_env->rep_stat(self->db_env, &statp, flags);
7765 MYDB_END_ALLOW_THREADS;
7766 RETURN_IF_ERR();
7767
7768 stats=PyDict_New();
7769 if (stats == NULL) {
7770 free(statp);
7771 return NULL;
7772 }
7773
7774#define MAKE_ENTRY(name) _addIntToDict(stats, #name, statp->st_##name)
7775#define MAKE_DB_LSN_ENTRY(name) _addDB_lsnToDict(stats , #name, statp->st_##name)
7776
7777#if (DBVER >= 44)
7778 MAKE_ENTRY(bulk_fills);
7779 MAKE_ENTRY(bulk_overflows);
7780 MAKE_ENTRY(bulk_records);
7781 MAKE_ENTRY(bulk_transfers);
7782 MAKE_ENTRY(client_rerequests);
7783 MAKE_ENTRY(client_svc_miss);
7784 MAKE_ENTRY(client_svc_req);
7785#endif
7786 MAKE_ENTRY(dupmasters);
Jesus Cea6557aac2010-03-22 14:22:26 +00007787 MAKE_ENTRY(egen);
7788 MAKE_ENTRY(election_nvotes);
7789 MAKE_ENTRY(startup_complete);
7790 MAKE_ENTRY(pg_duplicated);
7791 MAKE_ENTRY(pg_records);
7792 MAKE_ENTRY(pg_requested);
7793 MAKE_ENTRY(next_pg);
7794 MAKE_ENTRY(waiting_pg);
Jesus Cea6557aac2010-03-22 14:22:26 +00007795 MAKE_ENTRY(election_cur_winner);
7796 MAKE_ENTRY(election_gen);
7797 MAKE_DB_LSN_ENTRY(election_lsn);
7798 MAKE_ENTRY(election_nsites);
7799 MAKE_ENTRY(election_priority);
7800#if (DBVER >= 44)
7801 MAKE_ENTRY(election_sec);
7802 MAKE_ENTRY(election_usec);
7803#endif
7804 MAKE_ENTRY(election_status);
7805 MAKE_ENTRY(election_tiebreaker);
7806 MAKE_ENTRY(election_votes);
7807 MAKE_ENTRY(elections);
7808 MAKE_ENTRY(elections_won);
7809 MAKE_ENTRY(env_id);
7810 MAKE_ENTRY(env_priority);
7811 MAKE_ENTRY(gen);
7812 MAKE_ENTRY(log_duplicated);
7813 MAKE_ENTRY(log_queued);
7814 MAKE_ENTRY(log_queued_max);
7815 MAKE_ENTRY(log_queued_total);
7816 MAKE_ENTRY(log_records);
7817 MAKE_ENTRY(log_requested);
7818 MAKE_ENTRY(master);
7819 MAKE_ENTRY(master_changes);
7820#if (DBVER >= 47)
7821 MAKE_ENTRY(max_lease_sec);
7822 MAKE_ENTRY(max_lease_usec);
7823 MAKE_DB_LSN_ENTRY(max_perm_lsn);
7824#endif
7825 MAKE_ENTRY(msgs_badgen);
7826 MAKE_ENTRY(msgs_processed);
7827 MAKE_ENTRY(msgs_recover);
7828 MAKE_ENTRY(msgs_send_failures);
7829 MAKE_ENTRY(msgs_sent);
7830 MAKE_ENTRY(newsites);
7831 MAKE_DB_LSN_ENTRY(next_lsn);
7832 MAKE_ENTRY(nsites);
7833 MAKE_ENTRY(nthrottles);
7834 MAKE_ENTRY(outdated);
7835#if (DBVER >= 46)
7836 MAKE_ENTRY(startsync_delayed);
7837#endif
7838 MAKE_ENTRY(status);
7839 MAKE_ENTRY(txns_applied);
7840 MAKE_DB_LSN_ENTRY(waiting_lsn);
7841
7842#undef MAKE_DB_LSN_ENTRY
7843#undef MAKE_ENTRY
7844
7845 free(statp);
7846 return stats;
7847}
7848
Jesus Ceaef9764f2008-05-13 18:45:46 +00007849/* --------------------------------------------------------------------- */
7850/* REPLICATION METHODS: Replication Manager */
7851
7852#if (DBVER >= 45)
7853static PyObject*
7854DBEnv_repmgr_start(DBEnvObject* self, PyObject* args, PyObject*
7855 kwargs)
7856{
7857 int err;
7858 int nthreads, flags;
7859 static char* kwnames[] = {"nthreads","flags", NULL};
7860
7861 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
7862 "ii:repmgr_start", kwnames, &nthreads, &flags))
7863 {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00007864 return NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00007865 }
7866 CHECK_ENV_NOT_CLOSED(self);
7867 MYDB_BEGIN_ALLOW_THREADS;
7868 err = self->db_env->repmgr_start(self->db_env, nthreads, flags);
7869 MYDB_END_ALLOW_THREADS;
7870 RETURN_IF_ERR();
7871 RETURN_NONE();
7872}
7873
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07007874#if (DBVER < 52)
Jesus Ceaef9764f2008-05-13 18:45:46 +00007875static PyObject*
7876DBEnv_repmgr_set_local_site(DBEnvObject* self, PyObject* args, PyObject*
7877 kwargs)
7878{
7879 int err;
7880 char *host;
7881 int port;
7882 int flags = 0;
7883 static char* kwnames[] = {"host", "port", "flags", NULL};
7884
7885 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
7886 "si|i:repmgr_set_local_site", kwnames, &host, &port, &flags))
7887 {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00007888 return NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00007889 }
7890 CHECK_ENV_NOT_CLOSED(self);
7891 MYDB_BEGIN_ALLOW_THREADS;
7892 err = self->db_env->repmgr_set_local_site(self->db_env, host, port, flags);
7893 MYDB_END_ALLOW_THREADS;
7894 RETURN_IF_ERR();
7895 RETURN_NONE();
7896}
7897
7898static PyObject*
7899DBEnv_repmgr_add_remote_site(DBEnvObject* self, PyObject* args, PyObject*
7900 kwargs)
7901{
7902 int err;
7903 char *host;
7904 int port;
7905 int flags = 0;
7906 int eidp;
7907 static char* kwnames[] = {"host", "port", "flags", NULL};
7908
7909 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
7910 "si|i:repmgr_add_remote_site", kwnames, &host, &port, &flags))
7911 {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00007912 return NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00007913 }
7914 CHECK_ENV_NOT_CLOSED(self);
7915 MYDB_BEGIN_ALLOW_THREADS;
7916 err = self->db_env->repmgr_add_remote_site(self->db_env, host, port, &eidp, flags);
7917 MYDB_END_ALLOW_THREADS;
7918 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007919 return NUMBER_FromLong(eidp);
Jesus Ceaef9764f2008-05-13 18:45:46 +00007920}
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07007921#endif
Jesus Ceaef9764f2008-05-13 18:45:46 +00007922
7923static PyObject*
7924DBEnv_repmgr_set_ack_policy(DBEnvObject* self, PyObject* args)
7925{
7926 int err;
7927 int ack_policy;
7928
7929 if (!PyArg_ParseTuple(args, "i:repmgr_set_ack_policy", &ack_policy))
7930 {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00007931 return NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00007932 }
7933 CHECK_ENV_NOT_CLOSED(self);
7934 MYDB_BEGIN_ALLOW_THREADS;
7935 err = self->db_env->repmgr_set_ack_policy(self->db_env, ack_policy);
7936 MYDB_END_ALLOW_THREADS;
7937 RETURN_IF_ERR();
7938 RETURN_NONE();
7939}
7940
7941static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007942DBEnv_repmgr_get_ack_policy(DBEnvObject* self)
Jesus Ceaef9764f2008-05-13 18:45:46 +00007943{
7944 int err;
7945 int ack_policy;
7946
Jesus Ceaef9764f2008-05-13 18:45:46 +00007947 CHECK_ENV_NOT_CLOSED(self);
7948 MYDB_BEGIN_ALLOW_THREADS;
7949 err = self->db_env->repmgr_get_ack_policy(self->db_env, &ack_policy);
7950 MYDB_END_ALLOW_THREADS;
7951 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007952 return NUMBER_FromLong(ack_policy);
Jesus Ceaef9764f2008-05-13 18:45:46 +00007953}
7954
7955static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007956DBEnv_repmgr_site_list(DBEnvObject* self)
Jesus Ceaef9764f2008-05-13 18:45:46 +00007957{
7958 int err;
7959 unsigned int countp;
7960 DB_REPMGR_SITE *listp;
7961 PyObject *stats, *key, *tuple;
7962
Jesus Ceaef9764f2008-05-13 18:45:46 +00007963 CHECK_ENV_NOT_CLOSED(self);
7964 MYDB_BEGIN_ALLOW_THREADS;
7965 err = self->db_env->repmgr_site_list(self->db_env, &countp, &listp);
7966 MYDB_END_ALLOW_THREADS;
7967 RETURN_IF_ERR();
7968
7969 stats=PyDict_New();
7970 if (stats == NULL) {
7971 free(listp);
7972 return NULL;
7973 }
7974
7975 for(;countp--;) {
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007976 key=NUMBER_FromLong(listp[countp].eid);
Jesus Ceaef9764f2008-05-13 18:45:46 +00007977 if(!key) {
7978 Py_DECREF(stats);
7979 free(listp);
7980 return NULL;
7981 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00007982 tuple=Py_BuildValue("(sII)", listp[countp].host,
7983 listp[countp].port, listp[countp].status);
Jesus Ceaef9764f2008-05-13 18:45:46 +00007984 if(!tuple) {
7985 Py_DECREF(key);
7986 Py_DECREF(stats);
7987 free(listp);
7988 return NULL;
7989 }
7990 if(PyDict_SetItem(stats, key, tuple)) {
7991 Py_DECREF(key);
7992 Py_DECREF(tuple);
7993 Py_DECREF(stats);
7994 free(listp);
7995 return NULL;
7996 }
Florent Xiclunae7901c52010-03-01 20:45:01 +00007997 Py_DECREF(key);
7998 Py_DECREF(tuple);
Jesus Ceaef9764f2008-05-13 18:45:46 +00007999 }
8000 free(listp);
8001 return stats;
8002}
8003#endif
8004
8005#if (DBVER >= 46)
8006static PyObject*
8007DBEnv_repmgr_stat_print(DBEnvObject* self, PyObject* args, PyObject *kwargs)
8008{
8009 int err;
8010 int flags=0;
8011 static char* kwnames[] = { "flags", NULL };
8012
8013 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:repmgr_stat_print",
8014 kwnames, &flags))
8015 {
8016 return NULL;
8017 }
8018 CHECK_ENV_NOT_CLOSED(self);
8019 MYDB_BEGIN_ALLOW_THREADS;
8020 err = self->db_env->repmgr_stat_print(self->db_env, flags);
8021 MYDB_END_ALLOW_THREADS;
8022 RETURN_IF_ERR();
8023 RETURN_NONE();
8024}
8025
8026static PyObject*
8027DBEnv_repmgr_stat(DBEnvObject* self, PyObject* args, PyObject *kwargs)
8028{
8029 int err;
8030 int flags=0;
8031 DB_REPMGR_STAT *statp;
8032 PyObject *stats;
8033 static char* kwnames[] = { "flags", NULL };
8034
8035 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:repmgr_stat",
8036 kwnames, &flags))
8037 {
8038 return NULL;
8039 }
8040 CHECK_ENV_NOT_CLOSED(self);
8041 MYDB_BEGIN_ALLOW_THREADS;
8042 err = self->db_env->repmgr_stat(self->db_env, &statp, flags);
8043 MYDB_END_ALLOW_THREADS;
8044 RETURN_IF_ERR();
8045
8046 stats=PyDict_New();
8047 if (stats == NULL) {
8048 free(statp);
8049 return NULL;
8050 }
8051
8052#define MAKE_ENTRY(name) _addIntToDict(stats, #name, statp->st_##name)
8053
8054 MAKE_ENTRY(perm_failed);
8055 MAKE_ENTRY(msgs_queued);
8056 MAKE_ENTRY(msgs_dropped);
8057 MAKE_ENTRY(connection_drop);
8058 MAKE_ENTRY(connect_fail);
8059
8060#undef MAKE_ENTRY
8061
8062 free(statp);
8063 return stats;
8064}
8065#endif
8066
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008067
8068/* --------------------------------------------------------------------- */
8069/* DBTxn methods */
8070
8071
Jesus Ceaef9764f2008-05-13 18:45:46 +00008072static void _close_transaction_cursors(DBTxnObject* txn)
8073{
8074 PyObject *dummy;
8075
8076 while(txn->children_cursors) {
8077 PyErr_Warn(PyExc_RuntimeWarning,
8078 "Must close cursors before resolving a transaction.");
8079 dummy=DBC_close_internal(txn->children_cursors);
8080 Py_XDECREF(dummy);
8081 }
8082}
8083
8084static void _promote_transaction_dbs_and_sequences(DBTxnObject *txn)
8085{
8086 DBObject *db;
Jesus Ceaef9764f2008-05-13 18:45:46 +00008087 DBSequenceObject *dbs;
Jesus Ceaef9764f2008-05-13 18:45:46 +00008088
8089 while (txn->children_dbs) {
8090 db=txn->children_dbs;
8091 EXTRACT_FROM_DOUBLE_LINKED_LIST_TXN(db);
8092 if (txn->parent_txn) {
8093 INSERT_IN_DOUBLE_LINKED_LIST_TXN(txn->parent_txn->children_dbs,db);
8094 db->txn=txn->parent_txn;
8095 } else {
8096 /* The db is already linked to its environment,
8097 ** so nothing to do.
8098 */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00008099 db->txn=NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00008100 }
8101 }
8102
Jesus Ceaef9764f2008-05-13 18:45:46 +00008103 while (txn->children_sequences) {
8104 dbs=txn->children_sequences;
8105 EXTRACT_FROM_DOUBLE_LINKED_LIST_TXN(dbs);
8106 if (txn->parent_txn) {
8107 INSERT_IN_DOUBLE_LINKED_LIST_TXN(txn->parent_txn->children_sequences,dbs);
8108 dbs->txn=txn->parent_txn;
8109 } else {
8110 /* The sequence is already linked to its
8111 ** parent db. Nothing to do.
8112 */
8113 dbs->txn=NULL;
8114 }
8115 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00008116}
8117
8118
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008119static PyObject*
8120DBTxn_commit(DBTxnObject* self, PyObject* args)
8121{
8122 int flags=0, err;
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008123 DB_TXN *txn;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008124
8125 if (!PyArg_ParseTuple(args, "|i:commit", &flags))
8126 return NULL;
8127
Jesus Ceaef9764f2008-05-13 18:45:46 +00008128 _close_transaction_cursors(self);
8129
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008130 if (!self->txn) {
Thomas Woutersb3153832006-03-08 01:47:19 +00008131 PyObject *t = Py_BuildValue("(is)", 0, "DBTxn must not be used "
Jesus Ceaef9764f2008-05-13 18:45:46 +00008132 "after txn_commit, txn_abort "
8133 "or txn_discard");
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008134 if (t) {
8135 PyErr_SetObject(DBError, t);
8136 Py_DECREF(t);
8137 }
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008138 return NULL;
8139 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00008140 self->flag_prepare=0;
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008141 txn = self->txn;
8142 self->txn = NULL; /* this DB_TXN is no longer valid after this call */
Jesus Ceaef9764f2008-05-13 18:45:46 +00008143
8144 EXTRACT_FROM_DOUBLE_LINKED_LIST(self);
8145
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008146 MYDB_BEGIN_ALLOW_THREADS;
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008147 err = txn->commit(txn, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008148 MYDB_END_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00008149
8150 _promote_transaction_dbs_and_sequences(self);
8151
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008152 RETURN_IF_ERR();
8153 RETURN_NONE();
8154}
8155
8156static PyObject*
8157DBTxn_prepare(DBTxnObject* self, PyObject* args)
8158{
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008159 int err;
8160 char* gid=NULL;
8161 int gid_size=0;
8162
8163 if (!PyArg_ParseTuple(args, "s#:prepare", &gid, &gid_size))
8164 return NULL;
8165
Matthias Klose54cc5392010-03-15 12:46:18 +00008166 if (gid_size != DB_GID_SIZE) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008167 PyErr_SetString(PyExc_TypeError,
Matthias Klose54cc5392010-03-15 12:46:18 +00008168 "gid must be DB_GID_SIZE bytes long");
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008169 return NULL;
8170 }
8171
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008172 if (!self->txn) {
Thomas Woutersb3153832006-03-08 01:47:19 +00008173 PyObject *t = Py_BuildValue("(is)", 0,"DBTxn must not be used "
Jesus Ceaef9764f2008-05-13 18:45:46 +00008174 "after txn_commit, txn_abort "
8175 "or txn_discard");
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008176 if (t) {
8177 PyErr_SetObject(DBError, t);
8178 Py_DECREF(t);
8179 }
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008180 return NULL;
8181 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00008182 self->flag_prepare=1; /* Prepare state */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008183 MYDB_BEGIN_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008184 err = self->txn->prepare(self->txn, (u_int8_t*)gid);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008185 MYDB_END_ALLOW_THREADS;
8186 RETURN_IF_ERR();
8187 RETURN_NONE();
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008188}
8189
8190
8191static PyObject*
Jesus Ceaef9764f2008-05-13 18:45:46 +00008192DBTxn_abort_discard_internal(DBTxnObject* self, int discard)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008193{
Jesus Ceaef9764f2008-05-13 18:45:46 +00008194 PyObject *dummy;
8195 int err=0;
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008196 DB_TXN *txn;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008197
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008198 if (!self->txn) {
Thomas Woutersb3153832006-03-08 01:47:19 +00008199 PyObject *t = Py_BuildValue("(is)", 0, "DBTxn must not be used "
Jesus Ceaef9764f2008-05-13 18:45:46 +00008200 "after txn_commit, txn_abort "
8201 "or txn_discard");
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008202 if (t) {
8203 PyErr_SetObject(DBError, t);
8204 Py_DECREF(t);
8205 }
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008206 return NULL;
8207 }
8208 txn = self->txn;
8209 self->txn = NULL; /* this DB_TXN is no longer valid after this call */
Jesus Ceaef9764f2008-05-13 18:45:46 +00008210
8211 _close_transaction_cursors(self);
Jesus Ceaef9764f2008-05-13 18:45:46 +00008212 while (self->children_sequences) {
8213 dummy=DBSequence_close_internal(self->children_sequences,0,0);
8214 Py_XDECREF(dummy);
8215 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00008216 while (self->children_dbs) {
Jesus Cea5cd5f122008-09-23 18:54:08 +00008217 dummy=DB_close_internal(self->children_dbs, 0, 0);
Jesus Ceaef9764f2008-05-13 18:45:46 +00008218 Py_XDECREF(dummy);
8219 }
8220
8221 EXTRACT_FROM_DOUBLE_LINKED_LIST(self);
8222
8223 MYDB_BEGIN_ALLOW_THREADS;
8224 if (discard) {
8225 assert(!self->flag_prepare);
Jesus Ceaef9764f2008-05-13 18:45:46 +00008226 err = txn->discard(txn,0);
Jesus Ceaef9764f2008-05-13 18:45:46 +00008227 } else {
8228 /*
8229 ** If the transaction is in the "prepare" or "recover" state,
8230 ** we better do not implicitly abort it.
8231 */
8232 if (!self->flag_prepare) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00008233 err = txn->abort(txn);
Jesus Ceaef9764f2008-05-13 18:45:46 +00008234 }
8235 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008236 MYDB_END_ALLOW_THREADS;
8237 RETURN_IF_ERR();
8238 RETURN_NONE();
8239}
8240
Jesus Ceaef9764f2008-05-13 18:45:46 +00008241static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008242DBTxn_abort(DBTxnObject* self)
Jesus Ceaef9764f2008-05-13 18:45:46 +00008243{
Jesus Ceaef9764f2008-05-13 18:45:46 +00008244 self->flag_prepare=0;
8245 _close_transaction_cursors(self);
8246
8247 return DBTxn_abort_discard_internal(self,0);
8248}
8249
8250static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008251DBTxn_discard(DBTxnObject* self)
Jesus Ceaef9764f2008-05-13 18:45:46 +00008252{
Jesus Ceaef9764f2008-05-13 18:45:46 +00008253 self->flag_prepare=0;
8254 _close_transaction_cursors(self);
8255
8256 return DBTxn_abort_discard_internal(self,1);
8257}
8258
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008259
8260static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008261DBTxn_id(DBTxnObject* self)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008262{
8263 int id;
8264
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008265 if (!self->txn) {
Thomas Woutersb3153832006-03-08 01:47:19 +00008266 PyObject *t = Py_BuildValue("(is)", 0, "DBTxn must not be used "
Jesus Ceaef9764f2008-05-13 18:45:46 +00008267 "after txn_commit, txn_abort "
8268 "or txn_discard");
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008269 if (t) {
8270 PyErr_SetObject(DBError, t);
8271 Py_DECREF(t);
8272 }
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008273 return NULL;
8274 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008275 MYDB_BEGIN_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008276 id = self->txn->id(self->txn);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008277 MYDB_END_ALLOW_THREADS;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008278 return NUMBER_FromLong(id);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008279}
8280
Jesus Cea6557aac2010-03-22 14:22:26 +00008281
8282static PyObject*
8283DBTxn_set_timeout(DBTxnObject* self, PyObject* args, PyObject* kwargs)
8284{
8285 int err;
8286 u_int32_t flags=0;
8287 u_int32_t timeout = 0;
8288 static char* kwnames[] = { "timeout", "flags", NULL };
8289
8290 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ii:set_timeout", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00008291 &timeout, &flags)) {
8292 return NULL;
Jesus Cea6557aac2010-03-22 14:22:26 +00008293 }
8294
8295 MYDB_BEGIN_ALLOW_THREADS;
8296 err = self->txn->set_timeout(self->txn, (db_timeout_t)timeout, flags);
8297 MYDB_END_ALLOW_THREADS;
8298
8299 RETURN_IF_ERR();
8300 RETURN_NONE();
8301}
8302
8303
8304#if (DBVER >= 44)
8305static PyObject*
8306DBTxn_set_name(DBTxnObject* self, PyObject* args)
8307{
8308 int err;
8309 const char *name;
8310
8311 if (!PyArg_ParseTuple(args, "s:set_name", &name))
8312 return NULL;
8313
8314 MYDB_BEGIN_ALLOW_THREADS;
8315 err = self->txn->set_name(self->txn, name);
8316 MYDB_END_ALLOW_THREADS;
8317
8318 RETURN_IF_ERR();
8319 RETURN_NONE();
8320}
8321#endif
8322
8323
8324#if (DBVER >= 44)
8325static PyObject*
8326DBTxn_get_name(DBTxnObject* self)
8327{
8328 int err;
8329 const char *name;
8330
8331 MYDB_BEGIN_ALLOW_THREADS;
8332 err = self->txn->get_name(self->txn, &name);
8333 MYDB_END_ALLOW_THREADS;
8334
8335 RETURN_IF_ERR();
8336#if (PY_VERSION_HEX < 0x03000000)
8337 if (!name) {
8338 return PyString_FromString("");
8339 }
8340 return PyString_FromString(name);
8341#else
8342 if (!name) {
8343 return PyUnicode_FromString("");
8344 }
8345 return PyUnicode_FromString(name);
8346#endif
8347}
8348#endif
8349
8350
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008351/* --------------------------------------------------------------------- */
8352/* DBSequence methods */
8353
8354
8355static PyObject*
Jesus Ceaef9764f2008-05-13 18:45:46 +00008356DBSequence_close_internal(DBSequenceObject* self, int flags, int do_not_close)
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008357{
Jesus Ceaef9764f2008-05-13 18:45:46 +00008358 int err=0;
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008359
Jesus Ceaef9764f2008-05-13 18:45:46 +00008360 if (self->sequence!=NULL) {
8361 EXTRACT_FROM_DOUBLE_LINKED_LIST(self);
8362 if (self->txn) {
8363 EXTRACT_FROM_DOUBLE_LINKED_LIST_TXN(self);
8364 self->txn=NULL;
8365 }
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008366
Jesus Cea5cd5f122008-09-23 18:54:08 +00008367 /*
8368 ** "do_not_close" is used to dispose all related objects in the
8369 ** tree, without actually releasing the "root" object.
8370 ** This is done, for example, because function calls like
8371 ** "DBSequence.remove()" implicitly close the underlying handle. So
8372 ** the handle doesn't need to be closed, but related objects
8373 ** must be cleaned up.
8374 */
Jesus Ceaef9764f2008-05-13 18:45:46 +00008375 if (!do_not_close) {
8376 MYDB_BEGIN_ALLOW_THREADS
8377 err = self->sequence->close(self->sequence, flags);
8378 MYDB_END_ALLOW_THREADS
8379 }
8380 self->sequence = NULL;
8381
8382 RETURN_IF_ERR();
8383 }
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008384
8385 RETURN_NONE();
8386}
8387
8388static PyObject*
Jesus Ceaef9764f2008-05-13 18:45:46 +00008389DBSequence_close(DBSequenceObject* self, PyObject* args)
8390{
8391 int flags=0;
8392 if (!PyArg_ParseTuple(args,"|i:close", &flags))
8393 return NULL;
8394
8395 return DBSequence_close_internal(self,flags,0);
8396}
8397
8398static PyObject*
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008399DBSequence_get(DBSequenceObject* self, PyObject* args, PyObject* kwargs)
8400{
8401 int err, flags = 0;
8402 int delta = 1;
8403 db_seq_t value;
8404 PyObject *txnobj = NULL;
8405 DB_TXN *txn = NULL;
8406 static char* kwnames[] = {"delta", "txn", "flags", NULL };
8407 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|iOi:get", kwnames, &delta, &txnobj, &flags))
8408 return NULL;
8409 CHECK_SEQUENCE_NOT_CLOSED(self)
8410
8411 if (!checkTxnObj(txnobj, &txn))
8412 return NULL;
8413
8414 MYDB_BEGIN_ALLOW_THREADS
8415 err = self->sequence->get(self->sequence, txn, delta, &value, flags);
8416 MYDB_END_ALLOW_THREADS
8417
8418 RETURN_IF_ERR();
8419 return PyLong_FromLongLong(value);
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008420}
8421
8422static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008423DBSequence_get_dbp(DBSequenceObject* self)
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008424{
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008425 CHECK_SEQUENCE_NOT_CLOSED(self)
8426 Py_INCREF(self->mydb);
8427 return (PyObject* )self->mydb;
8428}
8429
8430static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008431DBSequence_get_key(DBSequenceObject* self)
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008432{
8433 int err;
8434 DBT key;
Neal Norwitz088beae2007-10-12 03:01:54 +00008435 PyObject *retval = NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00008436
Gregory P. Smithe70be5c2007-10-06 07:48:10 +00008437 key.flags = DB_DBT_MALLOC;
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008438 CHECK_SEQUENCE_NOT_CLOSED(self)
8439 MYDB_BEGIN_ALLOW_THREADS
8440 err = self->sequence->get_key(self->sequence, &key);
8441 MYDB_END_ALLOW_THREADS
8442
Gregory P. Smithe70be5c2007-10-06 07:48:10 +00008443 if (!err)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008444 retval = Build_PyString(key.data, key.size);
Gregory P. Smithe70be5c2007-10-06 07:48:10 +00008445
8446 FREE_DBT(key);
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008447 RETURN_IF_ERR();
8448
Gregory P. Smithe70be5c2007-10-06 07:48:10 +00008449 return retval;
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008450}
8451
8452static PyObject*
Jesus Cea6557aac2010-03-22 14:22:26 +00008453DBSequence_initial_value(DBSequenceObject* self, PyObject* args)
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008454{
8455 int err;
Jesus Ceaef9764f2008-05-13 18:45:46 +00008456 PY_LONG_LONG value;
8457 db_seq_t value2;
Jesus Cea6557aac2010-03-22 14:22:26 +00008458 if (!PyArg_ParseTuple(args,"L:initial_value", &value))
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008459 return NULL;
8460 CHECK_SEQUENCE_NOT_CLOSED(self)
8461
Jesus Ceaef9764f2008-05-13 18:45:46 +00008462 value2=value; /* If truncation, compiler should show a warning */
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008463 MYDB_BEGIN_ALLOW_THREADS
Jesus Ceaef9764f2008-05-13 18:45:46 +00008464 err = self->sequence->initial_value(self->sequence, value2);
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008465 MYDB_END_ALLOW_THREADS
8466
8467 RETURN_IF_ERR();
8468
8469 RETURN_NONE();
8470}
8471
8472static PyObject*
8473DBSequence_open(DBSequenceObject* self, PyObject* args, PyObject* kwargs)
8474{
8475 int err, flags = 0;
8476 PyObject* keyobj;
8477 PyObject *txnobj = NULL;
8478 DB_TXN *txn = NULL;
8479 DBT key;
8480
8481 static char* kwnames[] = {"key", "txn", "flags", NULL };
Neal Norwitzdd2a6bf2006-06-06 07:23:01 +00008482 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|Oi:open", kwnames, &keyobj, &txnobj, &flags))
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008483 return NULL;
8484
8485 if (!checkTxnObj(txnobj, &txn))
8486 return NULL;
8487
8488 if (!make_key_dbt(self->mydb, keyobj, &key, NULL))
8489 return NULL;
8490
8491 MYDB_BEGIN_ALLOW_THREADS
8492 err = self->sequence->open(self->sequence, txn, &key, flags);
8493 MYDB_END_ALLOW_THREADS
8494
Jesus Ceaac25fab2008-09-03 17:50:32 +00008495 FREE_DBT(key);
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008496 RETURN_IF_ERR();
8497
Jesus Ceaef9764f2008-05-13 18:45:46 +00008498 if (txn) {
8499 INSERT_IN_DOUBLE_LINKED_LIST_TXN(((DBTxnObject *)txnobj)->children_sequences,self);
8500 self->txn=(DBTxnObject *)txnobj;
8501 }
8502
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008503 RETURN_NONE();
8504}
8505
8506static PyObject*
8507DBSequence_remove(DBSequenceObject* self, PyObject* args, PyObject* kwargs)
8508{
Jesus Ceaef9764f2008-05-13 18:45:46 +00008509 PyObject *dummy;
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008510 int err, flags = 0;
8511 PyObject *txnobj = NULL;
8512 DB_TXN *txn = NULL;
8513
8514 static char* kwnames[] = {"txn", "flags", NULL };
Neal Norwitzdd2a6bf2006-06-06 07:23:01 +00008515 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Oi:remove", kwnames, &txnobj, &flags))
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008516 return NULL;
8517
8518 if (!checkTxnObj(txnobj, &txn))
8519 return NULL;
8520
8521 CHECK_SEQUENCE_NOT_CLOSED(self)
8522
8523 MYDB_BEGIN_ALLOW_THREADS
8524 err = self->sequence->remove(self->sequence, txn, flags);
8525 MYDB_END_ALLOW_THREADS
8526
Jesus Ceaef9764f2008-05-13 18:45:46 +00008527 dummy=DBSequence_close_internal(self,flags,1);
8528 Py_XDECREF(dummy);
8529
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008530 RETURN_IF_ERR();
8531 RETURN_NONE();
8532}
8533
8534static PyObject*
8535DBSequence_set_cachesize(DBSequenceObject* self, PyObject* args)
8536{
8537 int err, size;
Neal Norwitzdd2a6bf2006-06-06 07:23:01 +00008538 if (!PyArg_ParseTuple(args,"i:set_cachesize", &size))
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008539 return NULL;
8540 CHECK_SEQUENCE_NOT_CLOSED(self)
8541
8542 MYDB_BEGIN_ALLOW_THREADS
8543 err = self->sequence->set_cachesize(self->sequence, size);
8544 MYDB_END_ALLOW_THREADS
8545
8546 RETURN_IF_ERR();
8547 RETURN_NONE();
8548}
8549
8550static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008551DBSequence_get_cachesize(DBSequenceObject* self)
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008552{
8553 int err, size;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008554
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008555 CHECK_SEQUENCE_NOT_CLOSED(self)
8556
8557 MYDB_BEGIN_ALLOW_THREADS
8558 err = self->sequence->get_cachesize(self->sequence, &size);
8559 MYDB_END_ALLOW_THREADS
8560
8561 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008562 return NUMBER_FromLong(size);
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008563}
8564
8565static PyObject*
8566DBSequence_set_flags(DBSequenceObject* self, PyObject* args)
8567{
8568 int err, flags = 0;
Neal Norwitzdd2a6bf2006-06-06 07:23:01 +00008569 if (!PyArg_ParseTuple(args,"i:set_flags", &flags))
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008570 return NULL;
8571 CHECK_SEQUENCE_NOT_CLOSED(self)
8572
8573 MYDB_BEGIN_ALLOW_THREADS
8574 err = self->sequence->set_flags(self->sequence, flags);
8575 MYDB_END_ALLOW_THREADS
8576
8577 RETURN_IF_ERR();
8578 RETURN_NONE();
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008579}
8580
8581static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008582DBSequence_get_flags(DBSequenceObject* self)
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008583{
8584 unsigned int flags;
8585 int err;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008586
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008587 CHECK_SEQUENCE_NOT_CLOSED(self)
8588
8589 MYDB_BEGIN_ALLOW_THREADS
8590 err = self->sequence->get_flags(self->sequence, &flags);
8591 MYDB_END_ALLOW_THREADS
8592
8593 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008594 return NUMBER_FromLong((int)flags);
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008595}
8596
8597static PyObject*
8598DBSequence_set_range(DBSequenceObject* self, PyObject* args)
8599{
8600 int err;
Jesus Ceaef9764f2008-05-13 18:45:46 +00008601 PY_LONG_LONG min, max;
8602 db_seq_t min2, max2;
Tim Petersbb21b2c2006-06-06 15:50:17 +00008603 if (!PyArg_ParseTuple(args,"(LL):set_range", &min, &max))
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008604 return NULL;
8605 CHECK_SEQUENCE_NOT_CLOSED(self)
8606
Jesus Ceaef9764f2008-05-13 18:45:46 +00008607 min2=min; /* If truncation, compiler should show a warning */
8608 max2=max;
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008609 MYDB_BEGIN_ALLOW_THREADS
Jesus Ceaef9764f2008-05-13 18:45:46 +00008610 err = self->sequence->set_range(self->sequence, min2, max2);
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008611 MYDB_END_ALLOW_THREADS
8612
8613 RETURN_IF_ERR();
8614 RETURN_NONE();
8615}
8616
8617static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008618DBSequence_get_range(DBSequenceObject* self)
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008619{
8620 int err;
Jesus Ceaef9764f2008-05-13 18:45:46 +00008621 PY_LONG_LONG min, max;
8622 db_seq_t min2, max2;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008623
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008624 CHECK_SEQUENCE_NOT_CLOSED(self)
8625
8626 MYDB_BEGIN_ALLOW_THREADS
Jesus Ceaef9764f2008-05-13 18:45:46 +00008627 err = self->sequence->get_range(self->sequence, &min2, &max2);
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008628 MYDB_END_ALLOW_THREADS
8629
8630 RETURN_IF_ERR();
Jesus Ceaef9764f2008-05-13 18:45:46 +00008631 min=min2; /* If truncation, compiler should show a warning */
8632 max=max2;
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008633 return Py_BuildValue("(LL)", min, max);
8634}
8635
Jesus Cea6557aac2010-03-22 14:22:26 +00008636
8637static PyObject*
8638DBSequence_stat_print(DBSequenceObject* self, PyObject* args, PyObject *kwargs)
8639{
8640 int err;
8641 int flags=0;
8642 static char* kwnames[] = { "flags", NULL };
8643
8644 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:stat_print",
8645 kwnames, &flags))
8646 {
8647 return NULL;
8648 }
8649
8650 CHECK_SEQUENCE_NOT_CLOSED(self);
8651
8652 MYDB_BEGIN_ALLOW_THREADS;
8653 err = self->sequence->stat_print(self->sequence, flags);
8654 MYDB_END_ALLOW_THREADS;
8655 RETURN_IF_ERR();
8656 RETURN_NONE();
8657}
8658
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008659static PyObject*
8660DBSequence_stat(DBSequenceObject* self, PyObject* args, PyObject* kwargs)
8661{
8662 int err, flags = 0;
8663 DB_SEQUENCE_STAT* sp = NULL;
8664 PyObject* dict_stat;
8665 static char* kwnames[] = {"flags", NULL };
8666 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:stat", kwnames, &flags))
8667 return NULL;
8668 CHECK_SEQUENCE_NOT_CLOSED(self);
8669
8670 MYDB_BEGIN_ALLOW_THREADS;
8671 err = self->sequence->stat(self->sequence, &sp, flags);
8672 MYDB_END_ALLOW_THREADS;
8673 RETURN_IF_ERR();
8674
8675 if ((dict_stat = PyDict_New()) == NULL) {
8676 free(sp);
8677 return NULL;
8678 }
8679
8680
8681#define MAKE_INT_ENTRY(name) _addIntToDict(dict_stat, #name, sp->st_##name)
8682#define MAKE_LONG_LONG_ENTRY(name) _addDb_seq_tToDict(dict_stat, #name, sp->st_##name)
8683
8684 MAKE_INT_ENTRY(wait);
8685 MAKE_INT_ENTRY(nowait);
8686 MAKE_LONG_LONG_ENTRY(current);
8687 MAKE_LONG_LONG_ENTRY(value);
8688 MAKE_LONG_LONG_ENTRY(last_value);
8689 MAKE_LONG_LONG_ENTRY(min);
8690 MAKE_LONG_LONG_ENTRY(max);
8691 MAKE_INT_ENTRY(cache_size);
8692 MAKE_INT_ENTRY(flags);
8693
8694#undef MAKE_INT_ENTRY
8695#undef MAKE_LONG_LONG_ENTRY
8696
8697 free(sp);
8698 return dict_stat;
8699}
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008700
8701
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008702/* --------------------------------------------------------------------- */
8703/* Method definition tables and type objects */
8704
8705static PyMethodDef DB_methods[] = {
Jesus Cea4907d272008-08-31 14:00:51 +00008706 {"append", (PyCFunction)DB_append, METH_VARARGS|METH_KEYWORDS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008707 {"associate", (PyCFunction)DB_associate, METH_VARARGS|METH_KEYWORDS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008708 {"close", (PyCFunction)DB_close, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008709#if (DBVER >= 47)
8710 {"compact", (PyCFunction)DB_compact, METH_VARARGS|METH_KEYWORDS},
8711#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008712 {"consume", (PyCFunction)DB_consume, METH_VARARGS|METH_KEYWORDS},
8713 {"consume_wait", (PyCFunction)DB_consume_wait, METH_VARARGS|METH_KEYWORDS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008714 {"cursor", (PyCFunction)DB_cursor, METH_VARARGS|METH_KEYWORDS},
8715 {"delete", (PyCFunction)DB_delete, METH_VARARGS|METH_KEYWORDS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008716 {"fd", (PyCFunction)DB_fd, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008717#if (DBVER >= 46)
8718 {"exists", (PyCFunction)DB_exists,
8719 METH_VARARGS|METH_KEYWORDS},
8720#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008721 {"get", (PyCFunction)DB_get, METH_VARARGS|METH_KEYWORDS},
Gregory P. Smith19699a92004-06-28 04:06:49 +00008722 {"pget", (PyCFunction)DB_pget, METH_VARARGS|METH_KEYWORDS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008723 {"get_both", (PyCFunction)DB_get_both, METH_VARARGS|METH_KEYWORDS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008724 {"get_byteswapped", (PyCFunction)DB_get_byteswapped,METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008725 {"get_size", (PyCFunction)DB_get_size, METH_VARARGS|METH_KEYWORDS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008726 {"get_type", (PyCFunction)DB_get_type, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008727 {"join", (PyCFunction)DB_join, METH_VARARGS},
8728 {"key_range", (PyCFunction)DB_key_range, METH_VARARGS|METH_KEYWORDS},
Jesus Cea4907d272008-08-31 14:00:51 +00008729 {"has_key", (PyCFunction)DB_has_key, METH_VARARGS|METH_KEYWORDS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008730 {"items", (PyCFunction)DB_items, METH_VARARGS},
8731 {"keys", (PyCFunction)DB_keys, METH_VARARGS},
8732 {"open", (PyCFunction)DB_open, METH_VARARGS|METH_KEYWORDS},
8733 {"put", (PyCFunction)DB_put, METH_VARARGS|METH_KEYWORDS},
8734 {"remove", (PyCFunction)DB_remove, METH_VARARGS|METH_KEYWORDS},
8735 {"rename", (PyCFunction)DB_rename, METH_VARARGS},
8736 {"set_bt_minkey", (PyCFunction)DB_set_bt_minkey, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008737 {"get_bt_minkey", (PyCFunction)DB_get_bt_minkey, METH_NOARGS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008738 {"set_bt_compare", (PyCFunction)DB_set_bt_compare, METH_O},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008739 {"set_cachesize", (PyCFunction)DB_set_cachesize, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008740 {"get_cachesize", (PyCFunction)DB_get_cachesize, METH_NOARGS},
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07008741 {"set_dup_compare", (PyCFunction)DB_set_dup_compare, METH_O},
Jesus Cea6557aac2010-03-22 14:22:26 +00008742 {"set_encrypt", (PyCFunction)DB_set_encrypt, METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008743 {"get_encrypt_flags", (PyCFunction)DB_get_encrypt_flags, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008744 {"set_flags", (PyCFunction)DB_set_flags, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008745 {"get_flags", (PyCFunction)DB_get_flags, METH_NOARGS},
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07008746 {"get_transactional", (PyCFunction)DB_get_transactional, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008747 {"set_h_ffactor", (PyCFunction)DB_set_h_ffactor, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008748 {"get_h_ffactor", (PyCFunction)DB_get_h_ffactor, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008749 {"set_h_nelem", (PyCFunction)DB_set_h_nelem, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008750 {"get_h_nelem", (PyCFunction)DB_get_h_nelem, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008751 {"set_lorder", (PyCFunction)DB_set_lorder, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008752 {"get_lorder", (PyCFunction)DB_get_lorder, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008753 {"set_pagesize", (PyCFunction)DB_set_pagesize, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008754 {"get_pagesize", (PyCFunction)DB_get_pagesize, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008755 {"set_re_delim", (PyCFunction)DB_set_re_delim, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008756 {"get_re_delim", (PyCFunction)DB_get_re_delim, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008757 {"set_re_len", (PyCFunction)DB_set_re_len, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008758 {"get_re_len", (PyCFunction)DB_get_re_len, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008759 {"set_re_pad", (PyCFunction)DB_set_re_pad, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008760 {"get_re_pad", (PyCFunction)DB_get_re_pad, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008761 {"set_re_source", (PyCFunction)DB_set_re_source, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008762 {"get_re_source", (PyCFunction)DB_get_re_source, METH_NOARGS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008763 {"set_q_extentsize",(PyCFunction)DB_set_q_extentsize, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008764 {"get_q_extentsize",(PyCFunction)DB_get_q_extentsize, METH_NOARGS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008765 {"set_private", (PyCFunction)DB_set_private, METH_O},
8766 {"get_private", (PyCFunction)DB_get_private, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008767#if (DBVER >= 46)
8768 {"set_priority", (PyCFunction)DB_set_priority, METH_VARARGS},
8769 {"get_priority", (PyCFunction)DB_get_priority, METH_NOARGS},
8770#endif
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07008771 {"get_dbname", (PyCFunction)DB_get_dbname, METH_NOARGS},
8772 {"get_open_flags", (PyCFunction)DB_get_open_flags, METH_NOARGS},
Gregory P. Smith8b7e9172004-12-13 09:51:23 +00008773 {"stat", (PyCFunction)DB_stat, METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008774 {"stat_print", (PyCFunction)DB_stat_print,
8775 METH_VARARGS|METH_KEYWORDS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008776 {"sync", (PyCFunction)DB_sync, METH_VARARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008777 {"truncate", (PyCFunction)DB_truncate, METH_VARARGS|METH_KEYWORDS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008778 {"type", (PyCFunction)DB_get_type, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008779 {"upgrade", (PyCFunction)DB_upgrade, METH_VARARGS},
8780 {"values", (PyCFunction)DB_values, METH_VARARGS},
8781 {"verify", (PyCFunction)DB_verify, METH_VARARGS|METH_KEYWORDS},
8782 {"set_get_returns_none",(PyCFunction)DB_set_get_returns_none, METH_VARARGS},
8783 {NULL, NULL} /* sentinel */
8784};
8785
8786
Jesus Cea6557aac2010-03-22 14:22:26 +00008787/* We need this to support __contains__() */
8788static PySequenceMethods DB_sequence = {
8789 0, /* sq_length, mapping wins here */
8790 0, /* sq_concat */
8791 0, /* sq_repeat */
8792 0, /* sq_item */
8793 0, /* sq_slice */
8794 0, /* sq_ass_item */
8795 0, /* sq_ass_slice */
8796 (objobjproc)DB_contains, /* sq_contains */
8797 0, /* sq_inplace_concat */
8798 0, /* sq_inplace_repeat */
8799};
8800
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008801static PyMappingMethods DB_mapping = {
Martin v. Löwis70ee3cc2006-06-12 04:26:31 +00008802 DB_length, /*mp_length*/
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008803 (binaryfunc)DB_subscript, /*mp_subscript*/
8804 (objobjargproc)DB_ass_sub, /*mp_ass_subscript*/
8805};
8806
8807
8808static PyMethodDef DBCursor_methods[] = {
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008809 {"close", (PyCFunction)DBC_close, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008810 {"count", (PyCFunction)DBC_count, METH_VARARGS},
8811 {"current", (PyCFunction)DBC_current, METH_VARARGS|METH_KEYWORDS},
8812 {"delete", (PyCFunction)DBC_delete, METH_VARARGS},
8813 {"dup", (PyCFunction)DBC_dup, METH_VARARGS},
8814 {"first", (PyCFunction)DBC_first, METH_VARARGS|METH_KEYWORDS},
8815 {"get", (PyCFunction)DBC_get, METH_VARARGS|METH_KEYWORDS},
Gregory P. Smith19699a92004-06-28 04:06:49 +00008816 {"pget", (PyCFunction)DBC_pget, METH_VARARGS|METH_KEYWORDS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008817 {"get_recno", (PyCFunction)DBC_get_recno, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008818 {"last", (PyCFunction)DBC_last, METH_VARARGS|METH_KEYWORDS},
8819 {"next", (PyCFunction)DBC_next, METH_VARARGS|METH_KEYWORDS},
8820 {"prev", (PyCFunction)DBC_prev, METH_VARARGS|METH_KEYWORDS},
8821 {"put", (PyCFunction)DBC_put, METH_VARARGS|METH_KEYWORDS},
8822 {"set", (PyCFunction)DBC_set, METH_VARARGS|METH_KEYWORDS},
8823 {"set_range", (PyCFunction)DBC_set_range, METH_VARARGS|METH_KEYWORDS},
8824 {"get_both", (PyCFunction)DBC_get_both, METH_VARARGS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008825 {"get_current_size",(PyCFunction)DBC_get_current_size, METH_NOARGS},
Gregory P. Smith455d46f2003-07-09 04:45:59 +00008826 {"set_both", (PyCFunction)DBC_set_both, METH_VARARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008827 {"set_recno", (PyCFunction)DBC_set_recno, METH_VARARGS|METH_KEYWORDS},
8828 {"consume", (PyCFunction)DBC_consume, METH_VARARGS|METH_KEYWORDS},
8829 {"next_dup", (PyCFunction)DBC_next_dup, METH_VARARGS|METH_KEYWORDS},
8830 {"next_nodup", (PyCFunction)DBC_next_nodup, METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008831#if (DBVER >= 46)
8832 {"prev_dup", (PyCFunction)DBC_prev_dup,
8833 METH_VARARGS|METH_KEYWORDS},
8834#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008835 {"prev_nodup", (PyCFunction)DBC_prev_nodup, METH_VARARGS|METH_KEYWORDS},
8836 {"join_item", (PyCFunction)DBC_join_item, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008837#if (DBVER >= 46)
8838 {"set_priority", (PyCFunction)DBC_set_priority,
8839 METH_VARARGS|METH_KEYWORDS},
8840 {"get_priority", (PyCFunction)DBC_get_priority, METH_NOARGS},
8841#endif
8842 {NULL, NULL} /* sentinel */
8843};
8844
8845
8846static PyMethodDef DBLogCursor_methods[] = {
8847 {"close", (PyCFunction)DBLogCursor_close, METH_NOARGS},
8848 {"current", (PyCFunction)DBLogCursor_current, METH_NOARGS},
8849 {"first", (PyCFunction)DBLogCursor_first, METH_NOARGS},
8850 {"last", (PyCFunction)DBLogCursor_last, METH_NOARGS},
8851 {"next", (PyCFunction)DBLogCursor_next, METH_NOARGS},
8852 {"prev", (PyCFunction)DBLogCursor_prev, METH_NOARGS},
8853 {"set", (PyCFunction)DBLogCursor_set, METH_VARARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008854 {NULL, NULL} /* sentinel */
8855};
8856
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07008857#if (DBVER >= 52)
8858static PyMethodDef DBSite_methods[] = {
8859 {"get_config", (PyCFunction)DBSite_get_config,
8860 METH_VARARGS | METH_KEYWORDS},
8861 {"set_config", (PyCFunction)DBSite_set_config,
8862 METH_VARARGS | METH_KEYWORDS},
8863 {"remove", (PyCFunction)DBSite_remove, METH_NOARGS},
8864 {"get_eid", (PyCFunction)DBSite_get_eid, METH_NOARGS},
8865 {"get_address", (PyCFunction)DBSite_get_address, METH_NOARGS},
8866 {"close", (PyCFunction)DBSite_close, METH_NOARGS},
8867 {NULL, NULL} /* sentinel */
8868};
8869#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008870
8871static PyMethodDef DBEnv_methods[] = {
8872 {"close", (PyCFunction)DBEnv_close, METH_VARARGS},
8873 {"open", (PyCFunction)DBEnv_open, METH_VARARGS},
8874 {"remove", (PyCFunction)DBEnv_remove, METH_VARARGS},
Barry Warsaw9a0d7792002-12-30 20:53:52 +00008875 {"dbremove", (PyCFunction)DBEnv_dbremove, METH_VARARGS|METH_KEYWORDS},
8876 {"dbrename", (PyCFunction)DBEnv_dbrename, METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008877#if (DBVER >= 46)
8878 {"set_thread_count", (PyCFunction)DBEnv_set_thread_count, METH_VARARGS},
8879 {"get_thread_count", (PyCFunction)DBEnv_get_thread_count, METH_NOARGS},
8880#endif
Barry Warsaw9a0d7792002-12-30 20:53:52 +00008881 {"set_encrypt", (PyCFunction)DBEnv_set_encrypt, METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008882 {"get_encrypt_flags", (PyCFunction)DBEnv_get_encrypt_flags, METH_NOARGS},
8883 {"get_timeout", (PyCFunction)DBEnv_get_timeout,
8884 METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008885 {"set_timeout", (PyCFunction)DBEnv_set_timeout, METH_VARARGS|METH_KEYWORDS},
8886 {"set_shm_key", (PyCFunction)DBEnv_set_shm_key, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008887 {"get_shm_key", (PyCFunction)DBEnv_get_shm_key, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008888#if (DBVER >= 46)
8889 {"set_cache_max", (PyCFunction)DBEnv_set_cache_max, METH_VARARGS},
8890 {"get_cache_max", (PyCFunction)DBEnv_get_cache_max, METH_NOARGS},
8891#endif
8892 {"set_cachesize", (PyCFunction)DBEnv_set_cachesize, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008893 {"get_cachesize", (PyCFunction)DBEnv_get_cachesize, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008894 {"memp_trickle", (PyCFunction)DBEnv_memp_trickle, METH_VARARGS},
8895 {"memp_sync", (PyCFunction)DBEnv_memp_sync, METH_VARARGS},
8896 {"memp_stat", (PyCFunction)DBEnv_memp_stat,
8897 METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008898 {"memp_stat_print", (PyCFunction)DBEnv_memp_stat_print,
8899 METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008900#if (DBVER >= 44)
8901 {"mutex_set_max", (PyCFunction)DBEnv_mutex_set_max, METH_VARARGS},
8902 {"mutex_get_max", (PyCFunction)DBEnv_mutex_get_max, METH_NOARGS},
8903 {"mutex_set_align", (PyCFunction)DBEnv_mutex_set_align, METH_VARARGS},
8904 {"mutex_get_align", (PyCFunction)DBEnv_mutex_get_align, METH_NOARGS},
8905 {"mutex_set_increment", (PyCFunction)DBEnv_mutex_set_increment,
8906 METH_VARARGS},
8907 {"mutex_get_increment", (PyCFunction)DBEnv_mutex_get_increment,
8908 METH_NOARGS},
8909 {"mutex_set_tas_spins", (PyCFunction)DBEnv_mutex_set_tas_spins,
8910 METH_VARARGS},
8911 {"mutex_get_tas_spins", (PyCFunction)DBEnv_mutex_get_tas_spins,
8912 METH_NOARGS},
8913 {"mutex_stat", (PyCFunction)DBEnv_mutex_stat, METH_VARARGS},
8914#if (DBVER >= 44)
8915 {"mutex_stat_print", (PyCFunction)DBEnv_mutex_stat_print,
8916 METH_VARARGS|METH_KEYWORDS},
8917#endif
8918#endif
8919 {"set_data_dir", (PyCFunction)DBEnv_set_data_dir, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008920 {"get_data_dirs", (PyCFunction)DBEnv_get_data_dirs, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008921 {"get_flags", (PyCFunction)DBEnv_get_flags, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008922 {"set_flags", (PyCFunction)DBEnv_set_flags, METH_VARARGS},
8923#if (DBVER >= 47)
8924 {"log_set_config", (PyCFunction)DBEnv_log_set_config, METH_VARARGS},
8925 {"log_get_config", (PyCFunction)DBEnv_log_get_config, METH_VARARGS},
8926#endif
8927 {"set_lg_bsize", (PyCFunction)DBEnv_set_lg_bsize, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008928 {"get_lg_bsize", (PyCFunction)DBEnv_get_lg_bsize, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008929 {"set_lg_dir", (PyCFunction)DBEnv_set_lg_dir, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008930 {"get_lg_dir", (PyCFunction)DBEnv_get_lg_dir, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008931 {"set_lg_max", (PyCFunction)DBEnv_set_lg_max, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008932 {"get_lg_max", (PyCFunction)DBEnv_get_lg_max, METH_NOARGS},
Gregory P. Smithe9477062005-06-04 06:46:59 +00008933 {"set_lg_regionmax",(PyCFunction)DBEnv_set_lg_regionmax, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008934 {"get_lg_regionmax",(PyCFunction)DBEnv_get_lg_regionmax, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008935#if (DBVER >= 44)
8936 {"set_lg_filemode", (PyCFunction)DBEnv_set_lg_filemode, METH_VARARGS},
8937 {"get_lg_filemode", (PyCFunction)DBEnv_get_lg_filemode, METH_NOARGS},
8938#endif
8939#if (DBVER >= 47)
8940 {"set_lk_partitions", (PyCFunction)DBEnv_set_lk_partitions, METH_VARARGS},
8941 {"get_lk_partitions", (PyCFunction)DBEnv_get_lk_partitions, METH_NOARGS},
8942#endif
8943 {"set_lk_detect", (PyCFunction)DBEnv_set_lk_detect, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008944 {"get_lk_detect", (PyCFunction)DBEnv_get_lk_detect, METH_NOARGS},
Gregory P. Smith8b96a352007-01-05 01:59:42 +00008945#if (DBVER < 45)
Jesus Cea6557aac2010-03-22 14:22:26 +00008946 {"set_lk_max", (PyCFunction)DBEnv_set_lk_max, METH_VARARGS},
Gregory P. Smith8b96a352007-01-05 01:59:42 +00008947#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008948 {"set_lk_max_locks", (PyCFunction)DBEnv_set_lk_max_locks, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008949 {"get_lk_max_locks", (PyCFunction)DBEnv_get_lk_max_locks, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008950 {"set_lk_max_lockers", (PyCFunction)DBEnv_set_lk_max_lockers, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008951 {"get_lk_max_lockers", (PyCFunction)DBEnv_get_lk_max_lockers, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008952 {"set_lk_max_objects", (PyCFunction)DBEnv_set_lk_max_objects, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008953 {"get_lk_max_objects", (PyCFunction)DBEnv_get_lk_max_objects, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008954 {"stat_print", (PyCFunction)DBEnv_stat_print,
8955 METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008956 {"set_mp_mmapsize", (PyCFunction)DBEnv_set_mp_mmapsize, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008957 {"get_mp_mmapsize", (PyCFunction)DBEnv_get_mp_mmapsize, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008958 {"set_tmp_dir", (PyCFunction)DBEnv_set_tmp_dir, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008959 {"get_tmp_dir", (PyCFunction)DBEnv_get_tmp_dir, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008960 {"txn_begin", (PyCFunction)DBEnv_txn_begin, METH_VARARGS|METH_KEYWORDS},
8961 {"txn_checkpoint", (PyCFunction)DBEnv_txn_checkpoint, METH_VARARGS},
8962 {"txn_stat", (PyCFunction)DBEnv_txn_stat, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008963 {"txn_stat_print", (PyCFunction)DBEnv_txn_stat_print,
8964 METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008965 {"get_tx_max", (PyCFunction)DBEnv_get_tx_max, METH_NOARGS},
8966 {"get_tx_timestamp", (PyCFunction)DBEnv_get_tx_timestamp, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008967 {"set_tx_max", (PyCFunction)DBEnv_set_tx_max, METH_VARARGS},
Gregory P. Smith8a474042006-01-27 07:05:40 +00008968 {"set_tx_timestamp", (PyCFunction)DBEnv_set_tx_timestamp, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008969 {"lock_detect", (PyCFunction)DBEnv_lock_detect, METH_VARARGS},
8970 {"lock_get", (PyCFunction)DBEnv_lock_get, METH_VARARGS},
8971 {"lock_id", (PyCFunction)DBEnv_lock_id, METH_NOARGS},
8972 {"lock_id_free", (PyCFunction)DBEnv_lock_id_free, METH_VARARGS},
8973 {"lock_put", (PyCFunction)DBEnv_lock_put, METH_VARARGS},
8974 {"lock_stat", (PyCFunction)DBEnv_lock_stat, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008975 {"lock_stat_print", (PyCFunction)DBEnv_lock_stat_print,
8976 METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008977 {"log_cursor", (PyCFunction)DBEnv_log_cursor, METH_NOARGS},
8978 {"log_file", (PyCFunction)DBEnv_log_file, METH_VARARGS},
Gregory P. Smithdb8a8072006-06-05 01:56:15 +00008979#if (DBVER >= 44)
Jesus Cea6557aac2010-03-22 14:22:26 +00008980 {"log_printf", (PyCFunction)DBEnv_log_printf,
8981 METH_VARARGS|METH_KEYWORDS},
8982#endif
8983 {"log_archive", (PyCFunction)DBEnv_log_archive, METH_VARARGS},
8984 {"log_flush", (PyCFunction)DBEnv_log_flush, METH_NOARGS},
8985 {"log_stat", (PyCFunction)DBEnv_log_stat, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008986 {"log_stat_print", (PyCFunction)DBEnv_log_stat_print,
8987 METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008988#if (DBVER >= 44)
8989 {"fileid_reset", (PyCFunction)DBEnv_fileid_reset, METH_VARARGS|METH_KEYWORDS},
8990 {"lsn_reset", (PyCFunction)DBEnv_lsn_reset, METH_VARARGS|METH_KEYWORDS},
Gregory P. Smithdb8a8072006-06-05 01:56:15 +00008991#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008992 {"set_get_returns_none",(PyCFunction)DBEnv_set_get_returns_none, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008993 {"txn_recover", (PyCFunction)DBEnv_txn_recover, METH_NOARGS},
Matthias Klose54cc5392010-03-15 12:46:18 +00008994#if (DBVER < 48)
Jesus Ceaca3939c2008-05-22 15:27:38 +00008995 {"set_rpc_server", (PyCFunction)DBEnv_set_rpc_server,
Stefan Krah77112732011-09-15 22:56:00 +02008996 METH_VARARGS|METH_KEYWORDS},
Matthias Klose54cc5392010-03-15 12:46:18 +00008997#endif
Jesus Cea6557aac2010-03-22 14:22:26 +00008998 {"set_mp_max_openfd", (PyCFunction)DBEnv_set_mp_max_openfd, METH_VARARGS},
8999 {"get_mp_max_openfd", (PyCFunction)DBEnv_get_mp_max_openfd, METH_NOARGS},
9000 {"set_mp_max_write", (PyCFunction)DBEnv_set_mp_max_write, METH_VARARGS},
9001 {"get_mp_max_write", (PyCFunction)DBEnv_get_mp_max_write, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00009002 {"set_verbose", (PyCFunction)DBEnv_set_verbose, METH_VARARGS},
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009003 {"get_verbose", (PyCFunction)DBEnv_get_verbose, METH_VARARGS},
9004 {"set_private", (PyCFunction)DBEnv_set_private, METH_O},
9005 {"get_private", (PyCFunction)DBEnv_get_private, METH_NOARGS},
9006 {"get_open_flags", (PyCFunction)DBEnv_get_open_flags, METH_NOARGS},
9007#if (DBVER >= 47)
9008 {"set_intermediate_dir_mode", (PyCFunction)DBEnv_set_intermediate_dir_mode,
9009 METH_VARARGS},
9010 {"get_intermediate_dir_mode", (PyCFunction)DBEnv_get_intermediate_dir_mode,
9011 METH_NOARGS},
Jesus Ceaef9764f2008-05-13 18:45:46 +00009012#endif
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009013#if (DBVER < 47)
9014 {"set_intermediate_dir", (PyCFunction)DBEnv_set_intermediate_dir,
9015 METH_VARARGS},
9016#endif
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009017 {"rep_start", (PyCFunction)DBEnv_rep_start,
9018 METH_VARARGS|METH_KEYWORDS},
9019 {"rep_set_transport", (PyCFunction)DBEnv_rep_set_transport, METH_VARARGS},
9020 {"rep_process_message", (PyCFunction)DBEnv_rep_process_message,
9021 METH_VARARGS},
9022#if (DBVER >= 46)
9023 {"rep_elect", (PyCFunction)DBEnv_rep_elect, METH_VARARGS},
9024#endif
9025#if (DBVER >= 44)
9026 {"rep_set_config", (PyCFunction)DBEnv_rep_set_config, METH_VARARGS},
9027 {"rep_get_config", (PyCFunction)DBEnv_rep_get_config, METH_VARARGS},
9028 {"rep_sync", (PyCFunction)DBEnv_rep_sync, METH_NOARGS},
Jesus Ceaef9764f2008-05-13 18:45:46 +00009029#endif
9030#if (DBVER >= 45)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009031 {"rep_set_limit", (PyCFunction)DBEnv_rep_set_limit, METH_VARARGS},
9032 {"rep_get_limit", (PyCFunction)DBEnv_rep_get_limit, METH_NOARGS},
9033#endif
9034#if (DBVER >= 47)
9035 {"rep_set_request", (PyCFunction)DBEnv_rep_set_request, METH_VARARGS},
9036 {"rep_get_request", (PyCFunction)DBEnv_rep_get_request, METH_NOARGS},
9037#endif
9038#if (DBVER >= 45)
9039 {"set_event_notify", (PyCFunction)DBEnv_set_event_notify, METH_O},
Jesus Ceaef9764f2008-05-13 18:45:46 +00009040#endif
9041#if (DBVER >= 45)
9042 {"rep_set_nsites", (PyCFunction)DBEnv_rep_set_nsites, METH_VARARGS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009043 {"rep_get_nsites", (PyCFunction)DBEnv_rep_get_nsites, METH_NOARGS},
Jesus Ceaef9764f2008-05-13 18:45:46 +00009044 {"rep_set_priority", (PyCFunction)DBEnv_rep_set_priority, METH_VARARGS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009045 {"rep_get_priority", (PyCFunction)DBEnv_rep_get_priority, METH_NOARGS},
Jesus Ceaef9764f2008-05-13 18:45:46 +00009046 {"rep_set_timeout", (PyCFunction)DBEnv_rep_set_timeout, METH_VARARGS},
9047 {"rep_get_timeout", (PyCFunction)DBEnv_rep_get_timeout, METH_VARARGS},
9048#endif
Jesus Cea6557aac2010-03-22 14:22:26 +00009049#if (DBVER >= 47)
9050 {"rep_set_clockskew", (PyCFunction)DBEnv_rep_set_clockskew, METH_VARARGS},
9051 {"rep_get_clockskew", (PyCFunction)DBEnv_rep_get_clockskew, METH_VARARGS},
9052#endif
9053 {"rep_stat", (PyCFunction)DBEnv_rep_stat,
9054 METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00009055 {"rep_stat_print", (PyCFunction)DBEnv_rep_stat_print,
9056 METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00009057
Jesus Ceaef9764f2008-05-13 18:45:46 +00009058#if (DBVER >= 45)
9059 {"repmgr_start", (PyCFunction)DBEnv_repmgr_start,
9060 METH_VARARGS|METH_KEYWORDS},
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009061#if (DBVER < 52)
Jesus Ceaef9764f2008-05-13 18:45:46 +00009062 {"repmgr_set_local_site", (PyCFunction)DBEnv_repmgr_set_local_site,
9063 METH_VARARGS|METH_KEYWORDS},
9064 {"repmgr_add_remote_site", (PyCFunction)DBEnv_repmgr_add_remote_site,
9065 METH_VARARGS|METH_KEYWORDS},
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009066#endif
Jesus Ceaef9764f2008-05-13 18:45:46 +00009067 {"repmgr_set_ack_policy", (PyCFunction)DBEnv_repmgr_set_ack_policy,
9068 METH_VARARGS},
9069 {"repmgr_get_ack_policy", (PyCFunction)DBEnv_repmgr_get_ack_policy,
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009070 METH_NOARGS},
Jesus Ceaef9764f2008-05-13 18:45:46 +00009071 {"repmgr_site_list", (PyCFunction)DBEnv_repmgr_site_list,
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009072 METH_NOARGS},
Jesus Ceaef9764f2008-05-13 18:45:46 +00009073#endif
9074#if (DBVER >= 46)
9075 {"repmgr_stat", (PyCFunction)DBEnv_repmgr_stat,
9076 METH_VARARGS|METH_KEYWORDS},
9077 {"repmgr_stat_print", (PyCFunction)DBEnv_repmgr_stat_print,
9078 METH_VARARGS|METH_KEYWORDS},
9079#endif
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009080#if (DBVER >= 52)
9081 {"repmgr_site", (PyCFunction)DBEnv_repmgr_site,
9082 METH_VARARGS | METH_KEYWORDS},
9083 {"repmgr_site_by_eid", (PyCFunction)DBEnv_repmgr_site_by_eid,
9084 METH_VARARGS | METH_KEYWORDS},
9085#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009086 {NULL, NULL} /* sentinel */
9087};
9088
9089
9090static PyMethodDef DBTxn_methods[] = {
9091 {"commit", (PyCFunction)DBTxn_commit, METH_VARARGS},
9092 {"prepare", (PyCFunction)DBTxn_prepare, METH_VARARGS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009093 {"discard", (PyCFunction)DBTxn_discard, METH_NOARGS},
9094 {"abort", (PyCFunction)DBTxn_abort, METH_NOARGS},
9095 {"id", (PyCFunction)DBTxn_id, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00009096 {"set_timeout", (PyCFunction)DBTxn_set_timeout,
9097 METH_VARARGS|METH_KEYWORDS},
9098#if (DBVER >= 44)
9099 {"set_name", (PyCFunction)DBTxn_set_name, METH_VARARGS},
9100 {"get_name", (PyCFunction)DBTxn_get_name, METH_NOARGS},
9101#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009102 {NULL, NULL} /* sentinel */
9103};
9104
9105
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009106static PyMethodDef DBSequence_methods[] = {
9107 {"close", (PyCFunction)DBSequence_close, METH_VARARGS},
9108 {"get", (PyCFunction)DBSequence_get, METH_VARARGS|METH_KEYWORDS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009109 {"get_dbp", (PyCFunction)DBSequence_get_dbp, METH_NOARGS},
9110 {"get_key", (PyCFunction)DBSequence_get_key, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00009111 {"initial_value", (PyCFunction)DBSequence_initial_value, METH_VARARGS},
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009112 {"open", (PyCFunction)DBSequence_open, METH_VARARGS|METH_KEYWORDS},
9113 {"remove", (PyCFunction)DBSequence_remove, METH_VARARGS|METH_KEYWORDS},
9114 {"set_cachesize", (PyCFunction)DBSequence_set_cachesize, METH_VARARGS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009115 {"get_cachesize", (PyCFunction)DBSequence_get_cachesize, METH_NOARGS},
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009116 {"set_flags", (PyCFunction)DBSequence_set_flags, METH_VARARGS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009117 {"get_flags", (PyCFunction)DBSequence_get_flags, METH_NOARGS},
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009118 {"set_range", (PyCFunction)DBSequence_set_range, METH_VARARGS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009119 {"get_range", (PyCFunction)DBSequence_get_range, METH_NOARGS},
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009120 {"stat", (PyCFunction)DBSequence_stat, METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00009121 {"stat_print", (PyCFunction)DBSequence_stat_print,
9122 METH_VARARGS|METH_KEYWORDS},
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009123 {NULL, NULL} /* sentinel */
9124};
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009125
9126
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009127static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009128DBEnv_db_home_get(DBEnvObject* self)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009129{
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009130 const char *home = NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009131
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009132 CHECK_ENV_NOT_CLOSED(self);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009133
Jesus Cea6557aac2010-03-22 14:22:26 +00009134 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009135 self->db_env->get_home(self->db_env, &home);
Jesus Cea6557aac2010-03-22 14:22:26 +00009136 MYDB_END_ALLOW_THREADS;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009137
9138 if (home == NULL) {
9139 RETURN_NONE();
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009140 }
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009141 return PyBytes_FromString(home);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009142}
9143
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009144static PyGetSetDef DBEnv_getsets[] = {
9145 {"db_home", (getter)DBEnv_db_home_get, NULL,},
9146 {NULL}
9147};
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009148
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009149
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009150statichere PyTypeObject DB_Type = {
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009151#if (PY_VERSION_HEX < 0x03000000)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009152 PyObject_HEAD_INIT(NULL)
9153 0, /*ob_size*/
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009154#else
9155 PyVarObject_HEAD_INIT(NULL, 0)
9156#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009157 "DB", /*tp_name*/
9158 sizeof(DBObject), /*tp_basicsize*/
9159 0, /*tp_itemsize*/
9160 /* methods */
9161 (destructor)DB_dealloc, /*tp_dealloc*/
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009162 0, /*tp_print*/
9163 0, /*tp_getattr*/
9164 0, /*tp_setattr*/
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009165 0, /*tp_compare*/
9166 0, /*tp_repr*/
9167 0, /*tp_as_number*/
Jesus Cea6557aac2010-03-22 14:22:26 +00009168 &DB_sequence,/*tp_as_sequence*/
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009169 &DB_mapping,/*tp_as_mapping*/
9170 0, /*tp_hash*/
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009171 0, /* tp_call */
9172 0, /* tp_str */
9173 0, /* tp_getattro */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009174 0, /* tp_setattro */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009175 0, /* tp_as_buffer */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009176#if (PY_VERSION_HEX < 0x03000000)
Gregory P. Smith31c50652004-06-28 01:20:40 +00009177 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009178#else
9179 Py_TPFLAGS_DEFAULT, /* tp_flags */
9180#endif
9181 0, /* tp_doc */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009182 0, /* tp_traverse */
9183 0, /* tp_clear */
9184 0, /* tp_richcompare */
Gregory P. Smith31c50652004-06-28 01:20:40 +00009185 offsetof(DBObject, in_weakreflist), /* tp_weaklistoffset */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009186 0, /*tp_iter*/
9187 0, /*tp_iternext*/
9188 DB_methods, /*tp_methods*/
9189 0, /*tp_members*/
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009190};
9191
9192
9193statichere PyTypeObject DBCursor_Type = {
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009194#if (PY_VERSION_HEX < 0x03000000)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009195 PyObject_HEAD_INIT(NULL)
9196 0, /*ob_size*/
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009197#else
9198 PyVarObject_HEAD_INIT(NULL, 0)
9199#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009200 "DBCursor", /*tp_name*/
9201 sizeof(DBCursorObject), /*tp_basicsize*/
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009202 0, /*tp_itemsize*/
9203 /* methods */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009204 (destructor)DBCursor_dealloc,/*tp_dealloc*/
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009205 0, /*tp_print*/
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009206 0, /*tp_getattr*/
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009207 0, /*tp_setattr*/
9208 0, /*tp_compare*/
9209 0, /*tp_repr*/
9210 0, /*tp_as_number*/
9211 0, /*tp_as_sequence*/
9212 0, /*tp_as_mapping*/
9213 0, /*tp_hash*/
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009214 0, /*tp_call*/
9215 0, /*tp_str*/
9216 0, /*tp_getattro*/
9217 0, /*tp_setattro*/
9218 0, /*tp_as_buffer*/
9219#if (PY_VERSION_HEX < 0x03000000)
Gregory P. Smith31c50652004-06-28 01:20:40 +00009220 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009221#else
9222 Py_TPFLAGS_DEFAULT, /* tp_flags */
9223#endif
9224 0, /* tp_doc */
9225 0, /* tp_traverse */
9226 0, /* tp_clear */
9227 0, /* tp_richcompare */
9228 offsetof(DBCursorObject, in_weakreflist), /* tp_weaklistoffset */
9229 0, /*tp_iter*/
9230 0, /*tp_iternext*/
9231 DBCursor_methods, /*tp_methods*/
9232 0, /*tp_members*/
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009233};
9234
9235
Jesus Cea6557aac2010-03-22 14:22:26 +00009236statichere PyTypeObject DBLogCursor_Type = {
9237#if (PY_VERSION_HEX < 0x03000000)
9238 PyObject_HEAD_INIT(NULL)
9239 0, /*ob_size*/
9240#else
9241 PyVarObject_HEAD_INIT(NULL, 0)
9242#endif
9243 "DBLogCursor", /*tp_name*/
9244 sizeof(DBLogCursorObject), /*tp_basicsize*/
9245 0, /*tp_itemsize*/
9246 /* methods */
9247 (destructor)DBLogCursor_dealloc,/*tp_dealloc*/
9248 0, /*tp_print*/
9249 0, /*tp_getattr*/
9250 0, /*tp_setattr*/
9251 0, /*tp_compare*/
9252 0, /*tp_repr*/
9253 0, /*tp_as_number*/
9254 0, /*tp_as_sequence*/
9255 0, /*tp_as_mapping*/
9256 0, /*tp_hash*/
9257 0, /*tp_call*/
9258 0, /*tp_str*/
9259 0, /*tp_getattro*/
9260 0, /*tp_setattro*/
9261 0, /*tp_as_buffer*/
9262#if (PY_VERSION_HEX < 0x03000000)
9263 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
9264#else
9265 Py_TPFLAGS_DEFAULT, /* tp_flags */
9266#endif
9267 0, /* tp_doc */
9268 0, /* tp_traverse */
9269 0, /* tp_clear */
9270 0, /* tp_richcompare */
9271 offsetof(DBLogCursorObject, in_weakreflist), /* tp_weaklistoffset */
9272 0, /*tp_iter*/
9273 0, /*tp_iternext*/
9274 DBLogCursor_methods, /*tp_methods*/
9275 0, /*tp_members*/
9276};
9277
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009278#if (DBVER >= 52)
9279statichere PyTypeObject DBSite_Type = {
9280#if (PY_VERSION_HEX < 0x03000000)
9281 PyObject_HEAD_INIT(NULL)
9282 0, /*ob_size*/
9283#else
9284 PyVarObject_HEAD_INIT(NULL, 0)
9285#endif
9286 "DBSite", /*tp_name*/
9287 sizeof(DBSiteObject), /*tp_basicsize*/
9288 0, /*tp_itemsize*/
9289 /* methods */
9290 (destructor)DBSite_dealloc,/*tp_dealloc*/
9291 0, /*tp_print*/
9292 0, /*tp_getattr*/
9293 0, /*tp_setattr*/
9294 0, /*tp_compare*/
9295 0, /*tp_repr*/
9296 0, /*tp_as_number*/
9297 0, /*tp_as_sequence*/
9298 0, /*tp_as_mapping*/
9299 0, /*tp_hash*/
9300 0, /*tp_call*/
9301 0, /*tp_str*/
9302 0, /*tp_getattro*/
9303 0, /*tp_setattro*/
9304 0, /*tp_as_buffer*/
9305#if (PY_VERSION_HEX < 0x03000000)
9306 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
9307#else
9308 Py_TPFLAGS_DEFAULT, /* tp_flags */
9309#endif
9310 0, /* tp_doc */
9311 0, /* tp_traverse */
9312 0, /* tp_clear */
9313 0, /* tp_richcompare */
9314 offsetof(DBSiteObject, in_weakreflist), /* tp_weaklistoffset */
9315 0, /*tp_iter*/
9316 0, /*tp_iternext*/
9317 DBSite_methods, /*tp_methods*/
9318 0, /*tp_members*/
9319};
9320#endif
Jesus Cea6557aac2010-03-22 14:22:26 +00009321
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009322statichere PyTypeObject DBEnv_Type = {
9323#if (PY_VERSION_HEX < 0x03000000)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009324 PyObject_HEAD_INIT(NULL)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009325 0, /*ob_size*/
9326#else
9327 PyVarObject_HEAD_INIT(NULL, 0)
9328#endif
9329 "DBEnv", /*tp_name*/
9330 sizeof(DBEnvObject), /*tp_basicsize*/
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009331 0, /*tp_itemsize*/
9332 /* methods */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009333 (destructor)DBEnv_dealloc, /*tp_dealloc*/
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009334 0, /*tp_print*/
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009335 0, /*tp_getattr*/
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009336 0, /*tp_setattr*/
9337 0, /*tp_compare*/
9338 0, /*tp_repr*/
9339 0, /*tp_as_number*/
9340 0, /*tp_as_sequence*/
9341 0, /*tp_as_mapping*/
9342 0, /*tp_hash*/
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009343 0, /* tp_call */
9344 0, /* tp_str */
9345 0, /* tp_getattro */
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009346 0, /* tp_setattro */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009347 0, /* tp_as_buffer */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009348#if (PY_VERSION_HEX < 0x03000000)
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009349 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009350#else
9351 Py_TPFLAGS_DEFAULT, /* tp_flags */
9352#endif
9353 0, /* tp_doc */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009354 0, /* tp_traverse */
9355 0, /* tp_clear */
9356 0, /* tp_richcompare */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009357 offsetof(DBEnvObject, in_weakreflist), /* tp_weaklistoffset */
9358 0, /* tp_iter */
9359 0, /* tp_iternext */
9360 DBEnv_methods, /* tp_methods */
9361 0, /* tp_members */
9362 DBEnv_getsets, /* tp_getsets */
9363};
9364
9365statichere PyTypeObject DBTxn_Type = {
9366#if (PY_VERSION_HEX < 0x03000000)
9367 PyObject_HEAD_INIT(NULL)
9368 0, /*ob_size*/
9369#else
9370 PyVarObject_HEAD_INIT(NULL, 0)
9371#endif
9372 "DBTxn", /*tp_name*/
9373 sizeof(DBTxnObject), /*tp_basicsize*/
9374 0, /*tp_itemsize*/
9375 /* methods */
9376 (destructor)DBTxn_dealloc, /*tp_dealloc*/
9377 0, /*tp_print*/
9378 0, /*tp_getattr*/
9379 0, /*tp_setattr*/
9380 0, /*tp_compare*/
9381 0, /*tp_repr*/
9382 0, /*tp_as_number*/
9383 0, /*tp_as_sequence*/
9384 0, /*tp_as_mapping*/
9385 0, /*tp_hash*/
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009386 0, /* tp_call */
9387 0, /* tp_str */
9388 0, /* tp_getattro */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009389 0, /* tp_setattro */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009390 0, /* tp_as_buffer */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009391#if (PY_VERSION_HEX < 0x03000000)
9392 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
9393#else
9394 Py_TPFLAGS_DEFAULT, /* tp_flags */
9395#endif
9396 0, /* tp_doc */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009397 0, /* tp_traverse */
9398 0, /* tp_clear */
9399 0, /* tp_richcompare */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009400 offsetof(DBTxnObject, in_weakreflist), /* tp_weaklistoffset */
9401 0, /*tp_iter*/
9402 0, /*tp_iternext*/
9403 DBTxn_methods, /*tp_methods*/
9404 0, /*tp_members*/
9405};
9406
9407
9408statichere PyTypeObject DBLock_Type = {
9409#if (PY_VERSION_HEX < 0x03000000)
9410 PyObject_HEAD_INIT(NULL)
9411 0, /*ob_size*/
9412#else
9413 PyVarObject_HEAD_INIT(NULL, 0)
9414#endif
9415 "DBLock", /*tp_name*/
9416 sizeof(DBLockObject), /*tp_basicsize*/
9417 0, /*tp_itemsize*/
9418 /* methods */
9419 (destructor)DBLock_dealloc, /*tp_dealloc*/
9420 0, /*tp_print*/
9421 0, /*tp_getattr*/
9422 0, /*tp_setattr*/
9423 0, /*tp_compare*/
9424 0, /*tp_repr*/
9425 0, /*tp_as_number*/
9426 0, /*tp_as_sequence*/
9427 0, /*tp_as_mapping*/
9428 0, /*tp_hash*/
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009429 0, /* tp_call */
9430 0, /* tp_str */
9431 0, /* tp_getattro */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009432 0, /* tp_setattro */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009433 0, /* tp_as_buffer */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009434#if (PY_VERSION_HEX < 0x03000000)
9435 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
9436#else
9437 Py_TPFLAGS_DEFAULT, /* tp_flags */
9438#endif
9439 0, /* tp_doc */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009440 0, /* tp_traverse */
9441 0, /* tp_clear */
9442 0, /* tp_richcompare */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009443 offsetof(DBLockObject, in_weakreflist), /* tp_weaklistoffset */
9444};
9445
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009446statichere PyTypeObject DBSequence_Type = {
9447#if (PY_VERSION_HEX < 0x03000000)
9448 PyObject_HEAD_INIT(NULL)
9449 0, /*ob_size*/
9450#else
9451 PyVarObject_HEAD_INIT(NULL, 0)
9452#endif
9453 "DBSequence", /*tp_name*/
9454 sizeof(DBSequenceObject), /*tp_basicsize*/
9455 0, /*tp_itemsize*/
9456 /* methods */
9457 (destructor)DBSequence_dealloc, /*tp_dealloc*/
9458 0, /*tp_print*/
9459 0, /*tp_getattr*/
9460 0, /*tp_setattr*/
9461 0, /*tp_compare*/
9462 0, /*tp_repr*/
9463 0, /*tp_as_number*/
9464 0, /*tp_as_sequence*/
9465 0, /*tp_as_mapping*/
9466 0, /*tp_hash*/
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009467 0, /* tp_call */
9468 0, /* tp_str */
9469 0, /* tp_getattro */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009470 0, /* tp_setattro */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009471 0, /* tp_as_buffer */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009472#if (PY_VERSION_HEX < 0x03000000)
9473 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
9474#else
9475 Py_TPFLAGS_DEFAULT, /* tp_flags */
9476#endif
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009477 0, /* tp_doc */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009478 0, /* tp_traverse */
9479 0, /* tp_clear */
9480 0, /* tp_richcompare */
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009481 offsetof(DBSequenceObject, in_weakreflist), /* tp_weaklistoffset */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009482 0, /*tp_iter*/
9483 0, /*tp_iternext*/
9484 DBSequence_methods, /*tp_methods*/
9485 0, /*tp_members*/
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009486};
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009487
9488/* --------------------------------------------------------------------- */
9489/* Module-level functions */
9490
9491static PyObject*
9492DB_construct(PyObject* self, PyObject* args, PyObject* kwargs)
9493{
9494 PyObject* dbenvobj = NULL;
9495 int flags = 0;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00009496 static char* kwnames[] = { "dbEnv", "flags", NULL};
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009497
Barry Warsaw9a0d7792002-12-30 20:53:52 +00009498 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Oi:DB", kwnames,
9499 &dbenvobj, &flags))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009500 return NULL;
9501 if (dbenvobj == Py_None)
9502 dbenvobj = NULL;
9503 else if (dbenvobj && !DBEnvObject_Check(dbenvobj)) {
9504 makeTypeError("DBEnv", dbenvobj);
9505 return NULL;
9506 }
9507
9508 return (PyObject* )newDBObject((DBEnvObject*)dbenvobj, flags);
9509}
9510
9511
9512static PyObject*
9513DBEnv_construct(PyObject* self, PyObject* args)
9514{
9515 int flags = 0;
9516 if (!PyArg_ParseTuple(args, "|i:DbEnv", &flags)) return NULL;
9517 return (PyObject* )newDBEnvObject(flags);
9518}
9519
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009520static PyObject*
9521DBSequence_construct(PyObject* self, PyObject* args, PyObject* kwargs)
9522{
Neal Norwitzb4fcf8d2006-06-11 05:44:18 +00009523 PyObject* dbobj;
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009524 int flags = 0;
9525 static char* kwnames[] = { "db", "flags", NULL};
9526
9527 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|i:DBSequence", kwnames, &dbobj, &flags))
9528 return NULL;
Neal Norwitzb4fcf8d2006-06-11 05:44:18 +00009529 if (!DBObject_Check(dbobj)) {
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009530 makeTypeError("DB", dbobj);
9531 return NULL;
9532 }
9533 return (PyObject* )newDBSequenceObject((DBObject*)dbobj, flags);
9534}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009535
9536static char bsddb_version_doc[] =
9537"Returns a tuple of major, minor, and patch release numbers of the\n\
9538underlying DB library.";
9539
9540static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009541bsddb_version(PyObject* self)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009542{
9543 int major, minor, patch;
9544
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009545 /* This should be instantaneous, no need to release the GIL */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009546 db_version(&major, &minor, &patch);
9547 return Py_BuildValue("(iii)", major, minor, patch);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009548}
9549
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009550#if (DBVER >= 50)
9551static PyObject*
9552bsddb_version_full(PyObject* self)
9553{
9554 char *version_string;
9555 int family, release, major, minor, patch;
9556
9557 /* This should be instantaneous, no need to release the GIL */
9558 version_string = db_full_version(&family, &release, &major, &minor, &patch);
9559 return Py_BuildValue("(siiiii)",
9560 version_string, family, release, major, minor, patch);
9561}
9562#endif
9563
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009564
9565/* List of functions defined in the module */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009566static PyMethodDef bsddb_methods[] = {
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009567 {"DB", (PyCFunction)DB_construct, METH_VARARGS | METH_KEYWORDS },
9568 {"DBEnv", (PyCFunction)DBEnv_construct, METH_VARARGS},
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009569 {"DBSequence", (PyCFunction)DBSequence_construct, METH_VARARGS | METH_KEYWORDS },
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009570 {"version", (PyCFunction)bsddb_version, METH_NOARGS, bsddb_version_doc},
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009571#if (DBVER >= 50)
9572 {"full_version", (PyCFunction)bsddb_version_full, METH_NOARGS},
9573#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009574 {NULL, NULL} /* sentinel */
9575};
9576
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009577
Gregory P. Smith39250532007-10-09 06:02:21 +00009578/* API structure */
9579static BSDDB_api bsddb_api;
9580
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009581
9582/* --------------------------------------------------------------------- */
9583/* Module initialization */
9584
9585
9586/* Convenience routine to export an integer value.
9587 * Errors are silently ignored, for better or for worse...
9588 */
9589#define ADD_INT(dict, NAME) _addIntToDict(dict, #NAME, NAME)
9590
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009591/*
9592** We can rename the module at import time, so the string allocated
9593** must be big enough, and any use of the name must use this particular
9594** string.
9595*/
Gregory P. Smith41631e82003-09-21 00:08:14 +00009596#define MODULE_NAME_MAX_LEN 11
9597static char _bsddbModuleName[MODULE_NAME_MAX_LEN+1] = "_bsddb";
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009598
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009599#if (PY_VERSION_HEX >= 0x03000000)
9600static struct PyModuleDef bsddbmodule = {
9601 PyModuleDef_HEAD_INIT,
9602 _bsddbModuleName, /* Name of module */
9603 NULL, /* module documentation, may be NULL */
9604 -1, /* size of per-interpreter state of the module,
9605 or -1 if the module keeps state in global variables. */
9606 bsddb_methods,
9607 NULL, /* Reload */
9608 NULL, /* Traverse */
9609 NULL, /* Clear */
9610 NULL /* Free */
9611};
9612#endif
9613
9614
9615#if (PY_VERSION_HEX < 0x03000000)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009616DL_EXPORT(void) init_bsddb(void)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009617#else
9618PyMODINIT_FUNC PyInit__bsddb(void) /* Note the two underscores */
9619#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009620{
9621 PyObject* m;
9622 PyObject* d;
Gregory P. Smith39250532007-10-09 06:02:21 +00009623 PyObject* py_api;
Jesus Cea6557aac2010-03-22 14:22:26 +00009624 PyObject* pybsddb_version_s;
9625 PyObject* db_version_s;
9626 PyObject* cvsid_s;
9627
9628#if (PY_VERSION_HEX < 0x03000000)
9629 pybsddb_version_s = PyString_FromString(PY_BSDDB_VERSION);
9630 db_version_s = PyString_FromString(DB_VERSION_STRING);
9631 cvsid_s = PyString_FromString(rcs_id);
9632#else
9633 /* This data should be ascii, so UTF-8 conversion is fine */
9634 pybsddb_version_s = PyUnicode_FromString(PY_BSDDB_VERSION);
9635 db_version_s = PyUnicode_FromString(DB_VERSION_STRING);
9636 cvsid_s = PyUnicode_FromString(rcs_id);
9637#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009638
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009639 /* Initialize object types */
9640 if ((PyType_Ready(&DB_Type) < 0)
9641 || (PyType_Ready(&DBCursor_Type) < 0)
Jesus Cea6557aac2010-03-22 14:22:26 +00009642 || (PyType_Ready(&DBLogCursor_Type) < 0)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009643 || (PyType_Ready(&DBEnv_Type) < 0)
9644 || (PyType_Ready(&DBTxn_Type) < 0)
9645 || (PyType_Ready(&DBLock_Type) < 0)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009646 || (PyType_Ready(&DBSequence_Type) < 0)
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009647#if (DBVER >= 52)
9648 || (PyType_Ready(&DBSite_Type) < 0)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009649#endif
9650 ) {
9651#if (PY_VERSION_HEX < 0x03000000)
9652 return;
9653#else
9654 return NULL;
9655#endif
9656 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009657
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009658 /* Create the module and add the functions */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009659#if (PY_VERSION_HEX < 0x03000000)
Gregory P. Smith41631e82003-09-21 00:08:14 +00009660 m = Py_InitModule(_bsddbModuleName, bsddb_methods);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009661#else
9662 m=PyModule_Create(&bsddbmodule);
9663#endif
9664 if (m == NULL) {
9665#if (PY_VERSION_HEX < 0x03000000)
9666 return;
9667#else
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009668 return NULL;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009669#endif
9670 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009671
9672 /* Add some symbolic constants to the module */
9673 d = PyModule_GetDict(m);
9674 PyDict_SetItemString(d, "__version__", pybsddb_version_s);
9675 PyDict_SetItemString(d, "cvsid", cvsid_s);
9676 PyDict_SetItemString(d, "DB_VERSION_STRING", db_version_s);
9677 Py_DECREF(pybsddb_version_s);
9678 pybsddb_version_s = NULL;
9679 Py_DECREF(cvsid_s);
9680 cvsid_s = NULL;
9681 Py_DECREF(db_version_s);
9682 db_version_s = NULL;
9683
9684 ADD_INT(d, DB_VERSION_MAJOR);
9685 ADD_INT(d, DB_VERSION_MINOR);
9686 ADD_INT(d, DB_VERSION_PATCH);
9687
9688 ADD_INT(d, DB_MAX_PAGES);
9689 ADD_INT(d, DB_MAX_RECORDS);
9690
Matthias Klose54cc5392010-03-15 12:46:18 +00009691#if (DBVER < 48)
Gregory P. Smith41631e82003-09-21 00:08:14 +00009692 ADD_INT(d, DB_RPCCLIENT);
Matthias Klose54cc5392010-03-15 12:46:18 +00009693#endif
9694
9695#if (DBVER < 48)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009696 ADD_INT(d, DB_XA_CREATE);
Matthias Klose54cc5392010-03-15 12:46:18 +00009697#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009698
9699 ADD_INT(d, DB_CREATE);
9700 ADD_INT(d, DB_NOMMAP);
9701 ADD_INT(d, DB_THREAD);
Jesus Ceaef9764f2008-05-13 18:45:46 +00009702#if (DBVER >= 45)
9703 ADD_INT(d, DB_MULTIVERSION);
9704#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009705
9706 ADD_INT(d, DB_FORCE);
9707 ADD_INT(d, DB_INIT_CDB);
9708 ADD_INT(d, DB_INIT_LOCK);
9709 ADD_INT(d, DB_INIT_LOG);
9710 ADD_INT(d, DB_INIT_MPOOL);
9711 ADD_INT(d, DB_INIT_TXN);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009712 ADD_INT(d, DB_JOINENV);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009713
Matthias Klose54cc5392010-03-15 12:46:18 +00009714#if (DBVER >= 48)
9715 ADD_INT(d, DB_GID_SIZE);
9716#else
Jesus Ceaef9764f2008-05-13 18:45:46 +00009717 ADD_INT(d, DB_XIDDATASIZE);
Matthias Klose54cc5392010-03-15 12:46:18 +00009718 /* Allow new code to work in old BDB releases */
9719 _addIntToDict(d, "DB_GID_SIZE", DB_XIDDATASIZE);
9720#endif
Jesus Ceaef9764f2008-05-13 18:45:46 +00009721
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009722 ADD_INT(d, DB_RECOVER);
9723 ADD_INT(d, DB_RECOVER_FATAL);
9724 ADD_INT(d, DB_TXN_NOSYNC);
9725 ADD_INT(d, DB_USE_ENVIRON);
9726 ADD_INT(d, DB_USE_ENVIRON_ROOT);
9727
9728 ADD_INT(d, DB_LOCKDOWN);
9729 ADD_INT(d, DB_PRIVATE);
9730 ADD_INT(d, DB_SYSTEM_MEM);
9731
9732 ADD_INT(d, DB_TXN_SYNC);
9733 ADD_INT(d, DB_TXN_NOWAIT);
9734
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009735#if (DBVER >= 51)
9736 ADD_INT(d, DB_TXN_BULK);
9737#endif
9738
9739#if (DBVER >= 48)
9740 ADD_INT(d, DB_CURSOR_BULK);
9741#endif
9742
Jesus Cea6557aac2010-03-22 14:22:26 +00009743#if (DBVER >= 46)
9744 ADD_INT(d, DB_TXN_WAIT);
9745#endif
9746
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009747 ADD_INT(d, DB_EXCL);
9748 ADD_INT(d, DB_FCNTL_LOCKING);
9749 ADD_INT(d, DB_ODDFILESIZE);
9750 ADD_INT(d, DB_RDWRMASTER);
9751 ADD_INT(d, DB_RDONLY);
9752 ADD_INT(d, DB_TRUNCATE);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009753 ADD_INT(d, DB_EXTENT);
9754 ADD_INT(d, DB_CDB_ALLDB);
9755 ADD_INT(d, DB_VERIFY);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009756 ADD_INT(d, DB_UPGRADE);
9757
Jesus Cea6557aac2010-03-22 14:22:26 +00009758 ADD_INT(d, DB_PRINTABLE);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009759 ADD_INT(d, DB_AGGRESSIVE);
9760 ADD_INT(d, DB_NOORDERCHK);
9761 ADD_INT(d, DB_ORDERCHKONLY);
9762 ADD_INT(d, DB_PR_PAGE);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009763
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009764 ADD_INT(d, DB_PR_RECOVERYTEST);
9765 ADD_INT(d, DB_SALVAGE);
9766
9767 ADD_INT(d, DB_LOCK_NORUN);
9768 ADD_INT(d, DB_LOCK_DEFAULT);
9769 ADD_INT(d, DB_LOCK_OLDEST);
9770 ADD_INT(d, DB_LOCK_RANDOM);
9771 ADD_INT(d, DB_LOCK_YOUNGEST);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009772 ADD_INT(d, DB_LOCK_MAXLOCKS);
9773 ADD_INT(d, DB_LOCK_MINLOCKS);
9774 ADD_INT(d, DB_LOCK_MINWRITE);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009775
Jesus Ceaef9764f2008-05-13 18:45:46 +00009776 ADD_INT(d, DB_LOCK_EXPIRE);
Jesus Ceaef9764f2008-05-13 18:45:46 +00009777 ADD_INT(d, DB_LOCK_MAXWRITE);
Jesus Ceaef9764f2008-05-13 18:45:46 +00009778
Barry Warsaw9a0d7792002-12-30 20:53:52 +00009779 _addIntToDict(d, "DB_LOCK_CONFLICT", 0);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009780
9781 ADD_INT(d, DB_LOCK_DUMP);
9782 ADD_INT(d, DB_LOCK_GET);
9783 ADD_INT(d, DB_LOCK_INHERIT);
9784 ADD_INT(d, DB_LOCK_PUT);
9785 ADD_INT(d, DB_LOCK_PUT_ALL);
9786 ADD_INT(d, DB_LOCK_PUT_OBJ);
9787
9788 ADD_INT(d, DB_LOCK_NG);
9789 ADD_INT(d, DB_LOCK_READ);
9790 ADD_INT(d, DB_LOCK_WRITE);
9791 ADD_INT(d, DB_LOCK_NOWAIT);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009792 ADD_INT(d, DB_LOCK_WAIT);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009793 ADD_INT(d, DB_LOCK_IWRITE);
9794 ADD_INT(d, DB_LOCK_IREAD);
9795 ADD_INT(d, DB_LOCK_IWR);
Gregory P. Smith29602d22006-01-24 09:46:48 +00009796#if (DBVER < 44)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009797 ADD_INT(d, DB_LOCK_DIRTY);
Gregory P. Smith29602d22006-01-24 09:46:48 +00009798#else
9799 ADD_INT(d, DB_LOCK_READ_UNCOMMITTED); /* renamed in 4.4 */
9800#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009801 ADD_INT(d, DB_LOCK_WWRITE);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009802
9803 ADD_INT(d, DB_LOCK_RECORD);
9804 ADD_INT(d, DB_LOCK_UPGRADE);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009805 ADD_INT(d, DB_LOCK_SWITCH);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009806 ADD_INT(d, DB_LOCK_UPGRADE_WRITE);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009807
9808 ADD_INT(d, DB_LOCK_NOWAIT);
9809 ADD_INT(d, DB_LOCK_RECORD);
9810 ADD_INT(d, DB_LOCK_UPGRADE);
9811
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009812 ADD_INT(d, DB_LSTAT_ABORTED);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009813 ADD_INT(d, DB_LSTAT_FREE);
9814 ADD_INT(d, DB_LSTAT_HELD);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009815
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009816 ADD_INT(d, DB_LSTAT_PENDING);
9817 ADD_INT(d, DB_LSTAT_WAITING);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009818
9819 ADD_INT(d, DB_ARCH_ABS);
9820 ADD_INT(d, DB_ARCH_DATA);
9821 ADD_INT(d, DB_ARCH_LOG);
Gregory P. Smith3dd20022006-06-05 00:31:01 +00009822 ADD_INT(d, DB_ARCH_REMOVE);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009823
9824 ADD_INT(d, DB_BTREE);
9825 ADD_INT(d, DB_HASH);
9826 ADD_INT(d, DB_RECNO);
9827 ADD_INT(d, DB_QUEUE);
9828 ADD_INT(d, DB_UNKNOWN);
9829
9830 ADD_INT(d, DB_DUP);
9831 ADD_INT(d, DB_DUPSORT);
9832 ADD_INT(d, DB_RECNUM);
9833 ADD_INT(d, DB_RENUMBER);
9834 ADD_INT(d, DB_REVSPLITOFF);
9835 ADD_INT(d, DB_SNAPSHOT);
9836
Jesus Cea6557aac2010-03-22 14:22:26 +00009837 ADD_INT(d, DB_INORDER);
Jesus Cea6557aac2010-03-22 14:22:26 +00009838
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009839 ADD_INT(d, DB_JOIN_NOSORT);
9840
9841 ADD_INT(d, DB_AFTER);
9842 ADD_INT(d, DB_APPEND);
9843 ADD_INT(d, DB_BEFORE);
Gregory P. Smith8b96a352007-01-05 01:59:42 +00009844#if (DBVER < 45)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009845 ADD_INT(d, DB_CACHED_COUNTS);
Gregory P. Smith8b96a352007-01-05 01:59:42 +00009846#endif
Jesus Ceaca3939c2008-05-22 15:27:38 +00009847
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009848 ADD_INT(d, DB_CONSUME);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009849 ADD_INT(d, DB_CONSUME_WAIT);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009850 ADD_INT(d, DB_CURRENT);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009851 ADD_INT(d, DB_FAST_STAT);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009852 ADD_INT(d, DB_FIRST);
9853 ADD_INT(d, DB_FLUSH);
9854 ADD_INT(d, DB_GET_BOTH);
Jesus Cea6557aac2010-03-22 14:22:26 +00009855 ADD_INT(d, DB_GET_BOTH_RANGE);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009856 ADD_INT(d, DB_GET_RECNO);
9857 ADD_INT(d, DB_JOIN_ITEM);
9858 ADD_INT(d, DB_KEYFIRST);
9859 ADD_INT(d, DB_KEYLAST);
9860 ADD_INT(d, DB_LAST);
9861 ADD_INT(d, DB_NEXT);
9862 ADD_INT(d, DB_NEXT_DUP);
9863 ADD_INT(d, DB_NEXT_NODUP);
9864 ADD_INT(d, DB_NODUPDATA);
9865 ADD_INT(d, DB_NOOVERWRITE);
9866 ADD_INT(d, DB_NOSYNC);
9867 ADD_INT(d, DB_POSITION);
9868 ADD_INT(d, DB_PREV);
9869 ADD_INT(d, DB_PREV_NODUP);
Jesus Cea6557aac2010-03-22 14:22:26 +00009870#if (DBVER >= 46)
9871 ADD_INT(d, DB_PREV_DUP);
9872#endif
Gregory P. Smith8b96a352007-01-05 01:59:42 +00009873#if (DBVER < 45)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009874 ADD_INT(d, DB_RECORDCOUNT);
Gregory P. Smith8b96a352007-01-05 01:59:42 +00009875#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009876 ADD_INT(d, DB_SET);
9877 ADD_INT(d, DB_SET_RANGE);
9878 ADD_INT(d, DB_SET_RECNO);
9879 ADD_INT(d, DB_WRITECURSOR);
9880
9881 ADD_INT(d, DB_OPFLAGS_MASK);
9882 ADD_INT(d, DB_RMW);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009883 ADD_INT(d, DB_DIRTY_READ);
9884 ADD_INT(d, DB_MULTIPLE);
9885 ADD_INT(d, DB_MULTIPLE_KEY);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009886
Gregory P. Smith29602d22006-01-24 09:46:48 +00009887#if (DBVER >= 44)
Jesus Cea6557aac2010-03-22 14:22:26 +00009888 ADD_INT(d, DB_IMMUTABLE_KEY);
Gregory P. Smith29602d22006-01-24 09:46:48 +00009889 ADD_INT(d, DB_READ_UNCOMMITTED); /* replaces DB_DIRTY_READ in 4.4 */
9890 ADD_INT(d, DB_READ_COMMITTED);
9891#endif
9892
Jesus Cea6557aac2010-03-22 14:22:26 +00009893#if (DBVER >= 44)
9894 ADD_INT(d, DB_FREELIST_ONLY);
9895 ADD_INT(d, DB_FREE_SPACE);
9896#endif
9897
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009898 ADD_INT(d, DB_DONOTINDEX);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009899
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009900 ADD_INT(d, DB_KEYEMPTY);
9901 ADD_INT(d, DB_KEYEXIST);
9902 ADD_INT(d, DB_LOCK_DEADLOCK);
9903 ADD_INT(d, DB_LOCK_NOTGRANTED);
9904 ADD_INT(d, DB_NOSERVER);
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009905#if (DBVER < 52)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009906 ADD_INT(d, DB_NOSERVER_HOME);
9907 ADD_INT(d, DB_NOSERVER_ID);
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009908#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009909 ADD_INT(d, DB_NOTFOUND);
9910 ADD_INT(d, DB_OLD_VERSION);
9911 ADD_INT(d, DB_RUNRECOVERY);
9912 ADD_INT(d, DB_VERIFY_BAD);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009913 ADD_INT(d, DB_PAGE_NOTFOUND);
9914 ADD_INT(d, DB_SECONDARY_BAD);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009915 ADD_INT(d, DB_STAT_CLEAR);
9916 ADD_INT(d, DB_REGION_INIT);
9917 ADD_INT(d, DB_NOLOCKING);
9918 ADD_INT(d, DB_YIELDCPU);
9919 ADD_INT(d, DB_PANIC_ENVIRONMENT);
9920 ADD_INT(d, DB_NOPANIC);
Jesus Ceaef9764f2008-05-13 18:45:46 +00009921 ADD_INT(d, DB_OVERWRITE);
Jesus Cea6557aac2010-03-22 14:22:26 +00009922
Jesus Cea6557aac2010-03-22 14:22:26 +00009923 ADD_INT(d, DB_STAT_SUBSYSTEM);
9924 ADD_INT(d, DB_STAT_MEMP_HASH);
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009925 ADD_INT(d, DB_STAT_LOCK_CONF);
9926 ADD_INT(d, DB_STAT_LOCK_LOCKERS);
9927 ADD_INT(d, DB_STAT_LOCK_OBJECTS);
9928 ADD_INT(d, DB_STAT_LOCK_PARAMS);
Jesus Ceaef9764f2008-05-13 18:45:46 +00009929
Jesus Cea6557aac2010-03-22 14:22:26 +00009930#if (DBVER >= 48)
9931 ADD_INT(d, DB_OVERWRITE_DUP);
9932#endif
9933
9934#if (DBVER >= 47)
9935 ADD_INT(d, DB_FOREIGN_ABORT);
9936 ADD_INT(d, DB_FOREIGN_CASCADE);
9937 ADD_INT(d, DB_FOREIGN_NULLIFY);
9938#endif
9939
9940#if (DBVER >= 44)
Gregory P. Smithaae141a2007-11-01 21:08:14 +00009941 ADD_INT(d, DB_REGISTER);
9942#endif
9943
Jesus Cea6557aac2010-03-22 14:22:26 +00009944 ADD_INT(d, DB_EID_INVALID);
9945 ADD_INT(d, DB_EID_BROADCAST);
9946
Gregory P. Smith41631e82003-09-21 00:08:14 +00009947 ADD_INT(d, DB_TIME_NOTGRANTED);
9948 ADD_INT(d, DB_TXN_NOT_DURABLE);
9949 ADD_INT(d, DB_TXN_WRITE_NOSYNC);
Gregory P. Smith41631e82003-09-21 00:08:14 +00009950 ADD_INT(d, DB_DIRECT_DB);
9951 ADD_INT(d, DB_INIT_REP);
9952 ADD_INT(d, DB_ENCRYPT);
9953 ADD_INT(d, DB_CHKSUM);
Gregory P. Smith41631e82003-09-21 00:08:14 +00009954
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009955#if (DBVER < 47)
Jesus Ceaca3939c2008-05-22 15:27:38 +00009956 ADD_INT(d, DB_LOG_AUTOREMOVE);
9957 ADD_INT(d, DB_DIRECT_LOG);
9958#endif
9959
9960#if (DBVER >= 47)
9961 ADD_INT(d, DB_LOG_DIRECT);
9962 ADD_INT(d, DB_LOG_DSYNC);
9963 ADD_INT(d, DB_LOG_IN_MEMORY);
9964 ADD_INT(d, DB_LOG_AUTO_REMOVE);
9965 ADD_INT(d, DB_LOG_ZERO);
9966#endif
9967
Jesus Ceaef9764f2008-05-13 18:45:46 +00009968#if (DBVER >= 44)
9969 ADD_INT(d, DB_DSYNC_DB);
9970#endif
9971
9972#if (DBVER >= 45)
9973 ADD_INT(d, DB_TXN_SNAPSHOT);
9974#endif
9975
Jesus Ceaef9764f2008-05-13 18:45:46 +00009976 ADD_INT(d, DB_VERB_DEADLOCK);
9977#if (DBVER >= 46)
9978 ADD_INT(d, DB_VERB_FILEOPS);
9979 ADD_INT(d, DB_VERB_FILEOPS_ALL);
9980#endif
9981 ADD_INT(d, DB_VERB_RECOVERY);
9982#if (DBVER >= 44)
9983 ADD_INT(d, DB_VERB_REGISTER);
9984#endif
9985 ADD_INT(d, DB_VERB_REPLICATION);
9986 ADD_INT(d, DB_VERB_WAITSFOR);
Jesus Ceaef9764f2008-05-13 18:45:46 +00009987
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009988#if (DBVER >= 50)
9989 ADD_INT(d, DB_VERB_REP_SYSTEM);
9990#endif
9991
9992#if (DBVER >= 47)
9993 ADD_INT(d, DB_VERB_REP_ELECT);
9994 ADD_INT(d, DB_VERB_REP_LEASE);
9995 ADD_INT(d, DB_VERB_REP_MISC);
9996 ADD_INT(d, DB_VERB_REP_MSGS);
9997 ADD_INT(d, DB_VERB_REP_SYNC);
9998 ADD_INT(d, DB_VERB_REPMGR_CONNFAIL);
9999 ADD_INT(d, DB_VERB_REPMGR_MISC);
10000#endif
10001
Jesus Ceaef9764f2008-05-13 18:45:46 +000010002#if (DBVER >= 45)
10003 ADD_INT(d, DB_EVENT_PANIC);
10004 ADD_INT(d, DB_EVENT_REP_CLIENT);
10005#if (DBVER >= 46)
10006 ADD_INT(d, DB_EVENT_REP_ELECTED);
10007#endif
10008 ADD_INT(d, DB_EVENT_REP_MASTER);
10009 ADD_INT(d, DB_EVENT_REP_NEWMASTER);
10010#if (DBVER >= 46)
10011 ADD_INT(d, DB_EVENT_REP_PERM_FAILED);
10012#endif
10013 ADD_INT(d, DB_EVENT_REP_STARTUPDONE);
10014 ADD_INT(d, DB_EVENT_WRITE_FAILED);
10015#endif
10016
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010017#if (DBVER >= 50)
10018 ADD_INT(d, DB_REPMGR_CONF_ELECTIONS);
10019 ADD_INT(d, DB_EVENT_REP_MASTER_FAILURE);
10020 ADD_INT(d, DB_EVENT_REP_DUPMASTER);
10021 ADD_INT(d, DB_EVENT_REP_ELECTION_FAILED);
10022#endif
10023#if (DBVER >= 48)
10024 ADD_INT(d, DB_EVENT_REG_ALIVE);
10025 ADD_INT(d, DB_EVENT_REG_PANIC);
10026#endif
10027
10028#if (DBVER >=52)
10029 ADD_INT(d, DB_EVENT_REP_SITE_ADDED);
10030 ADD_INT(d, DB_EVENT_REP_SITE_REMOVED);
10031 ADD_INT(d, DB_EVENT_REP_LOCAL_SITE_REMOVED);
10032 ADD_INT(d, DB_EVENT_REP_CONNECT_BROKEN);
10033 ADD_INT(d, DB_EVENT_REP_CONNECT_ESTD);
10034 ADD_INT(d, DB_EVENT_REP_CONNECT_TRY_FAILED);
10035 ADD_INT(d, DB_EVENT_REP_INIT_DONE);
10036
10037 ADD_INT(d, DB_MEM_LOCK);
10038 ADD_INT(d, DB_MEM_LOCKOBJECT);
10039 ADD_INT(d, DB_MEM_LOCKER);
10040 ADD_INT(d, DB_MEM_LOGID);
10041 ADD_INT(d, DB_MEM_TRANSACTION);
10042 ADD_INT(d, DB_MEM_THREAD);
10043
10044 ADD_INT(d, DB_BOOTSTRAP_HELPER);
10045 ADD_INT(d, DB_GROUP_CREATOR);
10046 ADD_INT(d, DB_LEGACY);
10047 ADD_INT(d, DB_LOCAL_SITE);
10048 ADD_INT(d, DB_REPMGR_PEER);
10049#endif
10050
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010051 ADD_INT(d, DB_REP_DUPMASTER);
10052 ADD_INT(d, DB_REP_HOLDELECTION);
10053#if (DBVER >= 44)
10054 ADD_INT(d, DB_REP_IGNORE);
10055 ADD_INT(d, DB_REP_JOIN_FAILURE);
10056#endif
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010057 ADD_INT(d, DB_REP_ISPERM);
10058 ADD_INT(d, DB_REP_NOTPERM);
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010059 ADD_INT(d, DB_REP_NEWSITE);
10060
Jesus Ceaef9764f2008-05-13 18:45:46 +000010061 ADD_INT(d, DB_REP_MASTER);
10062 ADD_INT(d, DB_REP_CLIENT);
Jesus Cea6557aac2010-03-22 14:22:26 +000010063
10064 ADD_INT(d, DB_REP_PERMANENT);
10065
10066#if (DBVER >= 44)
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010067#if (DBVER >= 50)
10068 ADD_INT(d, DB_REP_CONF_AUTOINIT);
10069#else
Jesus Cea6557aac2010-03-22 14:22:26 +000010070 ADD_INT(d, DB_REP_CONF_NOAUTOINIT);
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010071#endif /* 5.0 */
10072#endif /* 4.4 */
10073#if (DBVER >= 44)
Jesus Cea6557aac2010-03-22 14:22:26 +000010074 ADD_INT(d, DB_REP_CONF_DELAYCLIENT);
10075 ADD_INT(d, DB_REP_CONF_BULK);
10076 ADD_INT(d, DB_REP_CONF_NOWAIT);
10077 ADD_INT(d, DB_REP_ANYWHERE);
10078 ADD_INT(d, DB_REP_REREQUEST);
10079#endif
10080
Jesus Cea6557aac2010-03-22 14:22:26 +000010081 ADD_INT(d, DB_REP_NOBUFFER);
Jesus Cea6557aac2010-03-22 14:22:26 +000010082
10083#if (DBVER >= 46)
10084 ADD_INT(d, DB_REP_LEASE_EXPIRED);
10085 ADD_INT(d, DB_IGNORE_LEASE);
10086#endif
10087
10088#if (DBVER >= 47)
10089 ADD_INT(d, DB_REP_CONF_LEASE);
10090 ADD_INT(d, DB_REPMGR_CONF_2SITE_STRICT);
10091#endif
10092
Jesus Ceaef9764f2008-05-13 18:45:46 +000010093#if (DBVER >= 45)
10094 ADD_INT(d, DB_REP_ELECTION);
10095
10096 ADD_INT(d, DB_REP_ACK_TIMEOUT);
10097 ADD_INT(d, DB_REP_CONNECTION_RETRY);
10098 ADD_INT(d, DB_REP_ELECTION_TIMEOUT);
10099 ADD_INT(d, DB_REP_ELECTION_RETRY);
10100#endif
10101#if (DBVER >= 46)
10102 ADD_INT(d, DB_REP_CHECKPOINT_DELAY);
10103 ADD_INT(d, DB_REP_FULL_ELECTION_TIMEOUT);
Jesus Cea6557aac2010-03-22 14:22:26 +000010104 ADD_INT(d, DB_REP_LEASE_TIMEOUT);
10105#endif
10106#if (DBVER >= 47)
10107 ADD_INT(d, DB_REP_HEARTBEAT_MONITOR);
10108 ADD_INT(d, DB_REP_HEARTBEAT_SEND);
Jesus Ceaef9764f2008-05-13 18:45:46 +000010109#endif
Jesus Ceaef9764f2008-05-13 18:45:46 +000010110
10111#if (DBVER >= 45)
10112 ADD_INT(d, DB_REPMGR_PEER);
10113 ADD_INT(d, DB_REPMGR_ACKS_ALL);
10114 ADD_INT(d, DB_REPMGR_ACKS_ALL_PEERS);
10115 ADD_INT(d, DB_REPMGR_ACKS_NONE);
10116 ADD_INT(d, DB_REPMGR_ACKS_ONE);
10117 ADD_INT(d, DB_REPMGR_ACKS_ONE_PEER);
10118 ADD_INT(d, DB_REPMGR_ACKS_QUORUM);
10119 ADD_INT(d, DB_REPMGR_CONNECTED);
10120 ADD_INT(d, DB_REPMGR_DISCONNECTED);
Jesus Ceaef9764f2008-05-13 18:45:46 +000010121 ADD_INT(d, DB_STAT_ALL);
10122#endif
10123
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010124#if (DBVER >= 51)
10125 ADD_INT(d, DB_REPMGR_ACKS_ALL_AVAILABLE);
10126#endif
10127
10128#if (DBVER >= 48)
10129 ADD_INT(d, DB_REP_CONF_INMEM);
10130#endif
10131
10132 ADD_INT(d, DB_TIMEOUT);
10133
10134#if (DBVER >= 50)
10135 ADD_INT(d, DB_FORCESYNC);
10136#endif
10137
10138#if (DBVER >= 48)
10139 ADD_INT(d, DB_FAILCHK);
10140#endif
10141
10142#if (DBVER >= 51)
10143 ADD_INT(d, DB_HOTBACKUP_IN_PROGRESS);
10144#endif
10145
Gregory P. Smith8b7e9172004-12-13 09:51:23 +000010146 ADD_INT(d, DB_BUFFER_SMALL);
Gregory P. Smithf0547d02006-06-05 17:38:04 +000010147 ADD_INT(d, DB_SEQ_DEC);
10148 ADD_INT(d, DB_SEQ_INC);
10149 ADD_INT(d, DB_SEQ_WRAP);
Gregory P. Smith8b7e9172004-12-13 09:51:23 +000010150
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010151#if (DBVER < 47)
Jesus Ceaca3939c2008-05-22 15:27:38 +000010152 ADD_INT(d, DB_LOG_INMEMORY);
10153 ADD_INT(d, DB_DSYNC_LOG);
10154#endif
10155
Barry Warsaw9a0d7792002-12-30 20:53:52 +000010156 ADD_INT(d, DB_ENCRYPT_AES);
10157 ADD_INT(d, DB_AUTO_COMMIT);
Jesus Cea6557aac2010-03-22 14:22:26 +000010158 ADD_INT(d, DB_PRIORITY_VERY_LOW);
10159 ADD_INT(d, DB_PRIORITY_LOW);
10160 ADD_INT(d, DB_PRIORITY_DEFAULT);
10161 ADD_INT(d, DB_PRIORITY_HIGH);
10162 ADD_INT(d, DB_PRIORITY_VERY_HIGH);
10163
10164#if (DBVER >= 46)
10165 ADD_INT(d, DB_PRIORITY_UNCHANGED);
Barry Warsaw9a0d7792002-12-30 20:53:52 +000010166#endif
10167
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010168 ADD_INT(d, EINVAL);
10169 ADD_INT(d, EACCES);
10170 ADD_INT(d, ENOSPC);
10171 ADD_INT(d, ENOMEM);
10172 ADD_INT(d, EAGAIN);
10173 ADD_INT(d, EBUSY);
10174 ADD_INT(d, EEXIST);
10175 ADD_INT(d, ENOENT);
10176 ADD_INT(d, EPERM);
10177
Barry Warsaw1baa9822003-03-31 19:51:29 +000010178 ADD_INT(d, DB_SET_LOCK_TIMEOUT);
10179 ADD_INT(d, DB_SET_TXN_TIMEOUT);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010180
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010181#if (DBVER >= 48)
10182 ADD_INT(d, DB_SET_REG_TIMEOUT);
10183#endif
10184
Gregory P. Smith7f5b6f42006-04-08 07:10:51 +000010185 /* The exception name must be correct for pickled exception *
10186 * objects to unpickle properly. */
10187#ifdef PYBSDDB_STANDALONE /* different value needed for standalone pybsddb */
10188#define PYBSDDB_EXCEPTION_BASE "bsddb3.db."
10189#else
10190#define PYBSDDB_EXCEPTION_BASE "bsddb.db."
10191#endif
10192
10193 /* All the rest of the exceptions derive only from DBError */
10194#define MAKE_EX(name) name = PyErr_NewException(PYBSDDB_EXCEPTION_BASE #name, DBError, NULL); \
10195 PyDict_SetItemString(d, #name, name)
10196
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010197 /* The base exception class is DBError */
Gregory P. Smith7f5b6f42006-04-08 07:10:51 +000010198 DBError = NULL; /* used in MAKE_EX so that it derives from nothing */
10199 MAKE_EX(DBError);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010200
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010201#if (PY_VERSION_HEX < 0x03000000)
Gregory P. Smithe9477062005-06-04 06:46:59 +000010202 /* Some magic to make DBNotFoundError and DBKeyEmptyError derive
10203 * from both DBError and KeyError, since the API only supports
10204 * using one base class. */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010205 PyDict_SetItemString(d, "KeyError", PyExc_KeyError);
Gregory P. Smithe9477062005-06-04 06:46:59 +000010206 PyRun_String("class DBNotFoundError(DBError, KeyError): pass\n"
Antoine Pitrouc83ea132010-05-09 14:46:46 +000010207 "class DBKeyEmptyError(DBError, KeyError): pass",
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010208 Py_file_input, d, d);
10209 DBNotFoundError = PyDict_GetItemString(d, "DBNotFoundError");
Gregory P. Smithe9477062005-06-04 06:46:59 +000010210 DBKeyEmptyError = PyDict_GetItemString(d, "DBKeyEmptyError");
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010211 PyDict_DelItemString(d, "KeyError");
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010212#else
10213 /* Since Python 2.5, PyErr_NewException() accepts a tuple, to be able to
10214 ** derive from several classes. We use this new API only for Python 3.0,
10215 ** though.
10216 */
10217 {
10218 PyObject* bases;
10219
10220 bases = PyTuple_Pack(2, DBError, PyExc_KeyError);
10221
10222#define MAKE_EX2(name) name = PyErr_NewException(PYBSDDB_EXCEPTION_BASE #name, bases, NULL); \
10223 PyDict_SetItemString(d, #name, name)
10224 MAKE_EX2(DBNotFoundError);
10225 MAKE_EX2(DBKeyEmptyError);
10226
10227#undef MAKE_EX2
10228
10229 Py_XDECREF(bases);
10230 }
10231#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010232
Gregory P. Smithe2767172003-11-02 08:06:29 +000010233 MAKE_EX(DBCursorClosedError);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010234 MAKE_EX(DBKeyExistError);
10235 MAKE_EX(DBLockDeadlockError);
10236 MAKE_EX(DBLockNotGrantedError);
10237 MAKE_EX(DBOldVersionError);
10238 MAKE_EX(DBRunRecoveryError);
10239 MAKE_EX(DBVerifyBadError);
10240 MAKE_EX(DBNoServerError);
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010241#if (DBVER < 52)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010242 MAKE_EX(DBNoServerHomeError);
10243 MAKE_EX(DBNoServerIDError);
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010244#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010245 MAKE_EX(DBPageNotFoundError);
10246 MAKE_EX(DBSecondaryBadError);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010247
10248 MAKE_EX(DBInvalidArgError);
10249 MAKE_EX(DBAccessError);
10250 MAKE_EX(DBNoSpaceError);
10251 MAKE_EX(DBNoMemoryError);
10252 MAKE_EX(DBAgainError);
10253 MAKE_EX(DBBusyError);
10254 MAKE_EX(DBFileExistsError);
10255 MAKE_EX(DBNoSuchFileError);
10256 MAKE_EX(DBPermissionsError);
10257
Jesus Ceaef9764f2008-05-13 18:45:46 +000010258 MAKE_EX(DBRepHandleDeadError);
Jesus Cea6557aac2010-03-22 14:22:26 +000010259#if (DBVER >= 44)
10260 MAKE_EX(DBRepLockoutError);
10261#endif
Jesus Ceaef9764f2008-05-13 18:45:46 +000010262
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010263 MAKE_EX(DBRepUnavailError);
10264
Jesus Cea6557aac2010-03-22 14:22:26 +000010265#if (DBVER >= 46)
10266 MAKE_EX(DBRepLeaseExpiredError);
10267#endif
10268
10269#if (DBVER >= 47)
10270 MAKE_EX(DBForeignConflictError);
10271#endif
10272
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010273#undef MAKE_EX
10274
Jesus Cea6557aac2010-03-22 14:22:26 +000010275 /* Initialise the C API structure and add it to the module */
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010276 bsddb_api.api_version = PYBSDDB_API_VERSION;
Jesus Cea6557aac2010-03-22 14:22:26 +000010277 bsddb_api.db_type = &DB_Type;
10278 bsddb_api.dbcursor_type = &DBCursor_Type;
10279 bsddb_api.dblogcursor_type = &DBLogCursor_Type;
10280 bsddb_api.dbenv_type = &DBEnv_Type;
10281 bsddb_api.dbtxn_type = &DBTxn_Type;
10282 bsddb_api.dblock_type = &DBLock_Type;
Jesus Cea6557aac2010-03-22 14:22:26 +000010283 bsddb_api.dbsequence_type = &DBSequence_Type;
Jesus Cea6557aac2010-03-22 14:22:26 +000010284 bsddb_api.makeDBError = makeDBError;
Gregory P. Smith39250532007-10-09 06:02:21 +000010285
Jesus Cea6557aac2010-03-22 14:22:26 +000010286 /*
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010287 ** Capsules exist from Python 2.7 and 3.1.
10288 ** We don't support Python 3.0 anymore, so...
10289 ** #if (PY_VERSION_HEX < ((PY_MAJOR_VERSION < 3) ? 0x02070000 : 0x03020000))
Jesus Cea6557aac2010-03-22 14:22:26 +000010290 */
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010291#if (PY_VERSION_HEX < 0x02070000)
Gregory P. Smith39250532007-10-09 06:02:21 +000010292 py_api = PyCObject_FromVoidPtr((void*)&bsddb_api, NULL);
Jesus Cea6557aac2010-03-22 14:22:26 +000010293#else
10294 {
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010295 /*
10296 ** The data must outlive the call!!. So, the static definition.
10297 ** The buffer must be big enough...
10298 */
10299 static char py_api_name[MODULE_NAME_MAX_LEN+10];
Jesus Cea6557aac2010-03-22 14:22:26 +000010300
10301 strcpy(py_api_name, _bsddbModuleName);
10302 strcat(py_api_name, ".api");
10303
10304 py_api = PyCapsule_New((void*)&bsddb_api, py_api_name, NULL);
10305 }
10306#endif
10307
Jesus Cea84f2c322010-11-05 00:13:50 +000010308 /* Check error control */
10309 /*
10310 ** PyErr_NoMemory();
10311 ** py_api = NULL;
10312 */
10313
10314 if (py_api) {
10315 PyDict_SetItemString(d, "api", py_api);
10316 Py_DECREF(py_api);
10317 } else { /* Something bad happened */
10318 PyErr_WriteUnraisable(m);
Jesus Ceabf088f82010-11-08 12:57:59 +000010319 if(PyErr_Warn(PyExc_RuntimeWarning,
10320 "_bsddb/_pybsddb C API will be not available")) {
10321 PyErr_WriteUnraisable(m);
10322 }
Jesus Cea84f2c322010-11-05 00:13:50 +000010323 PyErr_Clear();
10324 }
Gregory P. Smith39250532007-10-09 06:02:21 +000010325
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010326 /* Check for errors */
10327 if (PyErr_Occurred()) {
10328 PyErr_Print();
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010329 Py_FatalError("can't initialize module _bsddb/_pybsddb");
10330 Py_DECREF(m);
10331 m = NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010332 }
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010333#if (PY_VERSION_HEX < 0x03000000)
10334 return;
10335#else
10336 return m;
10337#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010338}
Gregory P. Smith41631e82003-09-21 00:08:14 +000010339
10340/* allow this module to be named _pybsddb so that it can be installed
10341 * and imported on top of python >= 2.3 that includes its own older
10342 * copy of the library named _bsddb without importing the old version. */
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010343#if (PY_VERSION_HEX < 0x03000000)
Gregory P. Smith41631e82003-09-21 00:08:14 +000010344DL_EXPORT(void) init_pybsddb(void)
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010345#else
10346PyMODINIT_FUNC PyInit__pybsddb(void) /* Note the two underscores */
10347#endif
Gregory P. Smith41631e82003-09-21 00:08:14 +000010348{
10349 strncpy(_bsddbModuleName, "_pybsddb", MODULE_NAME_MAX_LEN);
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010350#if (PY_VERSION_HEX < 0x03000000)
Gregory P. Smith41631e82003-09-21 00:08:14 +000010351 init_bsddb();
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010352#else
10353 return PyInit__bsddb(); /* Note the two underscores */
10354#endif
Gregory P. Smith41631e82003-09-21 00:08:14 +000010355}