blob: a319333b8eaf848f3a95ab27acacd0c51a65fea9 [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. */
Thomas Woutersb3153832006-03-08 01:47:19 +00001610 Py_XINCREF(callback);
Serhiy Storchakabc62af12016-04-06 09:51:18 +03001611 Py_XSETREF(secondaryDB->associateCallback, callback);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001612 secondaryDB->primaryDBType = _DB_get_type(self);
1613
Martin v. Löwisb2c7aff2002-11-23 11:26:07 +00001614 /* PyEval_InitThreads is called here due to a quirk in python 1.5
1615 * - 2.2.1 (at least) according to Russell Williamson <merel@wt.net>:
1616 * The global interepreter lock is not initialized until the first
1617 * thread is created using thread.start_new_thread() or fork() is
1618 * called. that would cause the ALLOW_THREADS here to segfault due
1619 * to a null pointer reference if no threads or child processes
1620 * have been created. This works around that and is a no-op if
1621 * threads have already been initialized.
1622 * (see pybsddb-users mailing list post on 2002-08-07)
1623 */
Gregory P. Smithaa71f5f2003-01-17 07:56:16 +00001624#ifdef WITH_THREAD
Martin v. Löwisb2c7aff2002-11-23 11:26:07 +00001625 PyEval_InitThreads();
Gregory P. Smithaa71f5f2003-01-17 07:56:16 +00001626#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001627 MYDB_BEGIN_ALLOW_THREADS;
Barry Warsaw9a0d7792002-12-30 20:53:52 +00001628 err = self->db->associate(self->db,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001629 txn,
Barry Warsaw9a0d7792002-12-30 20:53:52 +00001630 secondaryDB->db,
1631 _db_associateCallback,
1632 flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001633 MYDB_END_ALLOW_THREADS;
1634
1635 if (err) {
Serhiy Storchaka98a97222014-02-09 13:14:04 +02001636 Py_CLEAR(secondaryDB->associateCallback);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001637 secondaryDB->primaryDBType = 0;
1638 }
1639
1640 RETURN_IF_ERR();
1641 RETURN_NONE();
1642}
1643
1644
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001645static PyObject*
Jesus Cea5cd5f122008-09-23 18:54:08 +00001646DB_close_internal(DBObject* self, int flags, int do_not_close)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001647{
Jesus Ceaef9764f2008-05-13 18:45:46 +00001648 PyObject *dummy;
Jesus Cea5cd5f122008-09-23 18:54:08 +00001649 int err = 0;
Jesus Ceaef9764f2008-05-13 18:45:46 +00001650
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001651 if (self->db != NULL) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00001652 /* Can be NULL if db is not in an environment */
1653 EXTRACT_FROM_DOUBLE_LINKED_LIST_MAYBE_NULL(self);
Jesus Cea4907d272008-08-31 14:00:51 +00001654
Jesus Ceaef9764f2008-05-13 18:45:46 +00001655 if (self->txn) {
1656 EXTRACT_FROM_DOUBLE_LINKED_LIST_TXN(self);
1657 self->txn=NULL;
1658 }
1659
1660 while(self->children_cursors) {
1661 dummy=DBC_close_internal(self->children_cursors);
1662 Py_XDECREF(dummy);
1663 }
1664
Jesus Ceaef9764f2008-05-13 18:45:46 +00001665 while(self->children_sequences) {
1666 dummy=DBSequence_close_internal(self->children_sequences,0,0);
1667 Py_XDECREF(dummy);
1668 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00001669
Jesus Cea5cd5f122008-09-23 18:54:08 +00001670 /*
1671 ** "do_not_close" is used to dispose all related objects in the
1672 ** tree, without actually releasing the "root" object.
1673 ** This is done, for example, because function calls like
1674 ** "DB.verify()" implicitly close the underlying handle. So
1675 ** the handle doesn't need to be closed, but related objects
1676 ** must be cleaned up.
1677 */
1678 if (!do_not_close) {
1679 MYDB_BEGIN_ALLOW_THREADS;
1680 err = self->db->close(self->db, flags);
1681 MYDB_END_ALLOW_THREADS;
1682 self->db = NULL;
1683 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001684 RETURN_IF_ERR();
1685 }
1686 RETURN_NONE();
1687}
1688
Jesus Ceaef9764f2008-05-13 18:45:46 +00001689static PyObject*
1690DB_close(DBObject* self, PyObject* args)
1691{
1692 int flags=0;
1693 if (!PyArg_ParseTuple(args,"|i:close", &flags))
1694 return NULL;
Jesus Cea5cd5f122008-09-23 18:54:08 +00001695 return DB_close_internal(self, flags, 0);
Jesus Ceaef9764f2008-05-13 18:45:46 +00001696}
1697
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001698
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001699static PyObject*
1700_DB_consume(DBObject* self, PyObject* args, PyObject* kwargs, int consume_flag)
1701{
1702 int err, flags=0, type;
1703 PyObject* txnobj = NULL;
1704 PyObject* retval = NULL;
1705 DBT key, data;
1706 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00001707 static char* kwnames[] = { "txn", "flags", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001708
1709 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Oi:consume", kwnames,
1710 &txnobj, &flags))
1711 return NULL;
1712
1713 CHECK_DB_NOT_CLOSED(self);
1714 type = _DB_get_type(self);
1715 if (type == -1)
1716 return NULL;
1717 if (type != DB_QUEUE) {
Barry Warsaw9a0d7792002-12-30 20:53:52 +00001718 PyErr_SetString(PyExc_TypeError,
1719 "Consume methods only allowed for Queue DB's");
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001720 return NULL;
1721 }
1722 if (!checkTxnObj(txnobj, &txn))
1723 return NULL;
1724
1725 CLEAR_DBT(key);
1726 CLEAR_DBT(data);
1727 if (CHECK_DBFLAG(self, DB_THREAD)) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00001728 /* Tell Berkeley DB to malloc the return value (thread safe) */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001729 data.flags = DB_DBT_MALLOC;
1730 key.flags = DB_DBT_MALLOC;
1731 }
1732
1733 MYDB_BEGIN_ALLOW_THREADS;
1734 err = self->db->get(self->db, txn, &key, &data, flags|consume_flag);
1735 MYDB_END_ALLOW_THREADS;
1736
Gregory P. Smithe9477062005-06-04 06:46:59 +00001737 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001738 && self->moduleFlags.getReturnsNone) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001739 err = 0;
1740 Py_INCREF(Py_None);
1741 retval = Py_None;
1742 }
1743 else if (!err) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00001744 retval = BuildValue_SS(key.data, key.size, data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001745 FREE_DBT(key);
1746 FREE_DBT(data);
1747 }
1748
1749 RETURN_IF_ERR();
1750 return retval;
1751}
1752
1753static PyObject*
1754DB_consume(DBObject* self, PyObject* args, PyObject* kwargs, int consume_flag)
1755{
1756 return _DB_consume(self, args, kwargs, DB_CONSUME);
1757}
1758
1759static PyObject*
Barry Warsaw9a0d7792002-12-30 20:53:52 +00001760DB_consume_wait(DBObject* self, PyObject* args, PyObject* kwargs,
1761 int consume_flag)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001762{
1763 return _DB_consume(self, args, kwargs, DB_CONSUME_WAIT);
1764}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001765
1766
1767static PyObject*
1768DB_cursor(DBObject* self, PyObject* args, PyObject* kwargs)
1769{
1770 int err, flags=0;
1771 DBC* dbc;
1772 PyObject* txnobj = NULL;
1773 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00001774 static char* kwnames[] = { "txn", "flags", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001775
1776 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Oi:cursor", kwnames,
1777 &txnobj, &flags))
1778 return NULL;
1779 CHECK_DB_NOT_CLOSED(self);
1780 if (!checkTxnObj(txnobj, &txn))
1781 return NULL;
1782
1783 MYDB_BEGIN_ALLOW_THREADS;
1784 err = self->db->cursor(self->db, txn, &dbc, flags);
1785 MYDB_END_ALLOW_THREADS;
1786 RETURN_IF_ERR();
Jesus Ceaef9764f2008-05-13 18:45:46 +00001787 return (PyObject*) newDBCursorObject(dbc, (DBTxnObject *)txnobj, self);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001788}
1789
1790
1791static PyObject*
1792DB_delete(DBObject* self, PyObject* args, PyObject* kwargs)
1793{
1794 PyObject* txnobj = NULL;
1795 int flags = 0;
1796 PyObject* keyobj;
1797 DBT key;
1798 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00001799 static char* kwnames[] = { "key", "txn", "flags", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001800
1801 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|Oi:delete", kwnames,
1802 &keyobj, &txnobj, &flags))
1803 return NULL;
1804 CHECK_DB_NOT_CLOSED(self);
1805 if (!make_key_dbt(self, keyobj, &key, NULL))
1806 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00001807 if (!checkTxnObj(txnobj, &txn)) {
1808 FREE_DBT(key);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001809 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00001810 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001811
Gregory P. Smithdc5af702004-06-27 23:32:34 +00001812 if (-1 == _DB_delete(self, txn, &key, 0)) {
1813 FREE_DBT(key);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001814 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00001815 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001816
1817 FREE_DBT(key);
1818 RETURN_NONE();
1819}
1820
1821
Jesus Cea6557aac2010-03-22 14:22:26 +00001822#if (DBVER >= 47)
1823/*
1824** This function is available since Berkeley DB 4.4,
1825** but 4.6 version is so buggy that we only support
1826** it from BDB 4.7 and newer.
1827*/
1828static PyObject*
1829DB_compact(DBObject* self, PyObject* args, PyObject* kwargs)
1830{
1831 PyObject* txnobj = NULL;
1832 PyObject *startobj = NULL, *stopobj = NULL;
1833 int flags = 0;
1834 DB_TXN *txn = NULL;
1835 DBT *start_p = NULL, *stop_p = NULL;
1836 DBT start, stop;
1837 int err;
1838 DB_COMPACT c_data = { 0 };
1839 static char* kwnames[] = { "txn", "start", "stop", "flags",
1840 "compact_fillpercent", "compact_pages",
1841 "compact_timeout", NULL };
1842
1843
1844 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OOOiiiI:compact", kwnames,
1845 &txnobj, &startobj, &stopobj, &flags,
1846 &c_data.compact_fillpercent,
1847 &c_data.compact_pages,
1848 &c_data.compact_timeout))
1849 return NULL;
1850
1851 CHECK_DB_NOT_CLOSED(self);
1852 if (!checkTxnObj(txnobj, &txn)) {
1853 return NULL;
1854 }
1855
1856 if (startobj && make_key_dbt(self, startobj, &start, NULL)) {
1857 start_p = &start;
1858 }
1859 if (stopobj && make_key_dbt(self, stopobj, &stop, NULL)) {
1860 stop_p = &stop;
1861 }
1862
1863 MYDB_BEGIN_ALLOW_THREADS;
1864 err = self->db->compact(self->db, txn, start_p, stop_p, &c_data,
1865 flags, NULL);
1866 MYDB_END_ALLOW_THREADS;
1867
1868 if (startobj)
1869 FREE_DBT(start);
1870 if (stopobj)
1871 FREE_DBT(stop);
1872
1873 RETURN_IF_ERR();
1874
1875 return PyLong_FromUnsignedLong(c_data.compact_pages_truncated);
1876}
1877#endif
1878
1879
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001880static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00001881DB_fd(DBObject* self)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001882{
1883 int err, the_fd;
1884
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001885 CHECK_DB_NOT_CLOSED(self);
1886
1887 MYDB_BEGIN_ALLOW_THREADS;
1888 err = self->db->fd(self->db, &the_fd);
1889 MYDB_END_ALLOW_THREADS;
1890 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00001891 return NUMBER_FromLong(the_fd);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001892}
1893
1894
Jesus Cea6557aac2010-03-22 14:22:26 +00001895#if (DBVER >= 46)
1896static PyObject*
1897DB_exists(DBObject* self, PyObject* args, PyObject* kwargs)
1898{
1899 int err, flags=0;
1900 PyObject* txnobj = NULL;
1901 PyObject* keyobj;
1902 DBT key;
1903 DB_TXN *txn;
1904
1905 static char* kwnames[] = {"key", "txn", "flags", NULL};
1906
1907 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|Oi:exists", kwnames,
1908 &keyobj, &txnobj, &flags))
1909 return NULL;
1910
1911 CHECK_DB_NOT_CLOSED(self);
1912 if (!make_key_dbt(self, keyobj, &key, NULL))
1913 return NULL;
1914 if (!checkTxnObj(txnobj, &txn)) {
1915 FREE_DBT(key);
1916 return NULL;
1917 }
1918
1919 MYDB_BEGIN_ALLOW_THREADS;
1920 err = self->db->exists(self->db, txn, &key, flags);
1921 MYDB_END_ALLOW_THREADS;
1922
1923 FREE_DBT(key);
1924
1925 if (!err) {
1926 Py_INCREF(Py_True);
1927 return Py_True;
1928 }
1929 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)) {
1930 Py_INCREF(Py_False);
1931 return Py_False;
1932 }
1933
1934 /*
1935 ** If we reach there, there was an error. The
1936 ** "return" should be unreachable.
1937 */
1938 RETURN_IF_ERR();
1939 assert(0); /* This coude SHOULD be unreachable */
1940 return NULL;
1941}
1942#endif
1943
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001944static PyObject*
1945DB_get(DBObject* self, PyObject* args, PyObject* kwargs)
1946{
1947 int err, flags=0;
1948 PyObject* txnobj = NULL;
1949 PyObject* keyobj;
1950 PyObject* dfltobj = NULL;
1951 PyObject* retval = NULL;
1952 int dlen = -1;
1953 int doff = -1;
1954 DBT key, data;
1955 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00001956 static char* kwnames[] = {"key", "default", "txn", "flags", "dlen",
Jeremy Hyltonaf68c872005-12-10 18:50:16 +00001957 "doff", NULL};
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001958
1959 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|OOiii:get", kwnames,
Barry Warsaw9a0d7792002-12-30 20:53:52 +00001960 &keyobj, &dfltobj, &txnobj, &flags, &dlen,
1961 &doff))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001962 return NULL;
1963
1964 CHECK_DB_NOT_CLOSED(self);
1965 if (!make_key_dbt(self, keyobj, &key, &flags))
1966 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00001967 if (!checkTxnObj(txnobj, &txn)) {
1968 FREE_DBT(key);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001969 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00001970 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001971
1972 CLEAR_DBT(data);
1973 if (CHECK_DBFLAG(self, DB_THREAD)) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00001974 /* Tell Berkeley DB to malloc the return value (thread safe) */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001975 data.flags = DB_DBT_MALLOC;
1976 }
Gregory P. Smithdc5af702004-06-27 23:32:34 +00001977 if (!add_partial_dbt(&data, dlen, doff)) {
1978 FREE_DBT(key);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001979 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00001980 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001981
1982 MYDB_BEGIN_ALLOW_THREADS;
1983 err = self->db->get(self->db, txn, &key, &data, flags);
1984 MYDB_END_ALLOW_THREADS;
1985
Gregory P. Smithe9477062005-06-04 06:46:59 +00001986 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY) && (dfltobj != NULL)) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001987 err = 0;
1988 Py_INCREF(dfltobj);
1989 retval = dfltobj;
1990 }
Gregory P. Smithe9477062005-06-04 06:46:59 +00001991 else if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001992 && self->moduleFlags.getReturnsNone) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001993 err = 0;
1994 Py_INCREF(Py_None);
1995 retval = Py_None;
1996 }
1997 else if (!err) {
1998 if (flags & DB_SET_RECNO) /* return both key and data */
Jesus Ceaef9764f2008-05-13 18:45:46 +00001999 retval = BuildValue_SS(key.data, key.size, data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002000 else /* return just the data */
Jesus Ceaef9764f2008-05-13 18:45:46 +00002001 retval = Build_PyString(data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002002 FREE_DBT(data);
2003 }
Gregory P. Smithdc5af702004-06-27 23:32:34 +00002004 FREE_DBT(key);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002005
2006 RETURN_IF_ERR();
2007 return retval;
2008}
2009
Gregory P. Smith19699a92004-06-28 04:06:49 +00002010static PyObject*
2011DB_pget(DBObject* self, PyObject* args, PyObject* kwargs)
2012{
2013 int err, flags=0;
2014 PyObject* txnobj = NULL;
2015 PyObject* keyobj;
2016 PyObject* dfltobj = NULL;
2017 PyObject* retval = NULL;
2018 int dlen = -1;
2019 int doff = -1;
2020 DBT key, pkey, data;
2021 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002022 static char* kwnames[] = {"key", "default", "txn", "flags", "dlen",
Jeremy Hyltonaf68c872005-12-10 18:50:16 +00002023 "doff", NULL};
Gregory P. Smith19699a92004-06-28 04:06:49 +00002024
2025 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|OOiii:pget", kwnames,
2026 &keyobj, &dfltobj, &txnobj, &flags, &dlen,
2027 &doff))
2028 return NULL;
2029
2030 CHECK_DB_NOT_CLOSED(self);
2031 if (!make_key_dbt(self, keyobj, &key, &flags))
2032 return NULL;
2033 if (!checkTxnObj(txnobj, &txn)) {
2034 FREE_DBT(key);
2035 return NULL;
2036 }
2037
2038 CLEAR_DBT(data);
2039 if (CHECK_DBFLAG(self, DB_THREAD)) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00002040 /* Tell Berkeley DB to malloc the return value (thread safe) */
Gregory P. Smith19699a92004-06-28 04:06:49 +00002041 data.flags = DB_DBT_MALLOC;
2042 }
2043 if (!add_partial_dbt(&data, dlen, doff)) {
2044 FREE_DBT(key);
2045 return NULL;
2046 }
2047
2048 CLEAR_DBT(pkey);
2049 pkey.flags = DB_DBT_MALLOC;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002050
Gregory P. Smith19699a92004-06-28 04:06:49 +00002051 MYDB_BEGIN_ALLOW_THREADS;
2052 err = self->db->pget(self->db, txn, &key, &pkey, &data, flags);
2053 MYDB_END_ALLOW_THREADS;
2054
Gregory P. Smithe9477062005-06-04 06:46:59 +00002055 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY) && (dfltobj != NULL)) {
Gregory P. Smith19699a92004-06-28 04:06:49 +00002056 err = 0;
2057 Py_INCREF(dfltobj);
2058 retval = dfltobj;
2059 }
Gregory P. Smithe9477062005-06-04 06:46:59 +00002060 else if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002061 && self->moduleFlags.getReturnsNone) {
Gregory P. Smith19699a92004-06-28 04:06:49 +00002062 err = 0;
2063 Py_INCREF(Py_None);
2064 retval = Py_None;
2065 }
2066 else if (!err) {
2067 PyObject *pkeyObj;
2068 PyObject *dataObj;
Jesus Ceaef9764f2008-05-13 18:45:46 +00002069 dataObj = Build_PyString(data.data, data.size);
Gregory P. Smith19699a92004-06-28 04:06:49 +00002070
2071 if (self->primaryDBType == DB_RECNO ||
2072 self->primaryDBType == DB_QUEUE)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002073 pkeyObj = NUMBER_FromLong(*(int *)pkey.data);
Gregory P. Smith19699a92004-06-28 04:06:49 +00002074 else
Jesus Ceaef9764f2008-05-13 18:45:46 +00002075 pkeyObj = Build_PyString(pkey.data, pkey.size);
Gregory P. Smith19699a92004-06-28 04:06:49 +00002076
2077 if (flags & DB_SET_RECNO) /* return key , pkey and data */
2078 {
2079 PyObject *keyObj;
2080 int type = _DB_get_type(self);
2081 if (type == DB_RECNO || type == DB_QUEUE)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002082 keyObj = NUMBER_FromLong(*(int *)key.data);
Gregory P. Smith19699a92004-06-28 04:06:49 +00002083 else
Jesus Ceaef9764f2008-05-13 18:45:46 +00002084 keyObj = Build_PyString(key.data, key.size);
Gregory P. Smith4e414d82006-01-24 19:55:02 +00002085 retval = PyTuple_Pack(3, keyObj, pkeyObj, dataObj);
Thomas Woutersb3153832006-03-08 01:47:19 +00002086 Py_DECREF(keyObj);
Gregory P. Smith19699a92004-06-28 04:06:49 +00002087 }
2088 else /* return just the pkey and data */
2089 {
Gregory P. Smith4e414d82006-01-24 19:55:02 +00002090 retval = PyTuple_Pack(2, pkeyObj, dataObj);
Gregory P. Smith19699a92004-06-28 04:06:49 +00002091 }
Thomas Woutersb3153832006-03-08 01:47:19 +00002092 Py_DECREF(dataObj);
2093 Py_DECREF(pkeyObj);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002094 FREE_DBT(pkey);
Gregory P. Smith19699a92004-06-28 04:06:49 +00002095 FREE_DBT(data);
2096 }
2097 FREE_DBT(key);
2098
2099 RETURN_IF_ERR();
2100 return retval;
2101}
2102
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002103
2104/* Return size of entry */
2105static PyObject*
2106DB_get_size(DBObject* self, PyObject* args, PyObject* kwargs)
2107{
2108 int err, flags=0;
2109 PyObject* txnobj = NULL;
2110 PyObject* keyobj;
2111 PyObject* retval = NULL;
2112 DBT key, data;
2113 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002114 static char* kwnames[] = { "key", "txn", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002115
2116 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O:get_size", kwnames,
2117 &keyobj, &txnobj))
2118 return NULL;
2119 CHECK_DB_NOT_CLOSED(self);
2120 if (!make_key_dbt(self, keyobj, &key, &flags))
2121 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00002122 if (!checkTxnObj(txnobj, &txn)) {
2123 FREE_DBT(key);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002124 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00002125 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002126 CLEAR_DBT(data);
2127
Gregory P. Smith8b7e9172004-12-13 09:51:23 +00002128 /* We don't allocate any memory, forcing a DB_BUFFER_SMALL error and
2129 thus getting the record size. */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002130 data.flags = DB_DBT_USERMEM;
2131 data.ulen = 0;
2132 MYDB_BEGIN_ALLOW_THREADS;
2133 err = self->db->get(self->db, txn, &key, &data, flags);
2134 MYDB_END_ALLOW_THREADS;
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07002135 if ((err == DB_BUFFER_SMALL) || (err == 0)) {
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002136 retval = NUMBER_FromLong((long)data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002137 err = 0;
2138 }
2139
2140 FREE_DBT(key);
2141 FREE_DBT(data);
2142 RETURN_IF_ERR();
2143 return retval;
2144}
2145
2146
2147static PyObject*
2148DB_get_both(DBObject* self, PyObject* args, PyObject* kwargs)
2149{
2150 int err, flags=0;
2151 PyObject* txnobj = NULL;
2152 PyObject* keyobj;
2153 PyObject* dataobj;
2154 PyObject* retval = NULL;
2155 DBT key, data;
Neal Norwitz994ebed2007-06-03 20:32:50 +00002156 void *orig_data;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002157 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002158 static char* kwnames[] = { "key", "data", "txn", "flags", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002159
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002160 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|Oi:get_both", kwnames,
2161 &keyobj, &dataobj, &txnobj, &flags))
2162 return NULL;
2163
2164 CHECK_DB_NOT_CLOSED(self);
2165 if (!make_key_dbt(self, keyobj, &key, NULL))
2166 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00002167 if ( !make_dbt(dataobj, &data) ||
2168 !checkTxnObj(txnobj, &txn) )
2169 {
2170 FREE_DBT(key);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002171 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00002172 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002173
2174 flags |= DB_GET_BOTH;
Neal Norwitz994ebed2007-06-03 20:32:50 +00002175 orig_data = data.data;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002176
2177 if (CHECK_DBFLAG(self, DB_THREAD)) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00002178 /* Tell Berkeley DB to malloc the return value (thread safe) */
Neal Norwitz994ebed2007-06-03 20:32:50 +00002179 /* XXX(nnorwitz): At least 4.4.20 and 4.5.20 require this flag. */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002180 data.flags = DB_DBT_MALLOC;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002181 }
2182
2183 MYDB_BEGIN_ALLOW_THREADS;
2184 err = self->db->get(self->db, txn, &key, &data, flags);
2185 MYDB_END_ALLOW_THREADS;
2186
Gregory P. Smithe9477062005-06-04 06:46:59 +00002187 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002188 && self->moduleFlags.getReturnsNone) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002189 err = 0;
2190 Py_INCREF(Py_None);
2191 retval = Py_None;
2192 }
2193 else if (!err) {
Neal Norwitz994ebed2007-06-03 20:32:50 +00002194 /* XXX(nnorwitz): can we do: retval = dataobj; Py_INCREF(retval); */
Jesus Ceaef9764f2008-05-13 18:45:46 +00002195 retval = Build_PyString(data.data, data.size);
Neal Norwitz994ebed2007-06-03 20:32:50 +00002196
2197 /* Even though the flags require DB_DBT_MALLOC, data is not always
2198 allocated. 4.4: allocated, 4.5: *not* allocated. :-( */
2199 if (data.data != orig_data)
2200 FREE_DBT(data);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002201 }
2202
2203 FREE_DBT(key);
2204 RETURN_IF_ERR();
2205 return retval;
2206}
2207
2208
2209static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002210DB_get_byteswapped(DBObject* self)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002211{
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002212 int err = 0;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002213 int retval = -1;
2214
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002215 CHECK_DB_NOT_CLOSED(self);
2216
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002217 MYDB_BEGIN_ALLOW_THREADS;
2218 err = self->db->get_byteswapped(self->db, &retval);
2219 MYDB_END_ALLOW_THREADS;
2220 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002221 return NUMBER_FromLong(retval);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002222}
2223
2224
2225static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002226DB_get_type(DBObject* self)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002227{
2228 int type;
2229
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002230 CHECK_DB_NOT_CLOSED(self);
2231
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002232 type = _DB_get_type(self);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002233 if (type == -1)
2234 return NULL;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002235 return NUMBER_FromLong(type);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002236}
2237
2238
2239static PyObject*
2240DB_join(DBObject* self, PyObject* args)
2241{
2242 int err, flags=0;
2243 int length, x;
2244 PyObject* cursorsObj;
2245 DBC** cursors;
2246 DBC* dbc;
2247
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002248 if (!PyArg_ParseTuple(args,"O|i:join", &cursorsObj, &flags))
2249 return NULL;
2250
2251 CHECK_DB_NOT_CLOSED(self);
2252
2253 if (!PySequence_Check(cursorsObj)) {
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002254 PyErr_SetString(PyExc_TypeError,
2255 "Sequence of DBCursor objects expected");
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002256 return NULL;
2257 }
2258
2259 length = PyObject_Length(cursorsObj);
2260 cursors = malloc((length+1) * sizeof(DBC*));
Neal Norwitz5aa96892006-08-13 18:11:43 +00002261 if (!cursors) {
Jesus Cea6557aac2010-03-22 14:22:26 +00002262 PyErr_NoMemory();
2263 return NULL;
Neal Norwitz5aa96892006-08-13 18:11:43 +00002264 }
2265
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002266 cursors[length] = NULL;
2267 for (x=0; x<length; x++) {
2268 PyObject* item = PySequence_GetItem(cursorsObj, x);
Thomas Woutersb3153832006-03-08 01:47:19 +00002269 if (item == NULL) {
2270 free(cursors);
2271 return NULL;
2272 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002273 if (!DBCursorObject_Check(item)) {
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002274 PyErr_SetString(PyExc_TypeError,
2275 "Sequence of DBCursor objects expected");
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002276 free(cursors);
2277 return NULL;
2278 }
2279 cursors[x] = ((DBCursorObject*)item)->dbc;
Thomas Woutersb2820ae2006-03-12 00:01:38 +00002280 Py_DECREF(item);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002281 }
2282
2283 MYDB_BEGIN_ALLOW_THREADS;
2284 err = self->db->join(self->db, cursors, &dbc, flags);
2285 MYDB_END_ALLOW_THREADS;
2286 free(cursors);
2287 RETURN_IF_ERR();
2288
Gregory P. Smith7441e652003-11-03 21:35:31 +00002289 /* FIXME: this is a buggy interface. The returned cursor
2290 contains internal references to the passed in cursors
2291 but does not hold python references to them or prevent
2292 them from being closed prematurely. This can cause
2293 python to crash when things are done in the wrong order. */
Jesus Ceaef9764f2008-05-13 18:45:46 +00002294 return (PyObject*) newDBCursorObject(dbc, NULL, self);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002295}
2296
2297
2298static PyObject*
2299DB_key_range(DBObject* self, PyObject* args, PyObject* kwargs)
2300{
2301 int err, flags=0;
2302 PyObject* txnobj = NULL;
2303 PyObject* keyobj;
2304 DBT key;
2305 DB_TXN *txn = NULL;
2306 DB_KEY_RANGE range;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002307 static char* kwnames[] = { "key", "txn", "flags", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002308
2309 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|Oi:key_range", kwnames,
2310 &keyobj, &txnobj, &flags))
2311 return NULL;
2312 CHECK_DB_NOT_CLOSED(self);
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002313 if (!make_dbt(keyobj, &key))
2314 /* BTree only, don't need to allow for an int key */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002315 return NULL;
2316 if (!checkTxnObj(txnobj, &txn))
2317 return NULL;
2318
2319 MYDB_BEGIN_ALLOW_THREADS;
2320 err = self->db->key_range(self->db, txn, &key, &range, flags);
2321 MYDB_END_ALLOW_THREADS;
2322
2323 RETURN_IF_ERR();
2324 return Py_BuildValue("ddd", range.less, range.equal, range.greater);
2325}
2326
2327
2328static PyObject*
2329DB_open(DBObject* self, PyObject* args, PyObject* kwargs)
2330{
2331 int err, type = DB_UNKNOWN, flags=0, mode=0660;
2332 char* filename = NULL;
2333 char* dbname = NULL;
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002334 PyObject *txnobj = NULL;
2335 DB_TXN *txn = NULL;
2336 /* with dbname */
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002337 static char* kwnames[] = {
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002338 "filename", "dbname", "dbtype", "flags", "mode", "txn", NULL};
2339 /* without dbname */
Tim Peters85b10522006-02-28 18:33:35 +00002340 static char* kwnames_basic[] = {
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002341 "filename", "dbtype", "flags", "mode", "txn", NULL};
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002342
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002343 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "z|ziiiO:open", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002344 &filename, &dbname, &type, &flags, &mode,
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002345 &txnobj))
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002346 {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002347 PyErr_Clear();
2348 type = DB_UNKNOWN; flags = 0; mode = 0660;
2349 filename = NULL; dbname = NULL;
2350 if (!PyArg_ParseTupleAndKeywords(args, kwargs,"z|iiiO:open",
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002351 kwnames_basic,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002352 &filename, &type, &flags, &mode,
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002353 &txnobj))
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002354 return NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002355 }
2356
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002357 if (!checkTxnObj(txnobj, &txn)) return NULL;
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002358
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002359 if (NULL == self->db) {
Thomas Woutersb3153832006-03-08 01:47:19 +00002360 PyObject *t = Py_BuildValue("(is)", 0,
2361 "Cannot call open() twice for DB object");
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002362 if (t) {
2363 PyErr_SetObject(DBError, t);
2364 Py_DECREF(t);
2365 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002366 return NULL;
2367 }
2368
Jesus Ceaef9764f2008-05-13 18:45:46 +00002369 if (txn) { /* Can't use 'txnobj' because could be 'txnobj==Py_None' */
2370 INSERT_IN_DOUBLE_LINKED_LIST_TXN(((DBTxnObject *)txnobj)->children_dbs,self);
2371 self->txn=(DBTxnObject *)txnobj;
2372 } else {
2373 self->txn=NULL;
2374 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00002375
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002376 MYDB_BEGIN_ALLOW_THREADS;
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002377 err = self->db->open(self->db, txn, filename, dbname, type, flags, mode);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002378 MYDB_END_ALLOW_THREADS;
Jesus Cea6557aac2010-03-22 14:22:26 +00002379
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002380 if (makeDBError(err)) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00002381 PyObject *dummy;
2382
Jesus Cea5cd5f122008-09-23 18:54:08 +00002383 dummy=DB_close_internal(self, 0, 0);
Jesus Ceaef9764f2008-05-13 18:45:46 +00002384 Py_XDECREF(dummy);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002385 return NULL;
2386 }
2387
Gregory P. Smithec10a4a2007-11-05 02:32:26 +00002388 self->db->get_flags(self->db, &self->setflags);
2389
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002390 self->flags = flags;
Jesus Ceaef9764f2008-05-13 18:45:46 +00002391
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002392 RETURN_NONE();
2393}
2394
2395
2396static PyObject*
2397DB_put(DBObject* self, PyObject* args, PyObject* kwargs)
2398{
2399 int flags=0;
2400 PyObject* txnobj = NULL;
2401 int dlen = -1;
2402 int doff = -1;
2403 PyObject* keyobj, *dataobj, *retval;
2404 DBT key, data;
2405 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002406 static char* kwnames[] = { "key", "data", "txn", "flags", "dlen",
Jeremy Hyltonaf68c872005-12-10 18:50:16 +00002407 "doff", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002408
2409 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|Oiii:put", kwnames,
2410 &keyobj, &dataobj, &txnobj, &flags, &dlen, &doff))
2411 return NULL;
2412
2413 CHECK_DB_NOT_CLOSED(self);
Gregory P. Smithdc5af702004-06-27 23:32:34 +00002414 if (!make_key_dbt(self, keyobj, &key, NULL))
2415 return NULL;
2416 if ( !make_dbt(dataobj, &data) ||
2417 !add_partial_dbt(&data, dlen, doff) ||
2418 !checkTxnObj(txnobj, &txn) )
2419 {
2420 FREE_DBT(key);
2421 return NULL;
2422 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002423
2424 if (-1 == _DB_put(self, txn, &key, &data, flags)) {
2425 FREE_DBT(key);
2426 return NULL;
2427 }
2428
2429 if (flags & DB_APPEND)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002430 retval = NUMBER_FromLong(*((db_recno_t*)key.data));
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002431 else {
2432 retval = Py_None;
2433 Py_INCREF(retval);
2434 }
2435 FREE_DBT(key);
2436 return retval;
2437}
2438
2439
2440
2441static PyObject*
2442DB_remove(DBObject* self, PyObject* args, PyObject* kwargs)
2443{
2444 char* filename;
2445 char* database = NULL;
2446 int err, flags=0;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002447 static char* kwnames[] = { "filename", "dbname", "flags", NULL};
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002448
2449 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|zi:remove", kwnames,
2450 &filename, &database, &flags))
2451 return NULL;
2452 CHECK_DB_NOT_CLOSED(self);
2453
Jesus Cea4907d272008-08-31 14:00:51 +00002454 EXTRACT_FROM_DOUBLE_LINKED_LIST_MAYBE_NULL(self);
2455
2456 MYDB_BEGIN_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002457 err = self->db->remove(self->db, filename, database, flags);
Jesus Cea4907d272008-08-31 14:00:51 +00002458 MYDB_END_ALLOW_THREADS;
2459
Gregory P. Smithf655dff2003-05-15 00:13:18 +00002460 self->db = NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002461 RETURN_IF_ERR();
2462 RETURN_NONE();
2463}
2464
2465
2466
2467static PyObject*
2468DB_rename(DBObject* self, PyObject* args)
2469{
2470 char* filename;
2471 char* database;
2472 char* newname;
2473 int err, flags=0;
2474
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002475 if (!PyArg_ParseTuple(args, "sss|i:rename", &filename, &database, &newname,
2476 &flags))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002477 return NULL;
2478 CHECK_DB_NOT_CLOSED(self);
2479
2480 MYDB_BEGIN_ALLOW_THREADS;
2481 err = self->db->rename(self->db, filename, database, newname, flags);
2482 MYDB_END_ALLOW_THREADS;
2483 RETURN_IF_ERR();
2484 RETURN_NONE();
2485}
2486
2487
2488static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002489DB_get_private(DBObject* self)
2490{
2491 /* We can give out the private field even if db is closed */
Jesus Cea4907d272008-08-31 14:00:51 +00002492 Py_INCREF(self->private_obj);
2493 return self->private_obj;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002494}
2495
2496static PyObject*
Jesus Cea4907d272008-08-31 14:00:51 +00002497DB_set_private(DBObject* self, PyObject* private_obj)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002498{
2499 /* We can set the private field even if db is closed */
Jesus Cea4907d272008-08-31 14:00:51 +00002500 Py_INCREF(private_obj);
Serhiy Storchaka763a61c2016-04-10 18:05:12 +03002501 Py_SETREF(self->private_obj, private_obj);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002502 RETURN_NONE();
2503}
2504
Jesus Cea6557aac2010-03-22 14:22:26 +00002505#if (DBVER >= 46)
2506static PyObject*
2507DB_set_priority(DBObject* self, PyObject* args)
2508{
2509 int err, priority;
2510
2511 if (!PyArg_ParseTuple(args,"i:set_priority", &priority))
2512 return NULL;
2513 CHECK_DB_NOT_CLOSED(self);
2514
2515 MYDB_BEGIN_ALLOW_THREADS;
2516 err = self->db->set_priority(self->db, priority);
2517 MYDB_END_ALLOW_THREADS;
2518 RETURN_IF_ERR();
2519 RETURN_NONE();
2520}
2521
2522static PyObject*
2523DB_get_priority(DBObject* self)
2524{
2525 int err = 0;
2526 DB_CACHE_PRIORITY priority;
2527
2528 CHECK_DB_NOT_CLOSED(self);
2529
2530 MYDB_BEGIN_ALLOW_THREADS;
2531 err = self->db->get_priority(self->db, &priority);
2532 MYDB_END_ALLOW_THREADS;
2533 RETURN_IF_ERR();
2534 return NUMBER_FromLong(priority);
2535}
2536#endif
2537
2538static PyObject*
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07002539DB_get_dbname(DBObject* self)
2540{
2541 int err;
2542 const char *filename, *dbname;
2543
2544 CHECK_DB_NOT_CLOSED(self);
2545
2546 MYDB_BEGIN_ALLOW_THREADS;
2547 err = self->db->get_dbname(self->db, &filename, &dbname);
2548 MYDB_END_ALLOW_THREADS;
2549 RETURN_IF_ERR();
2550 /* If "dbname==NULL", it is correctly converted to "None" */
2551 return Py_BuildValue("(ss)", filename, dbname);
2552}
2553
2554static PyObject*
2555DB_get_open_flags(DBObject* self)
2556{
2557 int err;
2558 unsigned int flags;
2559
2560 CHECK_DB_NOT_CLOSED(self);
2561
2562 MYDB_BEGIN_ALLOW_THREADS;
2563 err = self->db->get_open_flags(self->db, &flags);
2564 MYDB_END_ALLOW_THREADS;
2565 RETURN_IF_ERR();
2566 return NUMBER_FromLong(flags);
2567}
2568
2569static PyObject*
Jesus Cea6557aac2010-03-22 14:22:26 +00002570DB_set_q_extentsize(DBObject* self, PyObject* args)
2571{
2572 int err;
2573 u_int32_t extentsize;
2574
2575 if (!PyArg_ParseTuple(args,"i:set_q_extentsize", &extentsize))
2576 return NULL;
2577 CHECK_DB_NOT_CLOSED(self);
2578
2579 MYDB_BEGIN_ALLOW_THREADS;
2580 err = self->db->set_q_extentsize(self->db, extentsize);
2581 MYDB_END_ALLOW_THREADS;
2582 RETURN_IF_ERR();
2583 RETURN_NONE();
2584}
2585
Jesus Cea6557aac2010-03-22 14:22:26 +00002586static PyObject*
2587DB_get_q_extentsize(DBObject* self)
2588{
2589 int err = 0;
2590 u_int32_t extentsize;
2591
2592 CHECK_DB_NOT_CLOSED(self);
2593
2594 MYDB_BEGIN_ALLOW_THREADS;
2595 err = self->db->get_q_extentsize(self->db, &extentsize);
2596 MYDB_END_ALLOW_THREADS;
2597 RETURN_IF_ERR();
2598 return NUMBER_FromLong(extentsize);
2599}
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002600
2601static PyObject*
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002602DB_set_bt_minkey(DBObject* self, PyObject* args)
2603{
2604 int err, minkey;
2605
Jesus Cea6557aac2010-03-22 14:22:26 +00002606 if (!PyArg_ParseTuple(args,"i:set_bt_minkey", &minkey))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002607 return NULL;
2608 CHECK_DB_NOT_CLOSED(self);
2609
2610 MYDB_BEGIN_ALLOW_THREADS;
2611 err = self->db->set_bt_minkey(self->db, minkey);
2612 MYDB_END_ALLOW_THREADS;
2613 RETURN_IF_ERR();
2614 RETURN_NONE();
2615}
2616
Jesus Cea6557aac2010-03-22 14:22:26 +00002617static PyObject*
2618DB_get_bt_minkey(DBObject* self)
2619{
2620 int err;
2621 u_int32_t bt_minkey;
2622
2623 CHECK_DB_NOT_CLOSED(self);
2624
2625 MYDB_BEGIN_ALLOW_THREADS;
2626 err = self->db->get_bt_minkey(self->db, &bt_minkey);
2627 MYDB_END_ALLOW_THREADS;
2628 RETURN_IF_ERR();
2629 return NUMBER_FromLong(bt_minkey);
2630}
Jesus Cea6557aac2010-03-22 14:22:26 +00002631
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002632static int
Georg Brandlef1701f2006-03-07 14:57:48 +00002633_default_cmp(const DBT *leftKey,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002634 const DBT *rightKey)
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002635{
2636 int res;
2637 int lsize = leftKey->size, rsize = rightKey->size;
2638
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002639 res = memcmp(leftKey->data, rightKey->data,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002640 lsize < rsize ? lsize : rsize);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002641
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002642 if (res == 0) {
2643 if (lsize < rsize) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002644 res = -1;
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002645 }
2646 else if (lsize > rsize) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002647 res = 1;
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002648 }
2649 }
2650 return res;
2651}
2652
2653static int
Jesus Ceaef9764f2008-05-13 18:45:46 +00002654_db_compareCallback(DB* db,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002655 const DBT *leftKey,
2656 const DBT *rightKey)
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002657{
2658 int res = 0;
2659 PyObject *args;
Thomas Woutersb2820ae2006-03-12 00:01:38 +00002660 PyObject *result = NULL;
Georg Brandlef1701f2006-03-07 14:57:48 +00002661 DBObject *self = (DBObject *)db->app_private;
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002662
2663 if (self == NULL || self->btCompareCallback == NULL) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002664 MYDB_BEGIN_BLOCK_THREADS;
2665 PyErr_SetString(PyExc_TypeError,
2666 (self == 0
2667 ? "DB_bt_compare db is NULL."
2668 : "DB_bt_compare callback is NULL."));
2669 /* we're in a callback within the DB code, we can't raise */
2670 PyErr_Print();
2671 res = _default_cmp(leftKey, rightKey);
2672 MYDB_END_BLOCK_THREADS;
Georg Brandlef1701f2006-03-07 14:57:48 +00002673 } else {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002674 MYDB_BEGIN_BLOCK_THREADS;
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002675
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002676 args = BuildValue_SS(leftKey->data, leftKey->size, rightKey->data, rightKey->size);
2677 if (args != NULL) {
2678 result = PyEval_CallObject(self->btCompareCallback, args);
2679 }
2680 if (args == NULL || result == NULL) {
2681 /* we're in a callback within the DB code, we can't raise */
2682 PyErr_Print();
2683 res = _default_cmp(leftKey, rightKey);
2684 } else if (NUMBER_Check(result)) {
2685 res = NUMBER_AsLong(result);
2686 } else {
2687 PyErr_SetString(PyExc_TypeError,
2688 "DB_bt_compare callback MUST return an int.");
2689 /* we're in a callback within the DB code, we can't raise */
2690 PyErr_Print();
2691 res = _default_cmp(leftKey, rightKey);
2692 }
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002693
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002694 Py_XDECREF(args);
2695 Py_XDECREF(result);
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002696
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002697 MYDB_END_BLOCK_THREADS;
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002698 }
2699 return res;
2700}
2701
2702static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002703DB_set_bt_compare(DBObject* self, PyObject* comparator)
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002704{
2705 int err;
Thomas Woutersb3153832006-03-08 01:47:19 +00002706 PyObject *tuple, *result;
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002707
Georg Brandlef1701f2006-03-07 14:57:48 +00002708 CHECK_DB_NOT_CLOSED(self);
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002709
Georg Brandlef1701f2006-03-07 14:57:48 +00002710 if (!PyCallable_Check(comparator)) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002711 makeTypeError("Callable", comparator);
2712 return NULL;
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002713 }
2714
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002715 /*
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002716 * Perform a test call of the comparator function with two empty
2717 * string objects here. verify that it returns an int (0).
2718 * err if not.
2719 */
Thomas Woutersb3153832006-03-08 01:47:19 +00002720 tuple = Py_BuildValue("(ss)", "", "");
Georg Brandlef1701f2006-03-07 14:57:48 +00002721 result = PyEval_CallObject(comparator, tuple);
2722 Py_DECREF(tuple);
Thomas Woutersb3153832006-03-08 01:47:19 +00002723 if (result == NULL)
2724 return NULL;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002725 if (!NUMBER_Check(result)) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002726 Py_DECREF(result);
2727 PyErr_SetString(PyExc_TypeError,
2728 "callback MUST return an int");
2729 return NULL;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002730 } else if (NUMBER_AsLong(result) != 0) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002731 Py_DECREF(result);
2732 PyErr_SetString(PyExc_TypeError,
2733 "callback failed to return 0 on two empty strings");
2734 return NULL;
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002735 }
Thomas Woutersb3153832006-03-08 01:47:19 +00002736 Py_DECREF(result);
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002737
2738 /* We don't accept multiple set_bt_compare operations, in order to
2739 * simplify the code. This would have no real use, as one cannot
2740 * change the function once the db is opened anyway */
2741 if (self->btCompareCallback != NULL) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002742 PyErr_SetString(PyExc_RuntimeError, "set_bt_compare() cannot be called more than once");
2743 return NULL;
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002744 }
2745
Georg Brandlef1701f2006-03-07 14:57:48 +00002746 Py_INCREF(comparator);
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002747 self->btCompareCallback = comparator;
2748
2749 /* This is to workaround a problem with un-initialized threads (see
2750 comment in DB_associate) */
2751#ifdef WITH_THREAD
2752 PyEval_InitThreads();
2753#endif
2754
Thomas Woutersb3153832006-03-08 01:47:19 +00002755 err = self->db->set_bt_compare(self->db, _db_compareCallback);
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002756
2757 if (err) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002758 /* restore the old state in case of error */
2759 Py_DECREF(comparator);
2760 self->btCompareCallback = NULL;
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002761 }
2762
Georg Brandlef1701f2006-03-07 14:57:48 +00002763 RETURN_IF_ERR();
2764 RETURN_NONE();
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002765}
2766
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07002767static int
2768_db_dupCompareCallback(DB* db,
2769 const DBT *leftKey,
2770 const DBT *rightKey)
2771{
2772 int res = 0;
2773 PyObject *args;
2774 PyObject *result = NULL;
2775 DBObject *self = (DBObject *)db->app_private;
2776
2777 if (self == NULL || self->dupCompareCallback == NULL) {
2778 MYDB_BEGIN_BLOCK_THREADS;
2779 PyErr_SetString(PyExc_TypeError,
2780 (self == 0
2781 ? "DB_dup_compare db is NULL."
2782 : "DB_dup_compare callback is NULL."));
2783 /* we're in a callback within the DB code, we can't raise */
2784 PyErr_Print();
2785 res = _default_cmp(leftKey, rightKey);
2786 MYDB_END_BLOCK_THREADS;
2787 } else {
2788 MYDB_BEGIN_BLOCK_THREADS;
2789
2790 args = BuildValue_SS(leftKey->data, leftKey->size, rightKey->data, rightKey->size);
2791 if (args != NULL) {
2792 result = PyEval_CallObject(self->dupCompareCallback, args);
2793 }
2794 if (args == NULL || result == NULL) {
2795 /* we're in a callback within the DB code, we can't raise */
2796 PyErr_Print();
2797 res = _default_cmp(leftKey, rightKey);
2798 } else if (NUMBER_Check(result)) {
2799 res = NUMBER_AsLong(result);
2800 } else {
2801 PyErr_SetString(PyExc_TypeError,
2802 "DB_dup_compare callback MUST return an int.");
2803 /* we're in a callback within the DB code, we can't raise */
2804 PyErr_Print();
2805 res = _default_cmp(leftKey, rightKey);
2806 }
2807
2808 Py_XDECREF(args);
2809 Py_XDECREF(result);
2810
2811 MYDB_END_BLOCK_THREADS;
2812 }
2813 return res;
2814}
2815
2816static PyObject*
2817DB_set_dup_compare(DBObject* self, PyObject* comparator)
2818{
2819 int err;
2820 PyObject *tuple, *result;
2821
2822 CHECK_DB_NOT_CLOSED(self);
2823
2824 if (!PyCallable_Check(comparator)) {
2825 makeTypeError("Callable", comparator);
2826 return NULL;
2827 }
2828
2829 /*
2830 * Perform a test call of the comparator function with two empty
2831 * string objects here. verify that it returns an int (0).
2832 * err if not.
2833 */
2834 tuple = Py_BuildValue("(ss)", "", "");
2835 result = PyEval_CallObject(comparator, tuple);
2836 Py_DECREF(tuple);
2837 if (result == NULL)
2838 return NULL;
2839 if (!NUMBER_Check(result)) {
2840 Py_DECREF(result);
2841 PyErr_SetString(PyExc_TypeError,
2842 "callback MUST return an int");
2843 return NULL;
2844 } else if (NUMBER_AsLong(result) != 0) {
2845 Py_DECREF(result);
2846 PyErr_SetString(PyExc_TypeError,
2847 "callback failed to return 0 on two empty strings");
2848 return NULL;
2849 }
2850 Py_DECREF(result);
2851
2852 /* We don't accept multiple set_dup_compare operations, in order to
2853 * simplify the code. This would have no real use, as one cannot
2854 * change the function once the db is opened anyway */
2855 if (self->dupCompareCallback != NULL) {
2856 PyErr_SetString(PyExc_RuntimeError, "set_dup_compare() cannot be called more than once");
2857 return NULL;
2858 }
2859
2860 Py_INCREF(comparator);
2861 self->dupCompareCallback = comparator;
2862
2863 /* This is to workaround a problem with un-initialized threads (see
2864 comment in DB_associate) */
2865#ifdef WITH_THREAD
2866 PyEval_InitThreads();
2867#endif
2868
2869 err = self->db->set_dup_compare(self->db, _db_dupCompareCallback);
2870
2871 if (err) {
2872 /* restore the old state in case of error */
2873 Py_DECREF(comparator);
2874 self->dupCompareCallback = NULL;
2875 }
2876
2877 RETURN_IF_ERR();
2878 RETURN_NONE();
2879}
2880
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002881
2882static PyObject*
2883DB_set_cachesize(DBObject* self, PyObject* args)
2884{
2885 int err;
2886 int gbytes = 0, bytes = 0, ncache = 0;
2887
2888 if (!PyArg_ParseTuple(args,"ii|i:set_cachesize",
2889 &gbytes,&bytes,&ncache))
2890 return NULL;
2891 CHECK_DB_NOT_CLOSED(self);
2892
2893 MYDB_BEGIN_ALLOW_THREADS;
2894 err = self->db->set_cachesize(self->db, gbytes, bytes, ncache);
2895 MYDB_END_ALLOW_THREADS;
2896 RETURN_IF_ERR();
2897 RETURN_NONE();
2898}
2899
Jesus Cea6557aac2010-03-22 14:22:26 +00002900static PyObject*
2901DB_get_cachesize(DBObject* self)
2902{
2903 int err;
2904 u_int32_t gbytes, bytes;
2905 int ncache;
2906
2907 CHECK_DB_NOT_CLOSED(self);
2908
2909 MYDB_BEGIN_ALLOW_THREADS;
2910 err = self->db->get_cachesize(self->db, &gbytes, &bytes, &ncache);
2911 MYDB_END_ALLOW_THREADS;
2912
2913 RETURN_IF_ERR();
2914
2915 return Py_BuildValue("(iii)", gbytes, bytes, ncache);
2916}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002917
2918static PyObject*
2919DB_set_flags(DBObject* self, PyObject* args)
2920{
2921 int err, flags;
2922
2923 if (!PyArg_ParseTuple(args,"i:set_flags", &flags))
2924 return NULL;
2925 CHECK_DB_NOT_CLOSED(self);
2926
2927 MYDB_BEGIN_ALLOW_THREADS;
2928 err = self->db->set_flags(self->db, flags);
2929 MYDB_END_ALLOW_THREADS;
2930 RETURN_IF_ERR();
2931
2932 self->setflags |= flags;
2933 RETURN_NONE();
2934}
2935
Jesus Cea6557aac2010-03-22 14:22:26 +00002936static PyObject*
2937DB_get_flags(DBObject* self)
2938{
2939 int err;
2940 u_int32_t flags;
2941
2942 CHECK_DB_NOT_CLOSED(self);
2943
2944 MYDB_BEGIN_ALLOW_THREADS;
2945 err = self->db->get_flags(self->db, &flags);
2946 MYDB_END_ALLOW_THREADS;
2947 RETURN_IF_ERR();
2948 return NUMBER_FromLong(flags);
2949}
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07002950
2951static PyObject*
2952DB_get_transactional(DBObject* self)
2953{
2954 int err;
2955
2956 CHECK_DB_NOT_CLOSED(self);
2957
2958 MYDB_BEGIN_ALLOW_THREADS;
2959 err = self->db->get_transactional(self->db);
2960 MYDB_END_ALLOW_THREADS;
2961
2962 if(err == 0) {
2963 Py_INCREF(Py_False);
2964 return Py_False;
2965 } else if(err == 1) {
2966 Py_INCREF(Py_True);
2967 return Py_True;
2968 }
2969
2970 /*
2971 ** If we reach there, there was an error. The
2972 ** "return" should be unreachable.
2973 */
2974 RETURN_IF_ERR();
2975 assert(0); /* This code SHOULD be unreachable */
2976 return NULL;
2977}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002978
2979static PyObject*
2980DB_set_h_ffactor(DBObject* self, PyObject* args)
2981{
2982 int err, ffactor;
2983
2984 if (!PyArg_ParseTuple(args,"i:set_h_ffactor", &ffactor))
2985 return NULL;
2986 CHECK_DB_NOT_CLOSED(self);
2987
2988 MYDB_BEGIN_ALLOW_THREADS;
2989 err = self->db->set_h_ffactor(self->db, ffactor);
2990 MYDB_END_ALLOW_THREADS;
2991 RETURN_IF_ERR();
2992 RETURN_NONE();
2993}
2994
Jesus Cea6557aac2010-03-22 14:22:26 +00002995static PyObject*
2996DB_get_h_ffactor(DBObject* self)
2997{
2998 int err;
2999 u_int32_t ffactor;
3000
3001 CHECK_DB_NOT_CLOSED(self);
3002
3003 MYDB_BEGIN_ALLOW_THREADS;
3004 err = self->db->get_h_ffactor(self->db, &ffactor);
3005 MYDB_END_ALLOW_THREADS;
3006 RETURN_IF_ERR();
3007 return NUMBER_FromLong(ffactor);
3008}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003009
3010static PyObject*
3011DB_set_h_nelem(DBObject* self, PyObject* args)
3012{
3013 int err, nelem;
3014
3015 if (!PyArg_ParseTuple(args,"i:set_h_nelem", &nelem))
3016 return NULL;
3017 CHECK_DB_NOT_CLOSED(self);
3018
3019 MYDB_BEGIN_ALLOW_THREADS;
3020 err = self->db->set_h_nelem(self->db, nelem);
3021 MYDB_END_ALLOW_THREADS;
3022 RETURN_IF_ERR();
3023 RETURN_NONE();
3024}
3025
Jesus Cea6557aac2010-03-22 14:22:26 +00003026static PyObject*
3027DB_get_h_nelem(DBObject* self)
3028{
3029 int err;
3030 u_int32_t nelem;
3031
3032 CHECK_DB_NOT_CLOSED(self);
3033
3034 MYDB_BEGIN_ALLOW_THREADS;
3035 err = self->db->get_h_nelem(self->db, &nelem);
3036 MYDB_END_ALLOW_THREADS;
3037 RETURN_IF_ERR();
3038 return NUMBER_FromLong(nelem);
3039}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003040
3041static PyObject*
3042DB_set_lorder(DBObject* self, PyObject* args)
3043{
3044 int err, lorder;
3045
3046 if (!PyArg_ParseTuple(args,"i:set_lorder", &lorder))
3047 return NULL;
3048 CHECK_DB_NOT_CLOSED(self);
3049
3050 MYDB_BEGIN_ALLOW_THREADS;
3051 err = self->db->set_lorder(self->db, lorder);
3052 MYDB_END_ALLOW_THREADS;
3053 RETURN_IF_ERR();
3054 RETURN_NONE();
3055}
3056
Jesus Cea6557aac2010-03-22 14:22:26 +00003057static PyObject*
3058DB_get_lorder(DBObject* self)
3059{
3060 int err;
3061 int lorder;
3062
3063 CHECK_DB_NOT_CLOSED(self);
3064
3065 MYDB_BEGIN_ALLOW_THREADS;
3066 err = self->db->get_lorder(self->db, &lorder);
3067 MYDB_END_ALLOW_THREADS;
3068 RETURN_IF_ERR();
3069 return NUMBER_FromLong(lorder);
3070}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003071
3072static PyObject*
3073DB_set_pagesize(DBObject* self, PyObject* args)
3074{
3075 int err, pagesize;
3076
3077 if (!PyArg_ParseTuple(args,"i:set_pagesize", &pagesize))
3078 return NULL;
3079 CHECK_DB_NOT_CLOSED(self);
3080
3081 MYDB_BEGIN_ALLOW_THREADS;
3082 err = self->db->set_pagesize(self->db, pagesize);
3083 MYDB_END_ALLOW_THREADS;
3084 RETURN_IF_ERR();
3085 RETURN_NONE();
3086}
3087
Jesus Cea6557aac2010-03-22 14:22:26 +00003088static PyObject*
3089DB_get_pagesize(DBObject* self)
3090{
3091 int err;
3092 u_int32_t pagesize;
3093
3094 CHECK_DB_NOT_CLOSED(self);
3095
3096 MYDB_BEGIN_ALLOW_THREADS;
3097 err = self->db->get_pagesize(self->db, &pagesize);
3098 MYDB_END_ALLOW_THREADS;
3099 RETURN_IF_ERR();
3100 return NUMBER_FromLong(pagesize);
3101}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003102
3103static PyObject*
3104DB_set_re_delim(DBObject* self, PyObject* args)
3105{
3106 int err;
3107 char delim;
3108
3109 if (!PyArg_ParseTuple(args,"b:set_re_delim", &delim)) {
3110 PyErr_Clear();
3111 if (!PyArg_ParseTuple(args,"c:set_re_delim", &delim))
3112 return NULL;
3113 }
3114
3115 CHECK_DB_NOT_CLOSED(self);
3116
3117 MYDB_BEGIN_ALLOW_THREADS;
3118 err = self->db->set_re_delim(self->db, delim);
3119 MYDB_END_ALLOW_THREADS;
3120 RETURN_IF_ERR();
3121 RETURN_NONE();
3122}
3123
Jesus Cea6557aac2010-03-22 14:22:26 +00003124static PyObject*
3125DB_get_re_delim(DBObject* self)
3126{
3127 int err, re_delim;
3128
3129 CHECK_DB_NOT_CLOSED(self);
3130
3131 MYDB_BEGIN_ALLOW_THREADS;
3132 err = self->db->get_re_delim(self->db, &re_delim);
3133 MYDB_END_ALLOW_THREADS;
3134 RETURN_IF_ERR();
3135 return NUMBER_FromLong(re_delim);
3136}
Jesus Cea6557aac2010-03-22 14:22:26 +00003137
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003138static PyObject*
3139DB_set_re_len(DBObject* self, PyObject* args)
3140{
3141 int err, len;
3142
3143 if (!PyArg_ParseTuple(args,"i:set_re_len", &len))
3144 return NULL;
3145 CHECK_DB_NOT_CLOSED(self);
3146
3147 MYDB_BEGIN_ALLOW_THREADS;
3148 err = self->db->set_re_len(self->db, len);
3149 MYDB_END_ALLOW_THREADS;
3150 RETURN_IF_ERR();
3151 RETURN_NONE();
3152}
3153
Jesus Cea6557aac2010-03-22 14:22:26 +00003154static PyObject*
3155DB_get_re_len(DBObject* self)
3156{
3157 int err;
3158 u_int32_t re_len;
3159
3160 CHECK_DB_NOT_CLOSED(self);
3161
3162 MYDB_BEGIN_ALLOW_THREADS;
3163 err = self->db->get_re_len(self->db, &re_len);
3164 MYDB_END_ALLOW_THREADS;
3165 RETURN_IF_ERR();
3166 return NUMBER_FromLong(re_len);
3167}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003168
3169static PyObject*
3170DB_set_re_pad(DBObject* self, PyObject* args)
3171{
3172 int err;
3173 char pad;
3174
3175 if (!PyArg_ParseTuple(args,"b:set_re_pad", &pad)) {
3176 PyErr_Clear();
3177 if (!PyArg_ParseTuple(args,"c:set_re_pad", &pad))
3178 return NULL;
3179 }
3180 CHECK_DB_NOT_CLOSED(self);
3181
3182 MYDB_BEGIN_ALLOW_THREADS;
3183 err = self->db->set_re_pad(self->db, pad);
3184 MYDB_END_ALLOW_THREADS;
3185 RETURN_IF_ERR();
3186 RETURN_NONE();
3187}
3188
Jesus Cea6557aac2010-03-22 14:22:26 +00003189static PyObject*
3190DB_get_re_pad(DBObject* self)
3191{
3192 int err, re_pad;
3193
3194 CHECK_DB_NOT_CLOSED(self);
3195
3196 MYDB_BEGIN_ALLOW_THREADS;
3197 err = self->db->get_re_pad(self->db, &re_pad);
3198 MYDB_END_ALLOW_THREADS;
3199 RETURN_IF_ERR();
3200 return NUMBER_FromLong(re_pad);
3201}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003202
3203static PyObject*
3204DB_set_re_source(DBObject* self, PyObject* args)
3205{
3206 int err;
Jesus Cea6557aac2010-03-22 14:22:26 +00003207 char *source;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003208
Jesus Cea6557aac2010-03-22 14:22:26 +00003209 if (!PyArg_ParseTuple(args,"s:set_re_source", &source))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003210 return NULL;
3211 CHECK_DB_NOT_CLOSED(self);
3212
3213 MYDB_BEGIN_ALLOW_THREADS;
Jesus Cea6557aac2010-03-22 14:22:26 +00003214 err = self->db->set_re_source(self->db, source);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003215 MYDB_END_ALLOW_THREADS;
3216 RETURN_IF_ERR();
3217 RETURN_NONE();
3218}
3219
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003220static PyObject*
Jesus Cea6557aac2010-03-22 14:22:26 +00003221DB_get_re_source(DBObject* self)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003222{
3223 int err;
Jesus Cea6557aac2010-03-22 14:22:26 +00003224 const char *source;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003225
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003226 CHECK_DB_NOT_CLOSED(self);
3227
3228 MYDB_BEGIN_ALLOW_THREADS;
Jesus Cea6557aac2010-03-22 14:22:26 +00003229 err = self->db->get_re_source(self->db, &source);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003230 MYDB_END_ALLOW_THREADS;
3231 RETURN_IF_ERR();
Jesus Cea6557aac2010-03-22 14:22:26 +00003232 return PyBytes_FromString(source);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003233}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003234
3235static PyObject*
Gregory P. Smith8b7e9172004-12-13 09:51:23 +00003236DB_stat(DBObject* self, PyObject* args, PyObject* kwargs)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003237{
3238 int err, flags = 0, type;
3239 void* sp;
3240 PyObject* d;
Gregory P. Smith8b7e9172004-12-13 09:51:23 +00003241 PyObject* txnobj = NULL;
3242 DB_TXN *txn = NULL;
Gregory P. Smith2fa06792006-09-19 17:35:04 +00003243 static char* kwnames[] = { "flags", "txn", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003244
Gregory P. Smith8b7e9172004-12-13 09:51:23 +00003245 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|iO:stat", kwnames,
3246 &flags, &txnobj))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003247 return NULL;
Gregory P. Smith8b7e9172004-12-13 09:51:23 +00003248 if (!checkTxnObj(txnobj, &txn))
3249 return NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003250 CHECK_DB_NOT_CLOSED(self);
3251
3252 MYDB_BEGIN_ALLOW_THREADS;
Gregory P. Smith8b7e9172004-12-13 09:51:23 +00003253 err = self->db->stat(self->db, txn, &sp, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003254 MYDB_END_ALLOW_THREADS;
3255 RETURN_IF_ERR();
3256
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003257 /* Turn the stat structure into a dictionary */
3258 type = _DB_get_type(self);
3259 if ((type == -1) || ((d = PyDict_New()) == NULL)) {
3260 free(sp);
3261 return NULL;
3262 }
3263
3264#define MAKE_HASH_ENTRY(name) _addIntToDict(d, #name, ((DB_HASH_STAT*)sp)->hash_##name)
3265#define MAKE_BT_ENTRY(name) _addIntToDict(d, #name, ((DB_BTREE_STAT*)sp)->bt_##name)
3266#define MAKE_QUEUE_ENTRY(name) _addIntToDict(d, #name, ((DB_QUEUE_STAT*)sp)->qs_##name)
3267
3268 switch (type) {
3269 case DB_HASH:
3270 MAKE_HASH_ENTRY(magic);
3271 MAKE_HASH_ENTRY(version);
3272 MAKE_HASH_ENTRY(nkeys);
3273 MAKE_HASH_ENTRY(ndata);
Jesus Ceaef9764f2008-05-13 18:45:46 +00003274#if (DBVER >= 46)
3275 MAKE_HASH_ENTRY(pagecnt);
3276#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003277 MAKE_HASH_ENTRY(pagesize);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003278 MAKE_HASH_ENTRY(ffactor);
3279 MAKE_HASH_ENTRY(buckets);
3280 MAKE_HASH_ENTRY(free);
3281 MAKE_HASH_ENTRY(bfree);
3282 MAKE_HASH_ENTRY(bigpages);
3283 MAKE_HASH_ENTRY(big_bfree);
3284 MAKE_HASH_ENTRY(overflows);
3285 MAKE_HASH_ENTRY(ovfl_free);
3286 MAKE_HASH_ENTRY(dup);
3287 MAKE_HASH_ENTRY(dup_free);
3288 break;
3289
3290 case DB_BTREE:
3291 case DB_RECNO:
3292 MAKE_BT_ENTRY(magic);
3293 MAKE_BT_ENTRY(version);
3294 MAKE_BT_ENTRY(nkeys);
3295 MAKE_BT_ENTRY(ndata);
Jesus Ceaef9764f2008-05-13 18:45:46 +00003296#if (DBVER >= 46)
3297 MAKE_BT_ENTRY(pagecnt);
3298#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003299 MAKE_BT_ENTRY(pagesize);
3300 MAKE_BT_ENTRY(minkey);
3301 MAKE_BT_ENTRY(re_len);
3302 MAKE_BT_ENTRY(re_pad);
3303 MAKE_BT_ENTRY(levels);
3304 MAKE_BT_ENTRY(int_pg);
3305 MAKE_BT_ENTRY(leaf_pg);
3306 MAKE_BT_ENTRY(dup_pg);
3307 MAKE_BT_ENTRY(over_pg);
Jesus Ceaef9764f2008-05-13 18:45:46 +00003308 MAKE_BT_ENTRY(empty_pg);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003309 MAKE_BT_ENTRY(free);
3310 MAKE_BT_ENTRY(int_pgfree);
3311 MAKE_BT_ENTRY(leaf_pgfree);
3312 MAKE_BT_ENTRY(dup_pgfree);
3313 MAKE_BT_ENTRY(over_pgfree);
3314 break;
3315
3316 case DB_QUEUE:
3317 MAKE_QUEUE_ENTRY(magic);
3318 MAKE_QUEUE_ENTRY(version);
3319 MAKE_QUEUE_ENTRY(nkeys);
3320 MAKE_QUEUE_ENTRY(ndata);
3321 MAKE_QUEUE_ENTRY(pagesize);
Jesus Ceaef9764f2008-05-13 18:45:46 +00003322 MAKE_QUEUE_ENTRY(extentsize);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003323 MAKE_QUEUE_ENTRY(pages);
3324 MAKE_QUEUE_ENTRY(re_len);
3325 MAKE_QUEUE_ENTRY(re_pad);
3326 MAKE_QUEUE_ENTRY(pgfree);
3327#if (DBVER == 31)
3328 MAKE_QUEUE_ENTRY(start);
3329#endif
3330 MAKE_QUEUE_ENTRY(first_recno);
3331 MAKE_QUEUE_ENTRY(cur_recno);
3332 break;
3333
3334 default:
3335 PyErr_SetString(PyExc_TypeError, "Unknown DB type, unable to stat");
3336 Py_DECREF(d);
3337 d = NULL;
3338 }
3339
3340#undef MAKE_HASH_ENTRY
3341#undef MAKE_BT_ENTRY
3342#undef MAKE_QUEUE_ENTRY
3343
3344 free(sp);
3345 return d;
3346}
3347
Jesus Cea6557aac2010-03-22 14:22:26 +00003348static PyObject*
3349DB_stat_print(DBObject* self, PyObject* args, PyObject *kwargs)
3350{
3351 int err;
3352 int flags=0;
3353 static char* kwnames[] = { "flags", NULL };
3354
3355 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:stat_print",
3356 kwnames, &flags))
3357 {
3358 return NULL;
3359 }
3360 CHECK_DB_NOT_CLOSED(self);
3361 MYDB_BEGIN_ALLOW_THREADS;
3362 err = self->db->stat_print(self->db, flags);
3363 MYDB_END_ALLOW_THREADS;
3364 RETURN_IF_ERR();
3365 RETURN_NONE();
3366}
Jesus Cea6557aac2010-03-22 14:22:26 +00003367
3368
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003369static PyObject*
3370DB_sync(DBObject* self, PyObject* args)
3371{
3372 int err;
3373 int flags = 0;
3374
3375 if (!PyArg_ParseTuple(args,"|i:sync", &flags ))
3376 return NULL;
3377 CHECK_DB_NOT_CLOSED(self);
3378
3379 MYDB_BEGIN_ALLOW_THREADS;
3380 err = self->db->sync(self->db, flags);
3381 MYDB_END_ALLOW_THREADS;
3382 RETURN_IF_ERR();
3383 RETURN_NONE();
3384}
3385
3386
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003387static PyObject*
3388DB_truncate(DBObject* self, PyObject* args, PyObject* kwargs)
3389{
3390 int err, flags=0;
3391 u_int32_t count=0;
3392 PyObject* txnobj = NULL;
3393 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003394 static char* kwnames[] = { "txn", "flags", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003395
3396 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Oi:cursor", kwnames,
3397 &txnobj, &flags))
3398 return NULL;
3399 CHECK_DB_NOT_CLOSED(self);
3400 if (!checkTxnObj(txnobj, &txn))
3401 return NULL;
3402
3403 MYDB_BEGIN_ALLOW_THREADS;
3404 err = self->db->truncate(self->db, txn, &count, flags);
3405 MYDB_END_ALLOW_THREADS;
3406 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00003407 return NUMBER_FromLong(count);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003408}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003409
3410
3411static PyObject*
3412DB_upgrade(DBObject* self, PyObject* args)
3413{
3414 int err, flags=0;
3415 char *filename;
3416
3417 if (!PyArg_ParseTuple(args,"s|i:upgrade", &filename, &flags))
3418 return NULL;
3419 CHECK_DB_NOT_CLOSED(self);
3420
3421 MYDB_BEGIN_ALLOW_THREADS;
3422 err = self->db->upgrade(self->db, filename, flags);
3423 MYDB_END_ALLOW_THREADS;
3424 RETURN_IF_ERR();
3425 RETURN_NONE();
3426}
3427
3428
3429static PyObject*
3430DB_verify(DBObject* self, PyObject* args, PyObject* kwargs)
3431{
3432 int err, flags=0;
3433 char* fileName;
3434 char* dbName=NULL;
3435 char* outFileName=NULL;
3436 FILE* outFile=NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003437 static char* kwnames[] = { "filename", "dbname", "outfile", "flags",
Jeremy Hyltonaf68c872005-12-10 18:50:16 +00003438 NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003439
3440 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|zzi:verify", kwnames,
3441 &fileName, &dbName, &outFileName, &flags))
3442 return NULL;
3443
3444 CHECK_DB_NOT_CLOSED(self);
3445 if (outFileName)
3446 outFile = fopen(outFileName, "w");
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003447 /* XXX(nnorwitz): it should probably be an exception if outFile
3448 can't be opened. */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003449
Jesus Ceaef9764f2008-05-13 18:45:46 +00003450 { /* DB.verify acts as a DB handle destructor (like close) */
3451 PyObject *error;
3452
Jesus Cea5cd5f122008-09-23 18:54:08 +00003453 error=DB_close_internal(self, 0, 1);
Jesus Cea6557aac2010-03-22 14:22:26 +00003454 if (error) {
Serhiy Storchakaaffac002015-07-24 08:05:45 +03003455 if (outFile)
3456 fclose(outFile);
3457 return error;
Jesus Ceaef9764f2008-05-13 18:45:46 +00003458 }
Serhiy Storchakaaffac002015-07-24 08:05:45 +03003459 }
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_INCREF(private_obj);
Serhiy Storchaka763a61c2016-04-10 18:05:12 +03007000 Py_SETREF(self->private_obj, private_obj);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007001 RETURN_NONE();
7002}
7003
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07007004#if (DBVER >= 47)
7005static PyObject*
7006DBEnv_set_intermediate_dir_mode(DBEnvObject* self, PyObject* args)
7007{
7008 int err;
7009 const char *mode;
7010
7011 if (!PyArg_ParseTuple(args,"s:set_intermediate_dir_mode", &mode))
7012 return NULL;
7013
7014 CHECK_ENV_NOT_CLOSED(self);
7015
7016 MYDB_BEGIN_ALLOW_THREADS;
7017 err = self->db_env->set_intermediate_dir_mode(self->db_env, mode);
7018 MYDB_END_ALLOW_THREADS;
7019 RETURN_IF_ERR();
7020 RETURN_NONE();
7021}
7022
7023static PyObject*
7024DBEnv_get_intermediate_dir_mode(DBEnvObject* self)
7025{
7026 int err;
7027 const char *mode;
7028
7029 CHECK_ENV_NOT_CLOSED(self);
7030
7031 MYDB_BEGIN_ALLOW_THREADS;
7032 err = self->db_env->get_intermediate_dir_mode(self->db_env, &mode);
7033 MYDB_END_ALLOW_THREADS;
7034 RETURN_IF_ERR();
7035 return Py_BuildValue("s", mode);
7036}
7037#endif
7038
7039#if (DBVER < 47)
7040static PyObject*
7041DBEnv_set_intermediate_dir(DBEnvObject* self, PyObject* args)
7042{
7043 int err;
7044 int mode;
7045 u_int32_t flags;
7046
7047 if (!PyArg_ParseTuple(args, "iI:set_intermediate_dir", &mode, &flags))
7048 return NULL;
7049
7050 CHECK_ENV_NOT_CLOSED(self);
7051
7052 MYDB_BEGIN_ALLOW_THREADS;
7053 err = self->db_env->set_intermediate_dir(self->db_env, mode, flags);
7054 MYDB_END_ALLOW_THREADS;
7055 RETURN_IF_ERR();
7056 RETURN_NONE();
7057}
7058#endif
7059
7060static PyObject*
7061DBEnv_get_open_flags(DBEnvObject* self)
7062{
7063 int err;
7064 unsigned int flags;
7065
7066 CHECK_ENV_NOT_CLOSED(self);
7067
7068 MYDB_BEGIN_ALLOW_THREADS;
7069 err = self->db_env->get_open_flags(self->db_env, &flags);
7070 MYDB_END_ALLOW_THREADS;
7071 RETURN_IF_ERR();
7072 return NUMBER_FromLong(flags);
7073}
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007074
Matthias Klose54cc5392010-03-15 12:46:18 +00007075#if (DBVER < 48)
Jesus Ceaef9764f2008-05-13 18:45:46 +00007076static PyObject*
Jesus Ceaca3939c2008-05-22 15:27:38 +00007077DBEnv_set_rpc_server(DBEnvObject* self, PyObject* args, PyObject* kwargs)
7078{
7079 int err;
7080 char *host;
7081 long cl_timeout=0, sv_timeout=0;
7082
7083 static char* kwnames[] = { "host", "cl_timeout", "sv_timeout", NULL};
7084
7085 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|ll:set_rpc_server", kwnames,
7086 &host, &cl_timeout, &sv_timeout))
7087 return NULL;
7088 CHECK_ENV_NOT_CLOSED(self);
7089
7090 MYDB_BEGIN_ALLOW_THREADS;
7091 err = self->db_env->set_rpc_server(self->db_env, NULL, host, cl_timeout,
7092 sv_timeout, 0);
7093 MYDB_END_ALLOW_THREADS;
7094 RETURN_IF_ERR();
7095 RETURN_NONE();
7096}
Matthias Klose54cc5392010-03-15 12:46:18 +00007097#endif
Jesus Ceaca3939c2008-05-22 15:27:38 +00007098
Jesus Cea6557aac2010-03-22 14:22:26 +00007099static PyObject*
7100DBEnv_set_mp_max_openfd(DBEnvObject* self, PyObject* args)
7101{
7102 int err;
7103 int maxopenfd;
7104
7105 if (!PyArg_ParseTuple(args, "i:set_mp_max_openfd", &maxopenfd)) {
7106 return NULL;
7107 }
7108 CHECK_ENV_NOT_CLOSED(self);
7109 MYDB_BEGIN_ALLOW_THREADS;
7110 err = self->db_env->set_mp_max_openfd(self->db_env, maxopenfd);
7111 MYDB_END_ALLOW_THREADS;
7112 RETURN_IF_ERR();
7113 RETURN_NONE();
7114}
7115
7116static PyObject*
7117DBEnv_get_mp_max_openfd(DBEnvObject* self)
7118{
7119 int err;
7120 int maxopenfd;
7121
7122 CHECK_ENV_NOT_CLOSED(self);
7123
7124 MYDB_BEGIN_ALLOW_THREADS;
7125 err = self->db_env->get_mp_max_openfd(self->db_env, &maxopenfd);
7126 MYDB_END_ALLOW_THREADS;
7127 RETURN_IF_ERR();
7128 return NUMBER_FromLong(maxopenfd);
7129}
7130
7131
7132static PyObject*
7133DBEnv_set_mp_max_write(DBEnvObject* self, PyObject* args)
7134{
7135 int err;
7136 int maxwrite, maxwrite_sleep;
7137
7138 if (!PyArg_ParseTuple(args, "ii:set_mp_max_write", &maxwrite,
7139 &maxwrite_sleep)) {
7140 return NULL;
7141 }
7142 CHECK_ENV_NOT_CLOSED(self);
7143 MYDB_BEGIN_ALLOW_THREADS;
7144 err = self->db_env->set_mp_max_write(self->db_env, maxwrite,
7145 maxwrite_sleep);
7146 MYDB_END_ALLOW_THREADS;
7147 RETURN_IF_ERR();
7148 RETURN_NONE();
7149}
7150
7151static PyObject*
7152DBEnv_get_mp_max_write(DBEnvObject* self)
7153{
7154 int err;
7155 int maxwrite;
7156#if (DBVER >= 46)
7157 db_timeout_t maxwrite_sleep;
7158#else
7159 int maxwrite_sleep;
7160#endif
7161
7162 CHECK_ENV_NOT_CLOSED(self);
7163
7164 MYDB_BEGIN_ALLOW_THREADS;
7165 err = self->db_env->get_mp_max_write(self->db_env, &maxwrite,
7166 &maxwrite_sleep);
7167 MYDB_END_ALLOW_THREADS;
7168 RETURN_IF_ERR();
7169
7170 return Py_BuildValue("(ii)", maxwrite, (int)maxwrite_sleep);
7171}
Jesus Cea6557aac2010-03-22 14:22:26 +00007172
7173
Jesus Ceaca3939c2008-05-22 15:27:38 +00007174static PyObject*
Jesus Ceaef9764f2008-05-13 18:45:46 +00007175DBEnv_set_verbose(DBEnvObject* self, PyObject* args)
7176{
7177 int err;
7178 int which, onoff;
7179
7180 if (!PyArg_ParseTuple(args, "ii:set_verbose", &which, &onoff)) {
7181 return NULL;
7182 }
7183 CHECK_ENV_NOT_CLOSED(self);
7184 MYDB_BEGIN_ALLOW_THREADS;
7185 err = self->db_env->set_verbose(self->db_env, which, onoff);
7186 MYDB_END_ALLOW_THREADS;
7187 RETURN_IF_ERR();
7188 RETURN_NONE();
7189}
7190
Jesus Ceaef9764f2008-05-13 18:45:46 +00007191static PyObject*
7192DBEnv_get_verbose(DBEnvObject* self, PyObject* args)
7193{
7194 int err;
7195 int which;
7196 int verbose;
7197
7198 if (!PyArg_ParseTuple(args, "i:get_verbose", &which)) {
7199 return NULL;
7200 }
7201 CHECK_ENV_NOT_CLOSED(self);
7202 MYDB_BEGIN_ALLOW_THREADS;
7203 err = self->db_env->get_verbose(self->db_env, which, &verbose);
7204 MYDB_END_ALLOW_THREADS;
7205 RETURN_IF_ERR();
7206 return PyBool_FromLong(verbose);
7207}
Jesus Ceaef9764f2008-05-13 18:45:46 +00007208
7209#if (DBVER >= 45)
7210static void
7211_dbenv_event_notifyCallback(DB_ENV* db_env, u_int32_t event, void *event_info)
7212{
7213 DBEnvObject *dbenv;
7214 PyObject* callback;
7215 PyObject* args;
7216 PyObject* result = NULL;
7217
7218 MYDB_BEGIN_BLOCK_THREADS;
7219 dbenv = (DBEnvObject *)db_env->app_private;
7220 callback = dbenv->event_notifyCallback;
7221 if (callback) {
7222 if (event == DB_EVENT_REP_NEWMASTER) {
7223 args = Py_BuildValue("(Oii)", dbenv, event, *((int *)event_info));
7224 } else {
7225 args = Py_BuildValue("(OiO)", dbenv, event, Py_None);
7226 }
7227 if (args) {
7228 result = PyEval_CallObject(callback, args);
7229 }
7230 if ((!args) || (!result)) {
7231 PyErr_Print();
7232 }
7233 Py_XDECREF(args);
7234 Py_XDECREF(result);
7235 }
7236 MYDB_END_BLOCK_THREADS;
7237}
7238#endif
7239
7240#if (DBVER >= 45)
7241static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007242DBEnv_set_event_notify(DBEnvObject* self, PyObject* notifyFunc)
Jesus Ceaef9764f2008-05-13 18:45:46 +00007243{
7244 int err;
Jesus Ceaef9764f2008-05-13 18:45:46 +00007245
7246 CHECK_ENV_NOT_CLOSED(self);
7247
7248 if (!PyCallable_Check(notifyFunc)) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00007249 makeTypeError("Callable", notifyFunc);
7250 return NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00007251 }
7252
Jesus Ceaef9764f2008-05-13 18:45:46 +00007253 Py_INCREF(notifyFunc);
Serhiy Storchakabc62af12016-04-06 09:51:18 +03007254 Py_XSETREF(self->event_notifyCallback, notifyFunc);
Jesus Ceaef9764f2008-05-13 18:45:46 +00007255
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007256 /* This is to workaround a problem with un-initialized threads (see
7257 comment in DB_associate) */
7258#ifdef WITH_THREAD
7259 PyEval_InitThreads();
7260#endif
7261
Jesus Ceaef9764f2008-05-13 18:45:46 +00007262 MYDB_BEGIN_ALLOW_THREADS;
7263 err = self->db_env->set_event_notify(self->db_env, _dbenv_event_notifyCallback);
7264 MYDB_END_ALLOW_THREADS;
7265
7266 if (err) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00007267 Py_DECREF(notifyFunc);
7268 self->event_notifyCallback = NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00007269 }
7270
7271 RETURN_IF_ERR();
7272 RETURN_NONE();
7273}
7274#endif
7275
7276
7277/* --------------------------------------------------------------------- */
7278/* REPLICATION METHODS: Base Replication */
7279
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007280
7281static PyObject*
7282DBEnv_rep_process_message(DBEnvObject* self, PyObject* args)
7283{
7284 int err;
7285 PyObject *control_py, *rec_py;
7286 DBT control, rec;
7287 int envid;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007288 DB_LSN lsn;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007289
7290 if (!PyArg_ParseTuple(args, "OOi:rep_process_message", &control_py,
7291 &rec_py, &envid))
7292 return NULL;
7293 CHECK_ENV_NOT_CLOSED(self);
7294
7295 if (!make_dbt(control_py, &control))
7296 return NULL;
7297 if (!make_dbt(rec_py, &rec))
7298 return NULL;
7299
7300 MYDB_BEGIN_ALLOW_THREADS;
7301#if (DBVER >= 46)
7302 err = self->db_env->rep_process_message(self->db_env, &control, &rec,
7303 envid, &lsn);
7304#else
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007305 err = self->db_env->rep_process_message(self->db_env, &control, &rec,
7306 &envid, &lsn);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007307#endif
7308 MYDB_END_ALLOW_THREADS;
7309 switch (err) {
7310 case DB_REP_NEWMASTER :
7311 return Py_BuildValue("(iO)", envid, Py_None);
7312 break;
7313
7314 case DB_REP_DUPMASTER :
7315 case DB_REP_HOLDELECTION :
7316#if (DBVER >= 44)
7317 case DB_REP_IGNORE :
7318 case DB_REP_JOIN_FAILURE :
7319#endif
7320 return Py_BuildValue("(iO)", err, Py_None);
7321 break;
7322 case DB_REP_NEWSITE :
Jesus Cea4907d272008-08-31 14:00:51 +00007323 {
7324 PyObject *tmp, *r;
7325
7326 if (!(tmp = PyBytes_FromStringAndSize(rec.data, rec.size))) {
7327 return NULL;
7328 }
7329
7330 r = Py_BuildValue("(iO)", err, tmp);
7331 Py_DECREF(tmp);
7332 return r;
7333 break;
7334 }
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007335 case DB_REP_NOTPERM :
7336 case DB_REP_ISPERM :
7337 return Py_BuildValue("(i(ll))", err, lsn.file, lsn.offset);
7338 break;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007339 }
7340 RETURN_IF_ERR();
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07007341 return PyTuple_Pack(2, Py_None, Py_None);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007342}
7343
7344static int
7345_DBEnv_rep_transportCallback(DB_ENV* db_env, const DBT* control, const DBT* rec,
7346 const DB_LSN *lsn, int envid, u_int32_t flags)
7347{
7348 DBEnvObject *dbenv;
7349 PyObject* rep_transport;
7350 PyObject* args;
Jesus Cea4907d272008-08-31 14:00:51 +00007351 PyObject *a, *b;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007352 PyObject* result = NULL;
7353 int ret=0;
7354
7355 MYDB_BEGIN_BLOCK_THREADS;
7356 dbenv = (DBEnvObject *)db_env->app_private;
7357 rep_transport = dbenv->rep_transport;
7358
Jesus Cea4907d272008-08-31 14:00:51 +00007359 /*
7360 ** The errors in 'a' or 'b' are detected in "Py_BuildValue".
7361 */
7362 a = PyBytes_FromStringAndSize(control->data, control->size);
7363 b = PyBytes_FromStringAndSize(rec->data, rec->size);
7364
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007365 args = Py_BuildValue(
Jesus Cea4907d272008-08-31 14:00:51 +00007366 "(OOO(ll)iI)",
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007367 dbenv,
Jesus Cea4907d272008-08-31 14:00:51 +00007368 a, b,
7369 lsn->file, lsn->offset, envid, flags);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007370 if (args) {
7371 result = PyEval_CallObject(rep_transport, args);
7372 }
7373
7374 if ((!args) || (!result)) {
7375 PyErr_Print();
7376 ret = -1;
7377 }
Jesus Cea4907d272008-08-31 14:00:51 +00007378 Py_XDECREF(a);
7379 Py_XDECREF(b);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007380 Py_XDECREF(args);
7381 Py_XDECREF(result);
7382 MYDB_END_BLOCK_THREADS;
7383 return ret;
7384}
7385
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007386static PyObject*
7387DBEnv_rep_set_transport(DBEnvObject* self, PyObject* args)
7388{
7389 int err;
7390 int envid;
7391 PyObject *rep_transport;
7392
7393 if (!PyArg_ParseTuple(args, "iO:rep_set_transport", &envid, &rep_transport))
7394 return NULL;
7395 CHECK_ENV_NOT_CLOSED(self);
7396 if (!PyCallable_Check(rep_transport)) {
7397 makeTypeError("Callable", rep_transport);
7398 return NULL;
7399 }
7400
7401 MYDB_BEGIN_ALLOW_THREADS;
7402#if (DBVER >=45)
7403 err = self->db_env->rep_set_transport(self->db_env, envid,
7404 &_DBEnv_rep_transportCallback);
7405#else
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007406 err = self->db_env->set_rep_transport(self->db_env, envid,
7407 &_DBEnv_rep_transportCallback);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007408#endif
7409 MYDB_END_ALLOW_THREADS;
7410 RETURN_IF_ERR();
7411
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007412 Py_INCREF(rep_transport);
Serhiy Storchaka763a61c2016-04-10 18:05:12 +03007413 Py_SETREF(self->rep_transport, rep_transport);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007414 RETURN_NONE();
7415}
7416
7417#if (DBVER >= 47)
7418static PyObject*
7419DBEnv_rep_set_request(DBEnvObject* self, PyObject* args)
7420{
7421 int err;
7422 unsigned int minimum, maximum;
7423
7424 if (!PyArg_ParseTuple(args,"II:rep_set_request", &minimum, &maximum))
7425 return NULL;
7426 CHECK_ENV_NOT_CLOSED(self);
7427
7428 MYDB_BEGIN_ALLOW_THREADS;
7429 err = self->db_env->rep_set_request(self->db_env, minimum, maximum);
7430 MYDB_END_ALLOW_THREADS;
7431 RETURN_IF_ERR();
7432 RETURN_NONE();
7433}
7434
7435static PyObject*
7436DBEnv_rep_get_request(DBEnvObject* self)
7437{
7438 int err;
7439 u_int32_t minimum, maximum;
7440
7441 CHECK_ENV_NOT_CLOSED(self);
7442 MYDB_BEGIN_ALLOW_THREADS;
7443 err = self->db_env->rep_get_request(self->db_env, &minimum, &maximum);
7444 MYDB_END_ALLOW_THREADS;
7445 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007446 return Py_BuildValue("II", minimum, maximum);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007447}
7448#endif
7449
7450#if (DBVER >= 45)
7451static PyObject*
7452DBEnv_rep_set_limit(DBEnvObject* self, PyObject* args)
7453{
7454 int err;
7455 int limit;
7456
7457 if (!PyArg_ParseTuple(args,"i:rep_set_limit", &limit))
7458 return NULL;
7459 CHECK_ENV_NOT_CLOSED(self);
7460
7461 MYDB_BEGIN_ALLOW_THREADS;
7462 err = self->db_env->rep_set_limit(self->db_env, 0, limit);
7463 MYDB_END_ALLOW_THREADS;
7464 RETURN_IF_ERR();
7465 RETURN_NONE();
7466}
7467
7468static PyObject*
7469DBEnv_rep_get_limit(DBEnvObject* self)
7470{
7471 int err;
7472 u_int32_t gbytes, bytes;
7473
7474 CHECK_ENV_NOT_CLOSED(self);
7475 MYDB_BEGIN_ALLOW_THREADS;
7476 err = self->db_env->rep_get_limit(self->db_env, &gbytes, &bytes);
7477 MYDB_END_ALLOW_THREADS;
7478 RETURN_IF_ERR();
7479 return NUMBER_FromLong(bytes);
7480}
7481#endif
7482
7483#if (DBVER >= 44)
7484static PyObject*
7485DBEnv_rep_set_config(DBEnvObject* self, PyObject* args)
7486{
7487 int err;
7488 int which;
7489 int onoff;
7490
7491 if (!PyArg_ParseTuple(args,"ii:rep_set_config", &which, &onoff))
7492 return NULL;
7493 CHECK_ENV_NOT_CLOSED(self);
7494
7495 MYDB_BEGIN_ALLOW_THREADS;
7496 err = self->db_env->rep_set_config(self->db_env, which, onoff);
7497 MYDB_END_ALLOW_THREADS;
7498 RETURN_IF_ERR();
7499 RETURN_NONE();
7500}
7501
7502static PyObject*
7503DBEnv_rep_get_config(DBEnvObject* self, PyObject* args)
7504{
7505 int err;
7506 int which;
7507 int onoff;
7508
7509 if (!PyArg_ParseTuple(args, "i:rep_get_config", &which)) {
7510 return NULL;
7511 }
7512 CHECK_ENV_NOT_CLOSED(self);
7513 MYDB_BEGIN_ALLOW_THREADS;
7514 err = self->db_env->rep_get_config(self->db_env, which, &onoff);
7515 MYDB_END_ALLOW_THREADS;
7516 RETURN_IF_ERR();
7517 return PyBool_FromLong(onoff);
7518}
7519#endif
7520
7521#if (DBVER >= 46)
7522static PyObject*
7523DBEnv_rep_elect(DBEnvObject* self, PyObject* args)
7524{
7525 int err;
7526 u_int32_t nsites, nvotes;
7527
7528 if (!PyArg_ParseTuple(args, "II:rep_elect", &nsites, &nvotes)) {
7529 return NULL;
7530 }
7531 CHECK_ENV_NOT_CLOSED(self);
7532 MYDB_BEGIN_ALLOW_THREADS;
Jesus Cea2ab4a912012-01-16 23:57:34 +01007533 err = self->db_env->rep_elect(self->db_env, nsites, nvotes, 0);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007534 MYDB_END_ALLOW_THREADS;
7535 RETURN_IF_ERR();
7536 RETURN_NONE();
7537}
7538#endif
7539
7540static PyObject*
7541DBEnv_rep_start(DBEnvObject* self, PyObject* args, PyObject* kwargs)
7542{
7543 int err;
7544 PyObject *cdata_py = Py_None;
7545 DBT cdata;
7546 int flags;
7547 static char* kwnames[] = {"flags","cdata", NULL};
7548
7549 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
7550 "i|O:rep_start", kwnames, &flags, &cdata_py))
7551 {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00007552 return NULL;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007553 }
7554 CHECK_ENV_NOT_CLOSED(self);
7555
7556 if (!make_dbt(cdata_py, &cdata))
7557 return NULL;
7558
7559 MYDB_BEGIN_ALLOW_THREADS;
7560 err = self->db_env->rep_start(self->db_env, cdata.size ? &cdata : NULL,
7561 flags);
7562 MYDB_END_ALLOW_THREADS;
7563 RETURN_IF_ERR();
7564 RETURN_NONE();
7565}
7566
7567#if (DBVER >= 44)
7568static PyObject*
7569DBEnv_rep_sync(DBEnvObject* self)
7570{
7571 int err;
7572
7573 CHECK_ENV_NOT_CLOSED(self);
7574 MYDB_BEGIN_ALLOW_THREADS;
7575 err = self->db_env->rep_sync(self->db_env, 0);
7576 MYDB_END_ALLOW_THREADS;
7577 RETURN_IF_ERR();
7578 RETURN_NONE();
7579}
7580#endif
7581
7582
Jesus Ceaef9764f2008-05-13 18:45:46 +00007583#if (DBVER >= 45)
7584static PyObject*
7585DBEnv_rep_set_nsites(DBEnvObject* self, PyObject* args)
7586{
7587 int err;
7588 int nsites;
7589
7590 if (!PyArg_ParseTuple(args, "i:rep_set_nsites", &nsites)) {
7591 return NULL;
7592 }
7593 CHECK_ENV_NOT_CLOSED(self);
7594 MYDB_BEGIN_ALLOW_THREADS;
7595 err = self->db_env->rep_set_nsites(self->db_env, nsites);
7596 MYDB_END_ALLOW_THREADS;
7597 RETURN_IF_ERR();
7598 RETURN_NONE();
7599}
7600
7601static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007602DBEnv_rep_get_nsites(DBEnvObject* self)
Jesus Ceaef9764f2008-05-13 18:45:46 +00007603{
7604 int err;
Jesus Ceaca3939c2008-05-22 15:27:38 +00007605#if (DBVER >= 47)
7606 u_int32_t nsites;
7607#else
Jesus Ceaef9764f2008-05-13 18:45:46 +00007608 int nsites;
Jesus Ceaca3939c2008-05-22 15:27:38 +00007609#endif
Jesus Ceaef9764f2008-05-13 18:45:46 +00007610
Jesus Ceaef9764f2008-05-13 18:45:46 +00007611 CHECK_ENV_NOT_CLOSED(self);
7612 MYDB_BEGIN_ALLOW_THREADS;
7613 err = self->db_env->rep_get_nsites(self->db_env, &nsites);
7614 MYDB_END_ALLOW_THREADS;
7615 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007616 return NUMBER_FromLong(nsites);
Jesus Ceaef9764f2008-05-13 18:45:46 +00007617}
7618
7619static PyObject*
7620DBEnv_rep_set_priority(DBEnvObject* self, PyObject* args)
7621{
7622 int err;
7623 int priority;
7624
7625 if (!PyArg_ParseTuple(args, "i:rep_set_priority", &priority)) {
7626 return NULL;
7627 }
7628 CHECK_ENV_NOT_CLOSED(self);
7629 MYDB_BEGIN_ALLOW_THREADS;
7630 err = self->db_env->rep_set_priority(self->db_env, priority);
7631 MYDB_END_ALLOW_THREADS;
7632 RETURN_IF_ERR();
7633 RETURN_NONE();
7634}
7635
7636static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007637DBEnv_rep_get_priority(DBEnvObject* self)
Jesus Ceaef9764f2008-05-13 18:45:46 +00007638{
7639 int err;
Jesus Ceaca3939c2008-05-22 15:27:38 +00007640#if (DBVER >= 47)
7641 u_int32_t priority;
7642#else
Jesus Ceaef9764f2008-05-13 18:45:46 +00007643 int priority;
Jesus Ceaca3939c2008-05-22 15:27:38 +00007644#endif
Jesus Ceaef9764f2008-05-13 18:45:46 +00007645
Jesus Ceaef9764f2008-05-13 18:45:46 +00007646 CHECK_ENV_NOT_CLOSED(self);
7647 MYDB_BEGIN_ALLOW_THREADS;
7648 err = self->db_env->rep_get_priority(self->db_env, &priority);
7649 MYDB_END_ALLOW_THREADS;
7650 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007651 return NUMBER_FromLong(priority);
Jesus Ceaef9764f2008-05-13 18:45:46 +00007652}
7653
7654static PyObject*
7655DBEnv_rep_set_timeout(DBEnvObject* self, PyObject* args)
7656{
7657 int err;
7658 int which, timeout;
7659
7660 if (!PyArg_ParseTuple(args, "ii:rep_set_timeout", &which, &timeout)) {
7661 return NULL;
7662 }
7663 CHECK_ENV_NOT_CLOSED(self);
7664 MYDB_BEGIN_ALLOW_THREADS;
7665 err = self->db_env->rep_set_timeout(self->db_env, which, timeout);
7666 MYDB_END_ALLOW_THREADS;
7667 RETURN_IF_ERR();
7668 RETURN_NONE();
7669}
7670
7671static PyObject*
7672DBEnv_rep_get_timeout(DBEnvObject* self, PyObject* args)
7673{
7674 int err;
7675 int which;
7676 u_int32_t timeout;
7677
7678 if (!PyArg_ParseTuple(args, "i:rep_get_timeout", &which)) {
7679 return NULL;
7680 }
7681 CHECK_ENV_NOT_CLOSED(self);
7682 MYDB_BEGIN_ALLOW_THREADS;
7683 err = self->db_env->rep_get_timeout(self->db_env, which, &timeout);
7684 MYDB_END_ALLOW_THREADS;
7685 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007686 return NUMBER_FromLong(timeout);
Jesus Ceaef9764f2008-05-13 18:45:46 +00007687}
7688#endif
7689
Jesus Cea6557aac2010-03-22 14:22:26 +00007690
7691#if (DBVER >= 47)
7692static PyObject*
7693DBEnv_rep_set_clockskew(DBEnvObject* self, PyObject* args)
7694{
7695 int err;
7696 unsigned int fast, slow;
7697
Jesus Cea6557aac2010-03-22 14:22:26 +00007698 if (!PyArg_ParseTuple(args,"II:rep_set_clockskew", &fast, &slow))
7699 return NULL;
Jesus Cea6557aac2010-03-22 14:22:26 +00007700
7701 CHECK_ENV_NOT_CLOSED(self);
7702
7703 MYDB_BEGIN_ALLOW_THREADS;
7704 err = self->db_env->rep_set_clockskew(self->db_env, fast, slow);
7705 MYDB_END_ALLOW_THREADS;
7706 RETURN_IF_ERR();
7707 RETURN_NONE();
7708}
7709
7710static PyObject*
7711DBEnv_rep_get_clockskew(DBEnvObject* self)
7712{
7713 int err;
7714 unsigned int fast, slow;
7715
7716 CHECK_ENV_NOT_CLOSED(self);
7717 MYDB_BEGIN_ALLOW_THREADS;
7718 err = self->db_env->rep_get_clockskew(self->db_env, &fast, &slow);
7719 MYDB_END_ALLOW_THREADS;
7720 RETURN_IF_ERR();
Jesus Cea6557aac2010-03-22 14:22:26 +00007721 return Py_BuildValue("(II)", fast, slow);
Jesus Cea6557aac2010-03-22 14:22:26 +00007722}
7723#endif
7724
Jesus Cea6557aac2010-03-22 14:22:26 +00007725static PyObject*
7726DBEnv_rep_stat_print(DBEnvObject* self, PyObject* args, PyObject *kwargs)
7727{
7728 int err;
7729 int flags=0;
7730 static char* kwnames[] = { "flags", NULL };
7731
7732 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:rep_stat_print",
7733 kwnames, &flags))
7734 {
7735 return NULL;
7736 }
7737 CHECK_ENV_NOT_CLOSED(self);
7738 MYDB_BEGIN_ALLOW_THREADS;
7739 err = self->db_env->rep_stat_print(self->db_env, flags);
7740 MYDB_END_ALLOW_THREADS;
7741 RETURN_IF_ERR();
7742 RETURN_NONE();
7743}
Jesus Cea6557aac2010-03-22 14:22:26 +00007744
7745static PyObject*
7746DBEnv_rep_stat(DBEnvObject* self, PyObject* args, PyObject *kwargs)
7747{
7748 int err;
7749 int flags=0;
7750 DB_REP_STAT *statp;
7751 PyObject *stats;
7752 static char* kwnames[] = { "flags", NULL };
7753
7754 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:rep_stat",
7755 kwnames, &flags))
7756 {
7757 return NULL;
7758 }
7759 CHECK_ENV_NOT_CLOSED(self);
7760 MYDB_BEGIN_ALLOW_THREADS;
7761 err = self->db_env->rep_stat(self->db_env, &statp, flags);
7762 MYDB_END_ALLOW_THREADS;
7763 RETURN_IF_ERR();
7764
7765 stats=PyDict_New();
7766 if (stats == NULL) {
7767 free(statp);
7768 return NULL;
7769 }
7770
7771#define MAKE_ENTRY(name) _addIntToDict(stats, #name, statp->st_##name)
7772#define MAKE_DB_LSN_ENTRY(name) _addDB_lsnToDict(stats , #name, statp->st_##name)
7773
7774#if (DBVER >= 44)
7775 MAKE_ENTRY(bulk_fills);
7776 MAKE_ENTRY(bulk_overflows);
7777 MAKE_ENTRY(bulk_records);
7778 MAKE_ENTRY(bulk_transfers);
7779 MAKE_ENTRY(client_rerequests);
7780 MAKE_ENTRY(client_svc_miss);
7781 MAKE_ENTRY(client_svc_req);
7782#endif
7783 MAKE_ENTRY(dupmasters);
Jesus Cea6557aac2010-03-22 14:22:26 +00007784 MAKE_ENTRY(egen);
7785 MAKE_ENTRY(election_nvotes);
7786 MAKE_ENTRY(startup_complete);
7787 MAKE_ENTRY(pg_duplicated);
7788 MAKE_ENTRY(pg_records);
7789 MAKE_ENTRY(pg_requested);
7790 MAKE_ENTRY(next_pg);
7791 MAKE_ENTRY(waiting_pg);
Jesus Cea6557aac2010-03-22 14:22:26 +00007792 MAKE_ENTRY(election_cur_winner);
7793 MAKE_ENTRY(election_gen);
7794 MAKE_DB_LSN_ENTRY(election_lsn);
7795 MAKE_ENTRY(election_nsites);
7796 MAKE_ENTRY(election_priority);
7797#if (DBVER >= 44)
7798 MAKE_ENTRY(election_sec);
7799 MAKE_ENTRY(election_usec);
7800#endif
7801 MAKE_ENTRY(election_status);
7802 MAKE_ENTRY(election_tiebreaker);
7803 MAKE_ENTRY(election_votes);
7804 MAKE_ENTRY(elections);
7805 MAKE_ENTRY(elections_won);
7806 MAKE_ENTRY(env_id);
7807 MAKE_ENTRY(env_priority);
7808 MAKE_ENTRY(gen);
7809 MAKE_ENTRY(log_duplicated);
7810 MAKE_ENTRY(log_queued);
7811 MAKE_ENTRY(log_queued_max);
7812 MAKE_ENTRY(log_queued_total);
7813 MAKE_ENTRY(log_records);
7814 MAKE_ENTRY(log_requested);
7815 MAKE_ENTRY(master);
7816 MAKE_ENTRY(master_changes);
7817#if (DBVER >= 47)
7818 MAKE_ENTRY(max_lease_sec);
7819 MAKE_ENTRY(max_lease_usec);
7820 MAKE_DB_LSN_ENTRY(max_perm_lsn);
7821#endif
7822 MAKE_ENTRY(msgs_badgen);
7823 MAKE_ENTRY(msgs_processed);
7824 MAKE_ENTRY(msgs_recover);
7825 MAKE_ENTRY(msgs_send_failures);
7826 MAKE_ENTRY(msgs_sent);
7827 MAKE_ENTRY(newsites);
7828 MAKE_DB_LSN_ENTRY(next_lsn);
7829 MAKE_ENTRY(nsites);
7830 MAKE_ENTRY(nthrottles);
7831 MAKE_ENTRY(outdated);
7832#if (DBVER >= 46)
7833 MAKE_ENTRY(startsync_delayed);
7834#endif
7835 MAKE_ENTRY(status);
7836 MAKE_ENTRY(txns_applied);
7837 MAKE_DB_LSN_ENTRY(waiting_lsn);
7838
7839#undef MAKE_DB_LSN_ENTRY
7840#undef MAKE_ENTRY
7841
7842 free(statp);
7843 return stats;
7844}
7845
Jesus Ceaef9764f2008-05-13 18:45:46 +00007846/* --------------------------------------------------------------------- */
7847/* REPLICATION METHODS: Replication Manager */
7848
7849#if (DBVER >= 45)
7850static PyObject*
7851DBEnv_repmgr_start(DBEnvObject* self, PyObject* args, PyObject*
7852 kwargs)
7853{
7854 int err;
7855 int nthreads, flags;
7856 static char* kwnames[] = {"nthreads","flags", NULL};
7857
7858 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
7859 "ii:repmgr_start", kwnames, &nthreads, &flags))
7860 {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00007861 return NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00007862 }
7863 CHECK_ENV_NOT_CLOSED(self);
7864 MYDB_BEGIN_ALLOW_THREADS;
7865 err = self->db_env->repmgr_start(self->db_env, nthreads, flags);
7866 MYDB_END_ALLOW_THREADS;
7867 RETURN_IF_ERR();
7868 RETURN_NONE();
7869}
7870
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07007871#if (DBVER < 52)
Jesus Ceaef9764f2008-05-13 18:45:46 +00007872static PyObject*
7873DBEnv_repmgr_set_local_site(DBEnvObject* self, PyObject* args, PyObject*
7874 kwargs)
7875{
7876 int err;
7877 char *host;
7878 int port;
7879 int flags = 0;
7880 static char* kwnames[] = {"host", "port", "flags", NULL};
7881
7882 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
7883 "si|i:repmgr_set_local_site", kwnames, &host, &port, &flags))
7884 {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00007885 return NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00007886 }
7887 CHECK_ENV_NOT_CLOSED(self);
7888 MYDB_BEGIN_ALLOW_THREADS;
7889 err = self->db_env->repmgr_set_local_site(self->db_env, host, port, flags);
7890 MYDB_END_ALLOW_THREADS;
7891 RETURN_IF_ERR();
7892 RETURN_NONE();
7893}
7894
7895static PyObject*
7896DBEnv_repmgr_add_remote_site(DBEnvObject* self, PyObject* args, PyObject*
7897 kwargs)
7898{
7899 int err;
7900 char *host;
7901 int port;
7902 int flags = 0;
7903 int eidp;
7904 static char* kwnames[] = {"host", "port", "flags", NULL};
7905
7906 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
7907 "si|i:repmgr_add_remote_site", kwnames, &host, &port, &flags))
7908 {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00007909 return NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00007910 }
7911 CHECK_ENV_NOT_CLOSED(self);
7912 MYDB_BEGIN_ALLOW_THREADS;
7913 err = self->db_env->repmgr_add_remote_site(self->db_env, host, port, &eidp, flags);
7914 MYDB_END_ALLOW_THREADS;
7915 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007916 return NUMBER_FromLong(eidp);
Jesus Ceaef9764f2008-05-13 18:45:46 +00007917}
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07007918#endif
Jesus Ceaef9764f2008-05-13 18:45:46 +00007919
7920static PyObject*
7921DBEnv_repmgr_set_ack_policy(DBEnvObject* self, PyObject* args)
7922{
7923 int err;
7924 int ack_policy;
7925
7926 if (!PyArg_ParseTuple(args, "i:repmgr_set_ack_policy", &ack_policy))
7927 {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00007928 return NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00007929 }
7930 CHECK_ENV_NOT_CLOSED(self);
7931 MYDB_BEGIN_ALLOW_THREADS;
7932 err = self->db_env->repmgr_set_ack_policy(self->db_env, ack_policy);
7933 MYDB_END_ALLOW_THREADS;
7934 RETURN_IF_ERR();
7935 RETURN_NONE();
7936}
7937
7938static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007939DBEnv_repmgr_get_ack_policy(DBEnvObject* self)
Jesus Ceaef9764f2008-05-13 18:45:46 +00007940{
7941 int err;
7942 int ack_policy;
7943
Jesus Ceaef9764f2008-05-13 18:45:46 +00007944 CHECK_ENV_NOT_CLOSED(self);
7945 MYDB_BEGIN_ALLOW_THREADS;
7946 err = self->db_env->repmgr_get_ack_policy(self->db_env, &ack_policy);
7947 MYDB_END_ALLOW_THREADS;
7948 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007949 return NUMBER_FromLong(ack_policy);
Jesus Ceaef9764f2008-05-13 18:45:46 +00007950}
7951
7952static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007953DBEnv_repmgr_site_list(DBEnvObject* self)
Jesus Ceaef9764f2008-05-13 18:45:46 +00007954{
7955 int err;
7956 unsigned int countp;
7957 DB_REPMGR_SITE *listp;
7958 PyObject *stats, *key, *tuple;
7959
Jesus Ceaef9764f2008-05-13 18:45:46 +00007960 CHECK_ENV_NOT_CLOSED(self);
7961 MYDB_BEGIN_ALLOW_THREADS;
7962 err = self->db_env->repmgr_site_list(self->db_env, &countp, &listp);
7963 MYDB_END_ALLOW_THREADS;
7964 RETURN_IF_ERR();
7965
7966 stats=PyDict_New();
7967 if (stats == NULL) {
7968 free(listp);
7969 return NULL;
7970 }
7971
7972 for(;countp--;) {
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007973 key=NUMBER_FromLong(listp[countp].eid);
Jesus Ceaef9764f2008-05-13 18:45:46 +00007974 if(!key) {
7975 Py_DECREF(stats);
7976 free(listp);
7977 return NULL;
7978 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00007979 tuple=Py_BuildValue("(sII)", listp[countp].host,
7980 listp[countp].port, listp[countp].status);
Jesus Ceaef9764f2008-05-13 18:45:46 +00007981 if(!tuple) {
7982 Py_DECREF(key);
7983 Py_DECREF(stats);
7984 free(listp);
7985 return NULL;
7986 }
7987 if(PyDict_SetItem(stats, key, tuple)) {
7988 Py_DECREF(key);
7989 Py_DECREF(tuple);
7990 Py_DECREF(stats);
7991 free(listp);
7992 return NULL;
7993 }
Florent Xiclunae7901c52010-03-01 20:45:01 +00007994 Py_DECREF(key);
7995 Py_DECREF(tuple);
Jesus Ceaef9764f2008-05-13 18:45:46 +00007996 }
7997 free(listp);
7998 return stats;
7999}
8000#endif
8001
8002#if (DBVER >= 46)
8003static PyObject*
8004DBEnv_repmgr_stat_print(DBEnvObject* self, PyObject* args, PyObject *kwargs)
8005{
8006 int err;
8007 int flags=0;
8008 static char* kwnames[] = { "flags", NULL };
8009
8010 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:repmgr_stat_print",
8011 kwnames, &flags))
8012 {
8013 return NULL;
8014 }
8015 CHECK_ENV_NOT_CLOSED(self);
8016 MYDB_BEGIN_ALLOW_THREADS;
8017 err = self->db_env->repmgr_stat_print(self->db_env, flags);
8018 MYDB_END_ALLOW_THREADS;
8019 RETURN_IF_ERR();
8020 RETURN_NONE();
8021}
8022
8023static PyObject*
8024DBEnv_repmgr_stat(DBEnvObject* self, PyObject* args, PyObject *kwargs)
8025{
8026 int err;
8027 int flags=0;
8028 DB_REPMGR_STAT *statp;
8029 PyObject *stats;
8030 static char* kwnames[] = { "flags", NULL };
8031
8032 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:repmgr_stat",
8033 kwnames, &flags))
8034 {
8035 return NULL;
8036 }
8037 CHECK_ENV_NOT_CLOSED(self);
8038 MYDB_BEGIN_ALLOW_THREADS;
8039 err = self->db_env->repmgr_stat(self->db_env, &statp, flags);
8040 MYDB_END_ALLOW_THREADS;
8041 RETURN_IF_ERR();
8042
8043 stats=PyDict_New();
8044 if (stats == NULL) {
8045 free(statp);
8046 return NULL;
8047 }
8048
8049#define MAKE_ENTRY(name) _addIntToDict(stats, #name, statp->st_##name)
8050
8051 MAKE_ENTRY(perm_failed);
8052 MAKE_ENTRY(msgs_queued);
8053 MAKE_ENTRY(msgs_dropped);
8054 MAKE_ENTRY(connection_drop);
8055 MAKE_ENTRY(connect_fail);
8056
8057#undef MAKE_ENTRY
8058
8059 free(statp);
8060 return stats;
8061}
8062#endif
8063
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008064
8065/* --------------------------------------------------------------------- */
8066/* DBTxn methods */
8067
8068
Jesus Ceaef9764f2008-05-13 18:45:46 +00008069static void _close_transaction_cursors(DBTxnObject* txn)
8070{
8071 PyObject *dummy;
8072
8073 while(txn->children_cursors) {
8074 PyErr_Warn(PyExc_RuntimeWarning,
8075 "Must close cursors before resolving a transaction.");
8076 dummy=DBC_close_internal(txn->children_cursors);
8077 Py_XDECREF(dummy);
8078 }
8079}
8080
8081static void _promote_transaction_dbs_and_sequences(DBTxnObject *txn)
8082{
8083 DBObject *db;
Jesus Ceaef9764f2008-05-13 18:45:46 +00008084 DBSequenceObject *dbs;
Jesus Ceaef9764f2008-05-13 18:45:46 +00008085
8086 while (txn->children_dbs) {
8087 db=txn->children_dbs;
8088 EXTRACT_FROM_DOUBLE_LINKED_LIST_TXN(db);
8089 if (txn->parent_txn) {
8090 INSERT_IN_DOUBLE_LINKED_LIST_TXN(txn->parent_txn->children_dbs,db);
8091 db->txn=txn->parent_txn;
8092 } else {
8093 /* The db is already linked to its environment,
8094 ** so nothing to do.
8095 */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00008096 db->txn=NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00008097 }
8098 }
8099
Jesus Ceaef9764f2008-05-13 18:45:46 +00008100 while (txn->children_sequences) {
8101 dbs=txn->children_sequences;
8102 EXTRACT_FROM_DOUBLE_LINKED_LIST_TXN(dbs);
8103 if (txn->parent_txn) {
8104 INSERT_IN_DOUBLE_LINKED_LIST_TXN(txn->parent_txn->children_sequences,dbs);
8105 dbs->txn=txn->parent_txn;
8106 } else {
8107 /* The sequence is already linked to its
8108 ** parent db. Nothing to do.
8109 */
8110 dbs->txn=NULL;
8111 }
8112 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00008113}
8114
8115
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008116static PyObject*
8117DBTxn_commit(DBTxnObject* self, PyObject* args)
8118{
8119 int flags=0, err;
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008120 DB_TXN *txn;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008121
8122 if (!PyArg_ParseTuple(args, "|i:commit", &flags))
8123 return NULL;
8124
Jesus Ceaef9764f2008-05-13 18:45:46 +00008125 _close_transaction_cursors(self);
8126
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008127 if (!self->txn) {
Thomas Woutersb3153832006-03-08 01:47:19 +00008128 PyObject *t = Py_BuildValue("(is)", 0, "DBTxn must not be used "
Jesus Ceaef9764f2008-05-13 18:45:46 +00008129 "after txn_commit, txn_abort "
8130 "or txn_discard");
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008131 if (t) {
8132 PyErr_SetObject(DBError, t);
8133 Py_DECREF(t);
8134 }
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008135 return NULL;
8136 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00008137 self->flag_prepare=0;
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008138 txn = self->txn;
8139 self->txn = NULL; /* this DB_TXN is no longer valid after this call */
Jesus Ceaef9764f2008-05-13 18:45:46 +00008140
8141 EXTRACT_FROM_DOUBLE_LINKED_LIST(self);
8142
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008143 MYDB_BEGIN_ALLOW_THREADS;
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008144 err = txn->commit(txn, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008145 MYDB_END_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00008146
8147 _promote_transaction_dbs_and_sequences(self);
8148
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008149 RETURN_IF_ERR();
8150 RETURN_NONE();
8151}
8152
8153static PyObject*
8154DBTxn_prepare(DBTxnObject* self, PyObject* args)
8155{
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008156 int err;
8157 char* gid=NULL;
8158 int gid_size=0;
8159
8160 if (!PyArg_ParseTuple(args, "s#:prepare", &gid, &gid_size))
8161 return NULL;
8162
Matthias Klose54cc5392010-03-15 12:46:18 +00008163 if (gid_size != DB_GID_SIZE) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008164 PyErr_SetString(PyExc_TypeError,
Matthias Klose54cc5392010-03-15 12:46:18 +00008165 "gid must be DB_GID_SIZE bytes long");
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008166 return NULL;
8167 }
8168
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008169 if (!self->txn) {
Thomas Woutersb3153832006-03-08 01:47:19 +00008170 PyObject *t = Py_BuildValue("(is)", 0,"DBTxn must not be used "
Jesus Ceaef9764f2008-05-13 18:45:46 +00008171 "after txn_commit, txn_abort "
8172 "or txn_discard");
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008173 if (t) {
8174 PyErr_SetObject(DBError, t);
8175 Py_DECREF(t);
8176 }
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008177 return NULL;
8178 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00008179 self->flag_prepare=1; /* Prepare state */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008180 MYDB_BEGIN_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008181 err = self->txn->prepare(self->txn, (u_int8_t*)gid);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008182 MYDB_END_ALLOW_THREADS;
8183 RETURN_IF_ERR();
8184 RETURN_NONE();
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008185}
8186
8187
8188static PyObject*
Jesus Ceaef9764f2008-05-13 18:45:46 +00008189DBTxn_abort_discard_internal(DBTxnObject* self, int discard)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008190{
Jesus Ceaef9764f2008-05-13 18:45:46 +00008191 PyObject *dummy;
8192 int err=0;
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008193 DB_TXN *txn;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008194
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008195 if (!self->txn) {
Thomas Woutersb3153832006-03-08 01:47:19 +00008196 PyObject *t = Py_BuildValue("(is)", 0, "DBTxn must not be used "
Jesus Ceaef9764f2008-05-13 18:45:46 +00008197 "after txn_commit, txn_abort "
8198 "or txn_discard");
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008199 if (t) {
8200 PyErr_SetObject(DBError, t);
8201 Py_DECREF(t);
8202 }
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008203 return NULL;
8204 }
8205 txn = self->txn;
8206 self->txn = NULL; /* this DB_TXN is no longer valid after this call */
Jesus Ceaef9764f2008-05-13 18:45:46 +00008207
8208 _close_transaction_cursors(self);
Jesus Ceaef9764f2008-05-13 18:45:46 +00008209 while (self->children_sequences) {
8210 dummy=DBSequence_close_internal(self->children_sequences,0,0);
8211 Py_XDECREF(dummy);
8212 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00008213 while (self->children_dbs) {
Jesus Cea5cd5f122008-09-23 18:54:08 +00008214 dummy=DB_close_internal(self->children_dbs, 0, 0);
Jesus Ceaef9764f2008-05-13 18:45:46 +00008215 Py_XDECREF(dummy);
8216 }
8217
8218 EXTRACT_FROM_DOUBLE_LINKED_LIST(self);
8219
8220 MYDB_BEGIN_ALLOW_THREADS;
8221 if (discard) {
8222 assert(!self->flag_prepare);
Jesus Ceaef9764f2008-05-13 18:45:46 +00008223 err = txn->discard(txn,0);
Jesus Ceaef9764f2008-05-13 18:45:46 +00008224 } else {
8225 /*
8226 ** If the transaction is in the "prepare" or "recover" state,
8227 ** we better do not implicitly abort it.
8228 */
8229 if (!self->flag_prepare) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00008230 err = txn->abort(txn);
Jesus Ceaef9764f2008-05-13 18:45:46 +00008231 }
8232 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008233 MYDB_END_ALLOW_THREADS;
8234 RETURN_IF_ERR();
8235 RETURN_NONE();
8236}
8237
Jesus Ceaef9764f2008-05-13 18:45:46 +00008238static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008239DBTxn_abort(DBTxnObject* self)
Jesus Ceaef9764f2008-05-13 18:45:46 +00008240{
Jesus Ceaef9764f2008-05-13 18:45:46 +00008241 self->flag_prepare=0;
8242 _close_transaction_cursors(self);
8243
8244 return DBTxn_abort_discard_internal(self,0);
8245}
8246
8247static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008248DBTxn_discard(DBTxnObject* self)
Jesus Ceaef9764f2008-05-13 18:45:46 +00008249{
Jesus Ceaef9764f2008-05-13 18:45:46 +00008250 self->flag_prepare=0;
8251 _close_transaction_cursors(self);
8252
8253 return DBTxn_abort_discard_internal(self,1);
8254}
8255
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008256
8257static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008258DBTxn_id(DBTxnObject* self)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008259{
8260 int id;
8261
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008262 if (!self->txn) {
Thomas Woutersb3153832006-03-08 01:47:19 +00008263 PyObject *t = Py_BuildValue("(is)", 0, "DBTxn must not be used "
Jesus Ceaef9764f2008-05-13 18:45:46 +00008264 "after txn_commit, txn_abort "
8265 "or txn_discard");
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008266 if (t) {
8267 PyErr_SetObject(DBError, t);
8268 Py_DECREF(t);
8269 }
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008270 return NULL;
8271 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008272 MYDB_BEGIN_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008273 id = self->txn->id(self->txn);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008274 MYDB_END_ALLOW_THREADS;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008275 return NUMBER_FromLong(id);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008276}
8277
Jesus Cea6557aac2010-03-22 14:22:26 +00008278
8279static PyObject*
8280DBTxn_set_timeout(DBTxnObject* self, PyObject* args, PyObject* kwargs)
8281{
8282 int err;
8283 u_int32_t flags=0;
8284 u_int32_t timeout = 0;
8285 static char* kwnames[] = { "timeout", "flags", NULL };
8286
8287 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ii:set_timeout", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00008288 &timeout, &flags)) {
8289 return NULL;
Jesus Cea6557aac2010-03-22 14:22:26 +00008290 }
8291
8292 MYDB_BEGIN_ALLOW_THREADS;
8293 err = self->txn->set_timeout(self->txn, (db_timeout_t)timeout, flags);
8294 MYDB_END_ALLOW_THREADS;
8295
8296 RETURN_IF_ERR();
8297 RETURN_NONE();
8298}
8299
8300
8301#if (DBVER >= 44)
8302static PyObject*
8303DBTxn_set_name(DBTxnObject* self, PyObject* args)
8304{
8305 int err;
8306 const char *name;
8307
8308 if (!PyArg_ParseTuple(args, "s:set_name", &name))
8309 return NULL;
8310
8311 MYDB_BEGIN_ALLOW_THREADS;
8312 err = self->txn->set_name(self->txn, name);
8313 MYDB_END_ALLOW_THREADS;
8314
8315 RETURN_IF_ERR();
8316 RETURN_NONE();
8317}
8318#endif
8319
8320
8321#if (DBVER >= 44)
8322static PyObject*
8323DBTxn_get_name(DBTxnObject* self)
8324{
8325 int err;
8326 const char *name;
8327
8328 MYDB_BEGIN_ALLOW_THREADS;
8329 err = self->txn->get_name(self->txn, &name);
8330 MYDB_END_ALLOW_THREADS;
8331
8332 RETURN_IF_ERR();
8333#if (PY_VERSION_HEX < 0x03000000)
8334 if (!name) {
8335 return PyString_FromString("");
8336 }
8337 return PyString_FromString(name);
8338#else
8339 if (!name) {
8340 return PyUnicode_FromString("");
8341 }
8342 return PyUnicode_FromString(name);
8343#endif
8344}
8345#endif
8346
8347
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008348/* --------------------------------------------------------------------- */
8349/* DBSequence methods */
8350
8351
8352static PyObject*
Jesus Ceaef9764f2008-05-13 18:45:46 +00008353DBSequence_close_internal(DBSequenceObject* self, int flags, int do_not_close)
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008354{
Jesus Ceaef9764f2008-05-13 18:45:46 +00008355 int err=0;
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008356
Jesus Ceaef9764f2008-05-13 18:45:46 +00008357 if (self->sequence!=NULL) {
8358 EXTRACT_FROM_DOUBLE_LINKED_LIST(self);
8359 if (self->txn) {
8360 EXTRACT_FROM_DOUBLE_LINKED_LIST_TXN(self);
8361 self->txn=NULL;
8362 }
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008363
Jesus Cea5cd5f122008-09-23 18:54:08 +00008364 /*
8365 ** "do_not_close" is used to dispose all related objects in the
8366 ** tree, without actually releasing the "root" object.
8367 ** This is done, for example, because function calls like
8368 ** "DBSequence.remove()" implicitly close the underlying handle. So
8369 ** the handle doesn't need to be closed, but related objects
8370 ** must be cleaned up.
8371 */
Jesus Ceaef9764f2008-05-13 18:45:46 +00008372 if (!do_not_close) {
8373 MYDB_BEGIN_ALLOW_THREADS
8374 err = self->sequence->close(self->sequence, flags);
8375 MYDB_END_ALLOW_THREADS
8376 }
8377 self->sequence = NULL;
8378
8379 RETURN_IF_ERR();
8380 }
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008381
8382 RETURN_NONE();
8383}
8384
8385static PyObject*
Jesus Ceaef9764f2008-05-13 18:45:46 +00008386DBSequence_close(DBSequenceObject* self, PyObject* args)
8387{
8388 int flags=0;
8389 if (!PyArg_ParseTuple(args,"|i:close", &flags))
8390 return NULL;
8391
8392 return DBSequence_close_internal(self,flags,0);
8393}
8394
8395static PyObject*
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008396DBSequence_get(DBSequenceObject* self, PyObject* args, PyObject* kwargs)
8397{
8398 int err, flags = 0;
8399 int delta = 1;
8400 db_seq_t value;
8401 PyObject *txnobj = NULL;
8402 DB_TXN *txn = NULL;
8403 static char* kwnames[] = {"delta", "txn", "flags", NULL };
8404 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|iOi:get", kwnames, &delta, &txnobj, &flags))
8405 return NULL;
8406 CHECK_SEQUENCE_NOT_CLOSED(self)
8407
8408 if (!checkTxnObj(txnobj, &txn))
8409 return NULL;
8410
8411 MYDB_BEGIN_ALLOW_THREADS
8412 err = self->sequence->get(self->sequence, txn, delta, &value, flags);
8413 MYDB_END_ALLOW_THREADS
8414
8415 RETURN_IF_ERR();
8416 return PyLong_FromLongLong(value);
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008417}
8418
8419static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008420DBSequence_get_dbp(DBSequenceObject* self)
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008421{
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008422 CHECK_SEQUENCE_NOT_CLOSED(self)
8423 Py_INCREF(self->mydb);
8424 return (PyObject* )self->mydb;
8425}
8426
8427static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008428DBSequence_get_key(DBSequenceObject* self)
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008429{
8430 int err;
8431 DBT key;
Neal Norwitz088beae2007-10-12 03:01:54 +00008432 PyObject *retval = NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00008433
Gregory P. Smithe70be5c2007-10-06 07:48:10 +00008434 key.flags = DB_DBT_MALLOC;
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008435 CHECK_SEQUENCE_NOT_CLOSED(self)
8436 MYDB_BEGIN_ALLOW_THREADS
8437 err = self->sequence->get_key(self->sequence, &key);
8438 MYDB_END_ALLOW_THREADS
8439
Gregory P. Smithe70be5c2007-10-06 07:48:10 +00008440 if (!err)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008441 retval = Build_PyString(key.data, key.size);
Gregory P. Smithe70be5c2007-10-06 07:48:10 +00008442
8443 FREE_DBT(key);
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008444 RETURN_IF_ERR();
8445
Gregory P. Smithe70be5c2007-10-06 07:48:10 +00008446 return retval;
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008447}
8448
8449static PyObject*
Jesus Cea6557aac2010-03-22 14:22:26 +00008450DBSequence_initial_value(DBSequenceObject* self, PyObject* args)
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008451{
8452 int err;
Jesus Ceaef9764f2008-05-13 18:45:46 +00008453 PY_LONG_LONG value;
8454 db_seq_t value2;
Jesus Cea6557aac2010-03-22 14:22:26 +00008455 if (!PyArg_ParseTuple(args,"L:initial_value", &value))
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008456 return NULL;
8457 CHECK_SEQUENCE_NOT_CLOSED(self)
8458
Jesus Ceaef9764f2008-05-13 18:45:46 +00008459 value2=value; /* If truncation, compiler should show a warning */
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008460 MYDB_BEGIN_ALLOW_THREADS
Jesus Ceaef9764f2008-05-13 18:45:46 +00008461 err = self->sequence->initial_value(self->sequence, value2);
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008462 MYDB_END_ALLOW_THREADS
8463
8464 RETURN_IF_ERR();
8465
8466 RETURN_NONE();
8467}
8468
8469static PyObject*
8470DBSequence_open(DBSequenceObject* self, PyObject* args, PyObject* kwargs)
8471{
8472 int err, flags = 0;
8473 PyObject* keyobj;
8474 PyObject *txnobj = NULL;
8475 DB_TXN *txn = NULL;
8476 DBT key;
8477
8478 static char* kwnames[] = {"key", "txn", "flags", NULL };
Neal Norwitzdd2a6bf2006-06-06 07:23:01 +00008479 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|Oi:open", kwnames, &keyobj, &txnobj, &flags))
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008480 return NULL;
8481
8482 if (!checkTxnObj(txnobj, &txn))
8483 return NULL;
8484
8485 if (!make_key_dbt(self->mydb, keyobj, &key, NULL))
8486 return NULL;
8487
8488 MYDB_BEGIN_ALLOW_THREADS
8489 err = self->sequence->open(self->sequence, txn, &key, flags);
8490 MYDB_END_ALLOW_THREADS
8491
Jesus Ceaac25fab2008-09-03 17:50:32 +00008492 FREE_DBT(key);
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008493 RETURN_IF_ERR();
8494
Jesus Ceaef9764f2008-05-13 18:45:46 +00008495 if (txn) {
8496 INSERT_IN_DOUBLE_LINKED_LIST_TXN(((DBTxnObject *)txnobj)->children_sequences,self);
8497 self->txn=(DBTxnObject *)txnobj;
8498 }
8499
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008500 RETURN_NONE();
8501}
8502
8503static PyObject*
8504DBSequence_remove(DBSequenceObject* self, PyObject* args, PyObject* kwargs)
8505{
Jesus Ceaef9764f2008-05-13 18:45:46 +00008506 PyObject *dummy;
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008507 int err, flags = 0;
8508 PyObject *txnobj = NULL;
8509 DB_TXN *txn = NULL;
8510
8511 static char* kwnames[] = {"txn", "flags", NULL };
Neal Norwitzdd2a6bf2006-06-06 07:23:01 +00008512 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Oi:remove", kwnames, &txnobj, &flags))
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008513 return NULL;
8514
8515 if (!checkTxnObj(txnobj, &txn))
8516 return NULL;
8517
8518 CHECK_SEQUENCE_NOT_CLOSED(self)
8519
8520 MYDB_BEGIN_ALLOW_THREADS
8521 err = self->sequence->remove(self->sequence, txn, flags);
8522 MYDB_END_ALLOW_THREADS
8523
Jesus Ceaef9764f2008-05-13 18:45:46 +00008524 dummy=DBSequence_close_internal(self,flags,1);
8525 Py_XDECREF(dummy);
8526
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008527 RETURN_IF_ERR();
8528 RETURN_NONE();
8529}
8530
8531static PyObject*
8532DBSequence_set_cachesize(DBSequenceObject* self, PyObject* args)
8533{
8534 int err, size;
Neal Norwitzdd2a6bf2006-06-06 07:23:01 +00008535 if (!PyArg_ParseTuple(args,"i:set_cachesize", &size))
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008536 return NULL;
8537 CHECK_SEQUENCE_NOT_CLOSED(self)
8538
8539 MYDB_BEGIN_ALLOW_THREADS
8540 err = self->sequence->set_cachesize(self->sequence, size);
8541 MYDB_END_ALLOW_THREADS
8542
8543 RETURN_IF_ERR();
8544 RETURN_NONE();
8545}
8546
8547static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008548DBSequence_get_cachesize(DBSequenceObject* self)
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008549{
8550 int err, size;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008551
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008552 CHECK_SEQUENCE_NOT_CLOSED(self)
8553
8554 MYDB_BEGIN_ALLOW_THREADS
8555 err = self->sequence->get_cachesize(self->sequence, &size);
8556 MYDB_END_ALLOW_THREADS
8557
8558 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008559 return NUMBER_FromLong(size);
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008560}
8561
8562static PyObject*
8563DBSequence_set_flags(DBSequenceObject* self, PyObject* args)
8564{
8565 int err, flags = 0;
Neal Norwitzdd2a6bf2006-06-06 07:23:01 +00008566 if (!PyArg_ParseTuple(args,"i:set_flags", &flags))
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008567 return NULL;
8568 CHECK_SEQUENCE_NOT_CLOSED(self)
8569
8570 MYDB_BEGIN_ALLOW_THREADS
8571 err = self->sequence->set_flags(self->sequence, flags);
8572 MYDB_END_ALLOW_THREADS
8573
8574 RETURN_IF_ERR();
8575 RETURN_NONE();
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008576}
8577
8578static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008579DBSequence_get_flags(DBSequenceObject* self)
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008580{
8581 unsigned int flags;
8582 int err;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008583
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008584 CHECK_SEQUENCE_NOT_CLOSED(self)
8585
8586 MYDB_BEGIN_ALLOW_THREADS
8587 err = self->sequence->get_flags(self->sequence, &flags);
8588 MYDB_END_ALLOW_THREADS
8589
8590 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008591 return NUMBER_FromLong((int)flags);
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008592}
8593
8594static PyObject*
8595DBSequence_set_range(DBSequenceObject* self, PyObject* args)
8596{
8597 int err;
Jesus Ceaef9764f2008-05-13 18:45:46 +00008598 PY_LONG_LONG min, max;
8599 db_seq_t min2, max2;
Tim Petersbb21b2c2006-06-06 15:50:17 +00008600 if (!PyArg_ParseTuple(args,"(LL):set_range", &min, &max))
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008601 return NULL;
8602 CHECK_SEQUENCE_NOT_CLOSED(self)
8603
Jesus Ceaef9764f2008-05-13 18:45:46 +00008604 min2=min; /* If truncation, compiler should show a warning */
8605 max2=max;
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008606 MYDB_BEGIN_ALLOW_THREADS
Jesus Ceaef9764f2008-05-13 18:45:46 +00008607 err = self->sequence->set_range(self->sequence, min2, max2);
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008608 MYDB_END_ALLOW_THREADS
8609
8610 RETURN_IF_ERR();
8611 RETURN_NONE();
8612}
8613
8614static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008615DBSequence_get_range(DBSequenceObject* self)
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008616{
8617 int err;
Jesus Ceaef9764f2008-05-13 18:45:46 +00008618 PY_LONG_LONG min, max;
8619 db_seq_t min2, max2;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008620
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008621 CHECK_SEQUENCE_NOT_CLOSED(self)
8622
8623 MYDB_BEGIN_ALLOW_THREADS
Jesus Ceaef9764f2008-05-13 18:45:46 +00008624 err = self->sequence->get_range(self->sequence, &min2, &max2);
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008625 MYDB_END_ALLOW_THREADS
8626
8627 RETURN_IF_ERR();
Jesus Ceaef9764f2008-05-13 18:45:46 +00008628 min=min2; /* If truncation, compiler should show a warning */
8629 max=max2;
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008630 return Py_BuildValue("(LL)", min, max);
8631}
8632
Jesus Cea6557aac2010-03-22 14:22:26 +00008633
8634static PyObject*
8635DBSequence_stat_print(DBSequenceObject* self, PyObject* args, PyObject *kwargs)
8636{
8637 int err;
8638 int flags=0;
8639 static char* kwnames[] = { "flags", NULL };
8640
8641 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:stat_print",
8642 kwnames, &flags))
8643 {
8644 return NULL;
8645 }
8646
8647 CHECK_SEQUENCE_NOT_CLOSED(self);
8648
8649 MYDB_BEGIN_ALLOW_THREADS;
8650 err = self->sequence->stat_print(self->sequence, flags);
8651 MYDB_END_ALLOW_THREADS;
8652 RETURN_IF_ERR();
8653 RETURN_NONE();
8654}
8655
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008656static PyObject*
8657DBSequence_stat(DBSequenceObject* self, PyObject* args, PyObject* kwargs)
8658{
8659 int err, flags = 0;
8660 DB_SEQUENCE_STAT* sp = NULL;
8661 PyObject* dict_stat;
8662 static char* kwnames[] = {"flags", NULL };
8663 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:stat", kwnames, &flags))
8664 return NULL;
8665 CHECK_SEQUENCE_NOT_CLOSED(self);
8666
8667 MYDB_BEGIN_ALLOW_THREADS;
8668 err = self->sequence->stat(self->sequence, &sp, flags);
8669 MYDB_END_ALLOW_THREADS;
8670 RETURN_IF_ERR();
8671
8672 if ((dict_stat = PyDict_New()) == NULL) {
8673 free(sp);
8674 return NULL;
8675 }
8676
8677
8678#define MAKE_INT_ENTRY(name) _addIntToDict(dict_stat, #name, sp->st_##name)
8679#define MAKE_LONG_LONG_ENTRY(name) _addDb_seq_tToDict(dict_stat, #name, sp->st_##name)
8680
8681 MAKE_INT_ENTRY(wait);
8682 MAKE_INT_ENTRY(nowait);
8683 MAKE_LONG_LONG_ENTRY(current);
8684 MAKE_LONG_LONG_ENTRY(value);
8685 MAKE_LONG_LONG_ENTRY(last_value);
8686 MAKE_LONG_LONG_ENTRY(min);
8687 MAKE_LONG_LONG_ENTRY(max);
8688 MAKE_INT_ENTRY(cache_size);
8689 MAKE_INT_ENTRY(flags);
8690
8691#undef MAKE_INT_ENTRY
8692#undef MAKE_LONG_LONG_ENTRY
8693
8694 free(sp);
8695 return dict_stat;
8696}
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008697
8698
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008699/* --------------------------------------------------------------------- */
8700/* Method definition tables and type objects */
8701
8702static PyMethodDef DB_methods[] = {
Jesus Cea4907d272008-08-31 14:00:51 +00008703 {"append", (PyCFunction)DB_append, METH_VARARGS|METH_KEYWORDS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008704 {"associate", (PyCFunction)DB_associate, METH_VARARGS|METH_KEYWORDS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008705 {"close", (PyCFunction)DB_close, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008706#if (DBVER >= 47)
8707 {"compact", (PyCFunction)DB_compact, METH_VARARGS|METH_KEYWORDS},
8708#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008709 {"consume", (PyCFunction)DB_consume, METH_VARARGS|METH_KEYWORDS},
8710 {"consume_wait", (PyCFunction)DB_consume_wait, METH_VARARGS|METH_KEYWORDS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008711 {"cursor", (PyCFunction)DB_cursor, METH_VARARGS|METH_KEYWORDS},
8712 {"delete", (PyCFunction)DB_delete, METH_VARARGS|METH_KEYWORDS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008713 {"fd", (PyCFunction)DB_fd, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008714#if (DBVER >= 46)
8715 {"exists", (PyCFunction)DB_exists,
8716 METH_VARARGS|METH_KEYWORDS},
8717#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008718 {"get", (PyCFunction)DB_get, METH_VARARGS|METH_KEYWORDS},
Gregory P. Smith19699a92004-06-28 04:06:49 +00008719 {"pget", (PyCFunction)DB_pget, METH_VARARGS|METH_KEYWORDS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008720 {"get_both", (PyCFunction)DB_get_both, METH_VARARGS|METH_KEYWORDS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008721 {"get_byteswapped", (PyCFunction)DB_get_byteswapped,METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008722 {"get_size", (PyCFunction)DB_get_size, METH_VARARGS|METH_KEYWORDS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008723 {"get_type", (PyCFunction)DB_get_type, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008724 {"join", (PyCFunction)DB_join, METH_VARARGS},
8725 {"key_range", (PyCFunction)DB_key_range, METH_VARARGS|METH_KEYWORDS},
Jesus Cea4907d272008-08-31 14:00:51 +00008726 {"has_key", (PyCFunction)DB_has_key, METH_VARARGS|METH_KEYWORDS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008727 {"items", (PyCFunction)DB_items, METH_VARARGS},
8728 {"keys", (PyCFunction)DB_keys, METH_VARARGS},
8729 {"open", (PyCFunction)DB_open, METH_VARARGS|METH_KEYWORDS},
8730 {"put", (PyCFunction)DB_put, METH_VARARGS|METH_KEYWORDS},
8731 {"remove", (PyCFunction)DB_remove, METH_VARARGS|METH_KEYWORDS},
8732 {"rename", (PyCFunction)DB_rename, METH_VARARGS},
8733 {"set_bt_minkey", (PyCFunction)DB_set_bt_minkey, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008734 {"get_bt_minkey", (PyCFunction)DB_get_bt_minkey, METH_NOARGS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008735 {"set_bt_compare", (PyCFunction)DB_set_bt_compare, METH_O},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008736 {"set_cachesize", (PyCFunction)DB_set_cachesize, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008737 {"get_cachesize", (PyCFunction)DB_get_cachesize, METH_NOARGS},
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07008738 {"set_dup_compare", (PyCFunction)DB_set_dup_compare, METH_O},
Jesus Cea6557aac2010-03-22 14:22:26 +00008739 {"set_encrypt", (PyCFunction)DB_set_encrypt, METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008740 {"get_encrypt_flags", (PyCFunction)DB_get_encrypt_flags, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008741 {"set_flags", (PyCFunction)DB_set_flags, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008742 {"get_flags", (PyCFunction)DB_get_flags, METH_NOARGS},
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07008743 {"get_transactional", (PyCFunction)DB_get_transactional, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008744 {"set_h_ffactor", (PyCFunction)DB_set_h_ffactor, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008745 {"get_h_ffactor", (PyCFunction)DB_get_h_ffactor, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008746 {"set_h_nelem", (PyCFunction)DB_set_h_nelem, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008747 {"get_h_nelem", (PyCFunction)DB_get_h_nelem, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008748 {"set_lorder", (PyCFunction)DB_set_lorder, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008749 {"get_lorder", (PyCFunction)DB_get_lorder, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008750 {"set_pagesize", (PyCFunction)DB_set_pagesize, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008751 {"get_pagesize", (PyCFunction)DB_get_pagesize, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008752 {"set_re_delim", (PyCFunction)DB_set_re_delim, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008753 {"get_re_delim", (PyCFunction)DB_get_re_delim, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008754 {"set_re_len", (PyCFunction)DB_set_re_len, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008755 {"get_re_len", (PyCFunction)DB_get_re_len, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008756 {"set_re_pad", (PyCFunction)DB_set_re_pad, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008757 {"get_re_pad", (PyCFunction)DB_get_re_pad, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008758 {"set_re_source", (PyCFunction)DB_set_re_source, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008759 {"get_re_source", (PyCFunction)DB_get_re_source, METH_NOARGS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008760 {"set_q_extentsize",(PyCFunction)DB_set_q_extentsize, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008761 {"get_q_extentsize",(PyCFunction)DB_get_q_extentsize, METH_NOARGS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008762 {"set_private", (PyCFunction)DB_set_private, METH_O},
8763 {"get_private", (PyCFunction)DB_get_private, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008764#if (DBVER >= 46)
8765 {"set_priority", (PyCFunction)DB_set_priority, METH_VARARGS},
8766 {"get_priority", (PyCFunction)DB_get_priority, METH_NOARGS},
8767#endif
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07008768 {"get_dbname", (PyCFunction)DB_get_dbname, METH_NOARGS},
8769 {"get_open_flags", (PyCFunction)DB_get_open_flags, METH_NOARGS},
Gregory P. Smith8b7e9172004-12-13 09:51:23 +00008770 {"stat", (PyCFunction)DB_stat, METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008771 {"stat_print", (PyCFunction)DB_stat_print,
8772 METH_VARARGS|METH_KEYWORDS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008773 {"sync", (PyCFunction)DB_sync, METH_VARARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008774 {"truncate", (PyCFunction)DB_truncate, METH_VARARGS|METH_KEYWORDS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008775 {"type", (PyCFunction)DB_get_type, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008776 {"upgrade", (PyCFunction)DB_upgrade, METH_VARARGS},
8777 {"values", (PyCFunction)DB_values, METH_VARARGS},
8778 {"verify", (PyCFunction)DB_verify, METH_VARARGS|METH_KEYWORDS},
8779 {"set_get_returns_none",(PyCFunction)DB_set_get_returns_none, METH_VARARGS},
8780 {NULL, NULL} /* sentinel */
8781};
8782
8783
Jesus Cea6557aac2010-03-22 14:22:26 +00008784/* We need this to support __contains__() */
8785static PySequenceMethods DB_sequence = {
8786 0, /* sq_length, mapping wins here */
8787 0, /* sq_concat */
8788 0, /* sq_repeat */
8789 0, /* sq_item */
8790 0, /* sq_slice */
8791 0, /* sq_ass_item */
8792 0, /* sq_ass_slice */
8793 (objobjproc)DB_contains, /* sq_contains */
8794 0, /* sq_inplace_concat */
8795 0, /* sq_inplace_repeat */
8796};
8797
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008798static PyMappingMethods DB_mapping = {
Martin v. Löwis70ee3cc2006-06-12 04:26:31 +00008799 DB_length, /*mp_length*/
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008800 (binaryfunc)DB_subscript, /*mp_subscript*/
8801 (objobjargproc)DB_ass_sub, /*mp_ass_subscript*/
8802};
8803
8804
8805static PyMethodDef DBCursor_methods[] = {
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008806 {"close", (PyCFunction)DBC_close, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008807 {"count", (PyCFunction)DBC_count, METH_VARARGS},
8808 {"current", (PyCFunction)DBC_current, METH_VARARGS|METH_KEYWORDS},
8809 {"delete", (PyCFunction)DBC_delete, METH_VARARGS},
8810 {"dup", (PyCFunction)DBC_dup, METH_VARARGS},
8811 {"first", (PyCFunction)DBC_first, METH_VARARGS|METH_KEYWORDS},
8812 {"get", (PyCFunction)DBC_get, METH_VARARGS|METH_KEYWORDS},
Gregory P. Smith19699a92004-06-28 04:06:49 +00008813 {"pget", (PyCFunction)DBC_pget, METH_VARARGS|METH_KEYWORDS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008814 {"get_recno", (PyCFunction)DBC_get_recno, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008815 {"last", (PyCFunction)DBC_last, METH_VARARGS|METH_KEYWORDS},
8816 {"next", (PyCFunction)DBC_next, METH_VARARGS|METH_KEYWORDS},
8817 {"prev", (PyCFunction)DBC_prev, METH_VARARGS|METH_KEYWORDS},
8818 {"put", (PyCFunction)DBC_put, METH_VARARGS|METH_KEYWORDS},
8819 {"set", (PyCFunction)DBC_set, METH_VARARGS|METH_KEYWORDS},
8820 {"set_range", (PyCFunction)DBC_set_range, METH_VARARGS|METH_KEYWORDS},
8821 {"get_both", (PyCFunction)DBC_get_both, METH_VARARGS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008822 {"get_current_size",(PyCFunction)DBC_get_current_size, METH_NOARGS},
Gregory P. Smith455d46f2003-07-09 04:45:59 +00008823 {"set_both", (PyCFunction)DBC_set_both, METH_VARARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008824 {"set_recno", (PyCFunction)DBC_set_recno, METH_VARARGS|METH_KEYWORDS},
8825 {"consume", (PyCFunction)DBC_consume, METH_VARARGS|METH_KEYWORDS},
8826 {"next_dup", (PyCFunction)DBC_next_dup, METH_VARARGS|METH_KEYWORDS},
8827 {"next_nodup", (PyCFunction)DBC_next_nodup, METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008828#if (DBVER >= 46)
8829 {"prev_dup", (PyCFunction)DBC_prev_dup,
8830 METH_VARARGS|METH_KEYWORDS},
8831#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008832 {"prev_nodup", (PyCFunction)DBC_prev_nodup, METH_VARARGS|METH_KEYWORDS},
8833 {"join_item", (PyCFunction)DBC_join_item, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008834#if (DBVER >= 46)
8835 {"set_priority", (PyCFunction)DBC_set_priority,
8836 METH_VARARGS|METH_KEYWORDS},
8837 {"get_priority", (PyCFunction)DBC_get_priority, METH_NOARGS},
8838#endif
8839 {NULL, NULL} /* sentinel */
8840};
8841
8842
8843static PyMethodDef DBLogCursor_methods[] = {
8844 {"close", (PyCFunction)DBLogCursor_close, METH_NOARGS},
8845 {"current", (PyCFunction)DBLogCursor_current, METH_NOARGS},
8846 {"first", (PyCFunction)DBLogCursor_first, METH_NOARGS},
8847 {"last", (PyCFunction)DBLogCursor_last, METH_NOARGS},
8848 {"next", (PyCFunction)DBLogCursor_next, METH_NOARGS},
8849 {"prev", (PyCFunction)DBLogCursor_prev, METH_NOARGS},
8850 {"set", (PyCFunction)DBLogCursor_set, METH_VARARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008851 {NULL, NULL} /* sentinel */
8852};
8853
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07008854#if (DBVER >= 52)
8855static PyMethodDef DBSite_methods[] = {
8856 {"get_config", (PyCFunction)DBSite_get_config,
8857 METH_VARARGS | METH_KEYWORDS},
8858 {"set_config", (PyCFunction)DBSite_set_config,
8859 METH_VARARGS | METH_KEYWORDS},
8860 {"remove", (PyCFunction)DBSite_remove, METH_NOARGS},
8861 {"get_eid", (PyCFunction)DBSite_get_eid, METH_NOARGS},
8862 {"get_address", (PyCFunction)DBSite_get_address, METH_NOARGS},
8863 {"close", (PyCFunction)DBSite_close, METH_NOARGS},
8864 {NULL, NULL} /* sentinel */
8865};
8866#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008867
8868static PyMethodDef DBEnv_methods[] = {
8869 {"close", (PyCFunction)DBEnv_close, METH_VARARGS},
8870 {"open", (PyCFunction)DBEnv_open, METH_VARARGS},
8871 {"remove", (PyCFunction)DBEnv_remove, METH_VARARGS},
Barry Warsaw9a0d7792002-12-30 20:53:52 +00008872 {"dbremove", (PyCFunction)DBEnv_dbremove, METH_VARARGS|METH_KEYWORDS},
8873 {"dbrename", (PyCFunction)DBEnv_dbrename, METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008874#if (DBVER >= 46)
8875 {"set_thread_count", (PyCFunction)DBEnv_set_thread_count, METH_VARARGS},
8876 {"get_thread_count", (PyCFunction)DBEnv_get_thread_count, METH_NOARGS},
8877#endif
Barry Warsaw9a0d7792002-12-30 20:53:52 +00008878 {"set_encrypt", (PyCFunction)DBEnv_set_encrypt, METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008879 {"get_encrypt_flags", (PyCFunction)DBEnv_get_encrypt_flags, METH_NOARGS},
8880 {"get_timeout", (PyCFunction)DBEnv_get_timeout,
8881 METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008882 {"set_timeout", (PyCFunction)DBEnv_set_timeout, METH_VARARGS|METH_KEYWORDS},
8883 {"set_shm_key", (PyCFunction)DBEnv_set_shm_key, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008884 {"get_shm_key", (PyCFunction)DBEnv_get_shm_key, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008885#if (DBVER >= 46)
8886 {"set_cache_max", (PyCFunction)DBEnv_set_cache_max, METH_VARARGS},
8887 {"get_cache_max", (PyCFunction)DBEnv_get_cache_max, METH_NOARGS},
8888#endif
8889 {"set_cachesize", (PyCFunction)DBEnv_set_cachesize, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008890 {"get_cachesize", (PyCFunction)DBEnv_get_cachesize, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008891 {"memp_trickle", (PyCFunction)DBEnv_memp_trickle, METH_VARARGS},
8892 {"memp_sync", (PyCFunction)DBEnv_memp_sync, METH_VARARGS},
8893 {"memp_stat", (PyCFunction)DBEnv_memp_stat,
8894 METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008895 {"memp_stat_print", (PyCFunction)DBEnv_memp_stat_print,
8896 METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008897#if (DBVER >= 44)
8898 {"mutex_set_max", (PyCFunction)DBEnv_mutex_set_max, METH_VARARGS},
8899 {"mutex_get_max", (PyCFunction)DBEnv_mutex_get_max, METH_NOARGS},
8900 {"mutex_set_align", (PyCFunction)DBEnv_mutex_set_align, METH_VARARGS},
8901 {"mutex_get_align", (PyCFunction)DBEnv_mutex_get_align, METH_NOARGS},
8902 {"mutex_set_increment", (PyCFunction)DBEnv_mutex_set_increment,
8903 METH_VARARGS},
8904 {"mutex_get_increment", (PyCFunction)DBEnv_mutex_get_increment,
8905 METH_NOARGS},
8906 {"mutex_set_tas_spins", (PyCFunction)DBEnv_mutex_set_tas_spins,
8907 METH_VARARGS},
8908 {"mutex_get_tas_spins", (PyCFunction)DBEnv_mutex_get_tas_spins,
8909 METH_NOARGS},
8910 {"mutex_stat", (PyCFunction)DBEnv_mutex_stat, METH_VARARGS},
8911#if (DBVER >= 44)
8912 {"mutex_stat_print", (PyCFunction)DBEnv_mutex_stat_print,
8913 METH_VARARGS|METH_KEYWORDS},
8914#endif
8915#endif
8916 {"set_data_dir", (PyCFunction)DBEnv_set_data_dir, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008917 {"get_data_dirs", (PyCFunction)DBEnv_get_data_dirs, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008918 {"get_flags", (PyCFunction)DBEnv_get_flags, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008919 {"set_flags", (PyCFunction)DBEnv_set_flags, METH_VARARGS},
8920#if (DBVER >= 47)
8921 {"log_set_config", (PyCFunction)DBEnv_log_set_config, METH_VARARGS},
8922 {"log_get_config", (PyCFunction)DBEnv_log_get_config, METH_VARARGS},
8923#endif
8924 {"set_lg_bsize", (PyCFunction)DBEnv_set_lg_bsize, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008925 {"get_lg_bsize", (PyCFunction)DBEnv_get_lg_bsize, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008926 {"set_lg_dir", (PyCFunction)DBEnv_set_lg_dir, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008927 {"get_lg_dir", (PyCFunction)DBEnv_get_lg_dir, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008928 {"set_lg_max", (PyCFunction)DBEnv_set_lg_max, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008929 {"get_lg_max", (PyCFunction)DBEnv_get_lg_max, METH_NOARGS},
Gregory P. Smithe9477062005-06-04 06:46:59 +00008930 {"set_lg_regionmax",(PyCFunction)DBEnv_set_lg_regionmax, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008931 {"get_lg_regionmax",(PyCFunction)DBEnv_get_lg_regionmax, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008932#if (DBVER >= 44)
8933 {"set_lg_filemode", (PyCFunction)DBEnv_set_lg_filemode, METH_VARARGS},
8934 {"get_lg_filemode", (PyCFunction)DBEnv_get_lg_filemode, METH_NOARGS},
8935#endif
8936#if (DBVER >= 47)
8937 {"set_lk_partitions", (PyCFunction)DBEnv_set_lk_partitions, METH_VARARGS},
8938 {"get_lk_partitions", (PyCFunction)DBEnv_get_lk_partitions, METH_NOARGS},
8939#endif
8940 {"set_lk_detect", (PyCFunction)DBEnv_set_lk_detect, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008941 {"get_lk_detect", (PyCFunction)DBEnv_get_lk_detect, METH_NOARGS},
Gregory P. Smith8b96a352007-01-05 01:59:42 +00008942#if (DBVER < 45)
Jesus Cea6557aac2010-03-22 14:22:26 +00008943 {"set_lk_max", (PyCFunction)DBEnv_set_lk_max, METH_VARARGS},
Gregory P. Smith8b96a352007-01-05 01:59:42 +00008944#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008945 {"set_lk_max_locks", (PyCFunction)DBEnv_set_lk_max_locks, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008946 {"get_lk_max_locks", (PyCFunction)DBEnv_get_lk_max_locks, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008947 {"set_lk_max_lockers", (PyCFunction)DBEnv_set_lk_max_lockers, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008948 {"get_lk_max_lockers", (PyCFunction)DBEnv_get_lk_max_lockers, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008949 {"set_lk_max_objects", (PyCFunction)DBEnv_set_lk_max_objects, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008950 {"get_lk_max_objects", (PyCFunction)DBEnv_get_lk_max_objects, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008951 {"stat_print", (PyCFunction)DBEnv_stat_print,
8952 METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008953 {"set_mp_mmapsize", (PyCFunction)DBEnv_set_mp_mmapsize, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008954 {"get_mp_mmapsize", (PyCFunction)DBEnv_get_mp_mmapsize, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008955 {"set_tmp_dir", (PyCFunction)DBEnv_set_tmp_dir, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008956 {"get_tmp_dir", (PyCFunction)DBEnv_get_tmp_dir, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008957 {"txn_begin", (PyCFunction)DBEnv_txn_begin, METH_VARARGS|METH_KEYWORDS},
8958 {"txn_checkpoint", (PyCFunction)DBEnv_txn_checkpoint, METH_VARARGS},
8959 {"txn_stat", (PyCFunction)DBEnv_txn_stat, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008960 {"txn_stat_print", (PyCFunction)DBEnv_txn_stat_print,
8961 METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008962 {"get_tx_max", (PyCFunction)DBEnv_get_tx_max, METH_NOARGS},
8963 {"get_tx_timestamp", (PyCFunction)DBEnv_get_tx_timestamp, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008964 {"set_tx_max", (PyCFunction)DBEnv_set_tx_max, METH_VARARGS},
Gregory P. Smith8a474042006-01-27 07:05:40 +00008965 {"set_tx_timestamp", (PyCFunction)DBEnv_set_tx_timestamp, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008966 {"lock_detect", (PyCFunction)DBEnv_lock_detect, METH_VARARGS},
8967 {"lock_get", (PyCFunction)DBEnv_lock_get, METH_VARARGS},
8968 {"lock_id", (PyCFunction)DBEnv_lock_id, METH_NOARGS},
8969 {"lock_id_free", (PyCFunction)DBEnv_lock_id_free, METH_VARARGS},
8970 {"lock_put", (PyCFunction)DBEnv_lock_put, METH_VARARGS},
8971 {"lock_stat", (PyCFunction)DBEnv_lock_stat, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008972 {"lock_stat_print", (PyCFunction)DBEnv_lock_stat_print,
8973 METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008974 {"log_cursor", (PyCFunction)DBEnv_log_cursor, METH_NOARGS},
8975 {"log_file", (PyCFunction)DBEnv_log_file, METH_VARARGS},
Gregory P. Smithdb8a8072006-06-05 01:56:15 +00008976#if (DBVER >= 44)
Jesus Cea6557aac2010-03-22 14:22:26 +00008977 {"log_printf", (PyCFunction)DBEnv_log_printf,
8978 METH_VARARGS|METH_KEYWORDS},
8979#endif
8980 {"log_archive", (PyCFunction)DBEnv_log_archive, METH_VARARGS},
8981 {"log_flush", (PyCFunction)DBEnv_log_flush, METH_NOARGS},
8982 {"log_stat", (PyCFunction)DBEnv_log_stat, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008983 {"log_stat_print", (PyCFunction)DBEnv_log_stat_print,
8984 METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008985#if (DBVER >= 44)
8986 {"fileid_reset", (PyCFunction)DBEnv_fileid_reset, METH_VARARGS|METH_KEYWORDS},
8987 {"lsn_reset", (PyCFunction)DBEnv_lsn_reset, METH_VARARGS|METH_KEYWORDS},
Gregory P. Smithdb8a8072006-06-05 01:56:15 +00008988#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008989 {"set_get_returns_none",(PyCFunction)DBEnv_set_get_returns_none, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008990 {"txn_recover", (PyCFunction)DBEnv_txn_recover, METH_NOARGS},
Matthias Klose54cc5392010-03-15 12:46:18 +00008991#if (DBVER < 48)
Jesus Ceaca3939c2008-05-22 15:27:38 +00008992 {"set_rpc_server", (PyCFunction)DBEnv_set_rpc_server,
Stefan Krah77112732011-09-15 22:56:00 +02008993 METH_VARARGS|METH_KEYWORDS},
Matthias Klose54cc5392010-03-15 12:46:18 +00008994#endif
Jesus Cea6557aac2010-03-22 14:22:26 +00008995 {"set_mp_max_openfd", (PyCFunction)DBEnv_set_mp_max_openfd, METH_VARARGS},
8996 {"get_mp_max_openfd", (PyCFunction)DBEnv_get_mp_max_openfd, METH_NOARGS},
8997 {"set_mp_max_write", (PyCFunction)DBEnv_set_mp_max_write, METH_VARARGS},
8998 {"get_mp_max_write", (PyCFunction)DBEnv_get_mp_max_write, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008999 {"set_verbose", (PyCFunction)DBEnv_set_verbose, METH_VARARGS},
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009000 {"get_verbose", (PyCFunction)DBEnv_get_verbose, METH_VARARGS},
9001 {"set_private", (PyCFunction)DBEnv_set_private, METH_O},
9002 {"get_private", (PyCFunction)DBEnv_get_private, METH_NOARGS},
9003 {"get_open_flags", (PyCFunction)DBEnv_get_open_flags, METH_NOARGS},
9004#if (DBVER >= 47)
9005 {"set_intermediate_dir_mode", (PyCFunction)DBEnv_set_intermediate_dir_mode,
9006 METH_VARARGS},
9007 {"get_intermediate_dir_mode", (PyCFunction)DBEnv_get_intermediate_dir_mode,
9008 METH_NOARGS},
Jesus Ceaef9764f2008-05-13 18:45:46 +00009009#endif
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009010#if (DBVER < 47)
9011 {"set_intermediate_dir", (PyCFunction)DBEnv_set_intermediate_dir,
9012 METH_VARARGS},
9013#endif
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009014 {"rep_start", (PyCFunction)DBEnv_rep_start,
9015 METH_VARARGS|METH_KEYWORDS},
9016 {"rep_set_transport", (PyCFunction)DBEnv_rep_set_transport, METH_VARARGS},
9017 {"rep_process_message", (PyCFunction)DBEnv_rep_process_message,
9018 METH_VARARGS},
9019#if (DBVER >= 46)
9020 {"rep_elect", (PyCFunction)DBEnv_rep_elect, METH_VARARGS},
9021#endif
9022#if (DBVER >= 44)
9023 {"rep_set_config", (PyCFunction)DBEnv_rep_set_config, METH_VARARGS},
9024 {"rep_get_config", (PyCFunction)DBEnv_rep_get_config, METH_VARARGS},
9025 {"rep_sync", (PyCFunction)DBEnv_rep_sync, METH_NOARGS},
Jesus Ceaef9764f2008-05-13 18:45:46 +00009026#endif
9027#if (DBVER >= 45)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009028 {"rep_set_limit", (PyCFunction)DBEnv_rep_set_limit, METH_VARARGS},
9029 {"rep_get_limit", (PyCFunction)DBEnv_rep_get_limit, METH_NOARGS},
9030#endif
9031#if (DBVER >= 47)
9032 {"rep_set_request", (PyCFunction)DBEnv_rep_set_request, METH_VARARGS},
9033 {"rep_get_request", (PyCFunction)DBEnv_rep_get_request, METH_NOARGS},
9034#endif
9035#if (DBVER >= 45)
9036 {"set_event_notify", (PyCFunction)DBEnv_set_event_notify, METH_O},
Jesus Ceaef9764f2008-05-13 18:45:46 +00009037#endif
9038#if (DBVER >= 45)
9039 {"rep_set_nsites", (PyCFunction)DBEnv_rep_set_nsites, METH_VARARGS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009040 {"rep_get_nsites", (PyCFunction)DBEnv_rep_get_nsites, METH_NOARGS},
Jesus Ceaef9764f2008-05-13 18:45:46 +00009041 {"rep_set_priority", (PyCFunction)DBEnv_rep_set_priority, METH_VARARGS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009042 {"rep_get_priority", (PyCFunction)DBEnv_rep_get_priority, METH_NOARGS},
Jesus Ceaef9764f2008-05-13 18:45:46 +00009043 {"rep_set_timeout", (PyCFunction)DBEnv_rep_set_timeout, METH_VARARGS},
9044 {"rep_get_timeout", (PyCFunction)DBEnv_rep_get_timeout, METH_VARARGS},
9045#endif
Jesus Cea6557aac2010-03-22 14:22:26 +00009046#if (DBVER >= 47)
9047 {"rep_set_clockskew", (PyCFunction)DBEnv_rep_set_clockskew, METH_VARARGS},
9048 {"rep_get_clockskew", (PyCFunction)DBEnv_rep_get_clockskew, METH_VARARGS},
9049#endif
9050 {"rep_stat", (PyCFunction)DBEnv_rep_stat,
9051 METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00009052 {"rep_stat_print", (PyCFunction)DBEnv_rep_stat_print,
9053 METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00009054
Jesus Ceaef9764f2008-05-13 18:45:46 +00009055#if (DBVER >= 45)
9056 {"repmgr_start", (PyCFunction)DBEnv_repmgr_start,
9057 METH_VARARGS|METH_KEYWORDS},
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009058#if (DBVER < 52)
Jesus Ceaef9764f2008-05-13 18:45:46 +00009059 {"repmgr_set_local_site", (PyCFunction)DBEnv_repmgr_set_local_site,
9060 METH_VARARGS|METH_KEYWORDS},
9061 {"repmgr_add_remote_site", (PyCFunction)DBEnv_repmgr_add_remote_site,
9062 METH_VARARGS|METH_KEYWORDS},
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009063#endif
Jesus Ceaef9764f2008-05-13 18:45:46 +00009064 {"repmgr_set_ack_policy", (PyCFunction)DBEnv_repmgr_set_ack_policy,
9065 METH_VARARGS},
9066 {"repmgr_get_ack_policy", (PyCFunction)DBEnv_repmgr_get_ack_policy,
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009067 METH_NOARGS},
Jesus Ceaef9764f2008-05-13 18:45:46 +00009068 {"repmgr_site_list", (PyCFunction)DBEnv_repmgr_site_list,
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009069 METH_NOARGS},
Jesus Ceaef9764f2008-05-13 18:45:46 +00009070#endif
9071#if (DBVER >= 46)
9072 {"repmgr_stat", (PyCFunction)DBEnv_repmgr_stat,
9073 METH_VARARGS|METH_KEYWORDS},
9074 {"repmgr_stat_print", (PyCFunction)DBEnv_repmgr_stat_print,
9075 METH_VARARGS|METH_KEYWORDS},
9076#endif
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009077#if (DBVER >= 52)
9078 {"repmgr_site", (PyCFunction)DBEnv_repmgr_site,
9079 METH_VARARGS | METH_KEYWORDS},
9080 {"repmgr_site_by_eid", (PyCFunction)DBEnv_repmgr_site_by_eid,
9081 METH_VARARGS | METH_KEYWORDS},
9082#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009083 {NULL, NULL} /* sentinel */
9084};
9085
9086
9087static PyMethodDef DBTxn_methods[] = {
9088 {"commit", (PyCFunction)DBTxn_commit, METH_VARARGS},
9089 {"prepare", (PyCFunction)DBTxn_prepare, METH_VARARGS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009090 {"discard", (PyCFunction)DBTxn_discard, METH_NOARGS},
9091 {"abort", (PyCFunction)DBTxn_abort, METH_NOARGS},
9092 {"id", (PyCFunction)DBTxn_id, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00009093 {"set_timeout", (PyCFunction)DBTxn_set_timeout,
9094 METH_VARARGS|METH_KEYWORDS},
9095#if (DBVER >= 44)
9096 {"set_name", (PyCFunction)DBTxn_set_name, METH_VARARGS},
9097 {"get_name", (PyCFunction)DBTxn_get_name, METH_NOARGS},
9098#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009099 {NULL, NULL} /* sentinel */
9100};
9101
9102
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009103static PyMethodDef DBSequence_methods[] = {
9104 {"close", (PyCFunction)DBSequence_close, METH_VARARGS},
9105 {"get", (PyCFunction)DBSequence_get, METH_VARARGS|METH_KEYWORDS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009106 {"get_dbp", (PyCFunction)DBSequence_get_dbp, METH_NOARGS},
9107 {"get_key", (PyCFunction)DBSequence_get_key, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00009108 {"initial_value", (PyCFunction)DBSequence_initial_value, METH_VARARGS},
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009109 {"open", (PyCFunction)DBSequence_open, METH_VARARGS|METH_KEYWORDS},
9110 {"remove", (PyCFunction)DBSequence_remove, METH_VARARGS|METH_KEYWORDS},
9111 {"set_cachesize", (PyCFunction)DBSequence_set_cachesize, METH_VARARGS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009112 {"get_cachesize", (PyCFunction)DBSequence_get_cachesize, METH_NOARGS},
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009113 {"set_flags", (PyCFunction)DBSequence_set_flags, METH_VARARGS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009114 {"get_flags", (PyCFunction)DBSequence_get_flags, METH_NOARGS},
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009115 {"set_range", (PyCFunction)DBSequence_set_range, METH_VARARGS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009116 {"get_range", (PyCFunction)DBSequence_get_range, METH_NOARGS},
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009117 {"stat", (PyCFunction)DBSequence_stat, METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00009118 {"stat_print", (PyCFunction)DBSequence_stat_print,
9119 METH_VARARGS|METH_KEYWORDS},
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009120 {NULL, NULL} /* sentinel */
9121};
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009122
9123
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009124static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009125DBEnv_db_home_get(DBEnvObject* self)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009126{
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009127 const char *home = NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009128
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009129 CHECK_ENV_NOT_CLOSED(self);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009130
Jesus Cea6557aac2010-03-22 14:22:26 +00009131 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009132 self->db_env->get_home(self->db_env, &home);
Jesus Cea6557aac2010-03-22 14:22:26 +00009133 MYDB_END_ALLOW_THREADS;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009134
9135 if (home == NULL) {
9136 RETURN_NONE();
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009137 }
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009138 return PyBytes_FromString(home);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009139}
9140
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009141static PyGetSetDef DBEnv_getsets[] = {
9142 {"db_home", (getter)DBEnv_db_home_get, NULL,},
9143 {NULL}
9144};
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009145
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009146
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009147statichere PyTypeObject DB_Type = {
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009148#if (PY_VERSION_HEX < 0x03000000)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009149 PyObject_HEAD_INIT(NULL)
9150 0, /*ob_size*/
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009151#else
9152 PyVarObject_HEAD_INIT(NULL, 0)
9153#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009154 "DB", /*tp_name*/
9155 sizeof(DBObject), /*tp_basicsize*/
9156 0, /*tp_itemsize*/
9157 /* methods */
9158 (destructor)DB_dealloc, /*tp_dealloc*/
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009159 0, /*tp_print*/
9160 0, /*tp_getattr*/
9161 0, /*tp_setattr*/
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009162 0, /*tp_compare*/
9163 0, /*tp_repr*/
9164 0, /*tp_as_number*/
Jesus Cea6557aac2010-03-22 14:22:26 +00009165 &DB_sequence,/*tp_as_sequence*/
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009166 &DB_mapping,/*tp_as_mapping*/
9167 0, /*tp_hash*/
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009168 0, /* tp_call */
9169 0, /* tp_str */
9170 0, /* tp_getattro */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009171 0, /* tp_setattro */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009172 0, /* tp_as_buffer */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009173#if (PY_VERSION_HEX < 0x03000000)
Gregory P. Smith31c50652004-06-28 01:20:40 +00009174 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009175#else
9176 Py_TPFLAGS_DEFAULT, /* tp_flags */
9177#endif
9178 0, /* tp_doc */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009179 0, /* tp_traverse */
9180 0, /* tp_clear */
9181 0, /* tp_richcompare */
Gregory P. Smith31c50652004-06-28 01:20:40 +00009182 offsetof(DBObject, in_weakreflist), /* tp_weaklistoffset */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009183 0, /*tp_iter*/
9184 0, /*tp_iternext*/
9185 DB_methods, /*tp_methods*/
9186 0, /*tp_members*/
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009187};
9188
9189
9190statichere PyTypeObject DBCursor_Type = {
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009191#if (PY_VERSION_HEX < 0x03000000)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009192 PyObject_HEAD_INIT(NULL)
9193 0, /*ob_size*/
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009194#else
9195 PyVarObject_HEAD_INIT(NULL, 0)
9196#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009197 "DBCursor", /*tp_name*/
9198 sizeof(DBCursorObject), /*tp_basicsize*/
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009199 0, /*tp_itemsize*/
9200 /* methods */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009201 (destructor)DBCursor_dealloc,/*tp_dealloc*/
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009202 0, /*tp_print*/
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009203 0, /*tp_getattr*/
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009204 0, /*tp_setattr*/
9205 0, /*tp_compare*/
9206 0, /*tp_repr*/
9207 0, /*tp_as_number*/
9208 0, /*tp_as_sequence*/
9209 0, /*tp_as_mapping*/
9210 0, /*tp_hash*/
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009211 0, /*tp_call*/
9212 0, /*tp_str*/
9213 0, /*tp_getattro*/
9214 0, /*tp_setattro*/
9215 0, /*tp_as_buffer*/
9216#if (PY_VERSION_HEX < 0x03000000)
Gregory P. Smith31c50652004-06-28 01:20:40 +00009217 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009218#else
9219 Py_TPFLAGS_DEFAULT, /* tp_flags */
9220#endif
9221 0, /* tp_doc */
9222 0, /* tp_traverse */
9223 0, /* tp_clear */
9224 0, /* tp_richcompare */
9225 offsetof(DBCursorObject, in_weakreflist), /* tp_weaklistoffset */
9226 0, /*tp_iter*/
9227 0, /*tp_iternext*/
9228 DBCursor_methods, /*tp_methods*/
9229 0, /*tp_members*/
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009230};
9231
9232
Jesus Cea6557aac2010-03-22 14:22:26 +00009233statichere PyTypeObject DBLogCursor_Type = {
9234#if (PY_VERSION_HEX < 0x03000000)
9235 PyObject_HEAD_INIT(NULL)
9236 0, /*ob_size*/
9237#else
9238 PyVarObject_HEAD_INIT(NULL, 0)
9239#endif
9240 "DBLogCursor", /*tp_name*/
9241 sizeof(DBLogCursorObject), /*tp_basicsize*/
9242 0, /*tp_itemsize*/
9243 /* methods */
9244 (destructor)DBLogCursor_dealloc,/*tp_dealloc*/
9245 0, /*tp_print*/
9246 0, /*tp_getattr*/
9247 0, /*tp_setattr*/
9248 0, /*tp_compare*/
9249 0, /*tp_repr*/
9250 0, /*tp_as_number*/
9251 0, /*tp_as_sequence*/
9252 0, /*tp_as_mapping*/
9253 0, /*tp_hash*/
9254 0, /*tp_call*/
9255 0, /*tp_str*/
9256 0, /*tp_getattro*/
9257 0, /*tp_setattro*/
9258 0, /*tp_as_buffer*/
9259#if (PY_VERSION_HEX < 0x03000000)
9260 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
9261#else
9262 Py_TPFLAGS_DEFAULT, /* tp_flags */
9263#endif
9264 0, /* tp_doc */
9265 0, /* tp_traverse */
9266 0, /* tp_clear */
9267 0, /* tp_richcompare */
9268 offsetof(DBLogCursorObject, in_weakreflist), /* tp_weaklistoffset */
9269 0, /*tp_iter*/
9270 0, /*tp_iternext*/
9271 DBLogCursor_methods, /*tp_methods*/
9272 0, /*tp_members*/
9273};
9274
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009275#if (DBVER >= 52)
9276statichere PyTypeObject DBSite_Type = {
9277#if (PY_VERSION_HEX < 0x03000000)
9278 PyObject_HEAD_INIT(NULL)
9279 0, /*ob_size*/
9280#else
9281 PyVarObject_HEAD_INIT(NULL, 0)
9282#endif
9283 "DBSite", /*tp_name*/
9284 sizeof(DBSiteObject), /*tp_basicsize*/
9285 0, /*tp_itemsize*/
9286 /* methods */
9287 (destructor)DBSite_dealloc,/*tp_dealloc*/
9288 0, /*tp_print*/
9289 0, /*tp_getattr*/
9290 0, /*tp_setattr*/
9291 0, /*tp_compare*/
9292 0, /*tp_repr*/
9293 0, /*tp_as_number*/
9294 0, /*tp_as_sequence*/
9295 0, /*tp_as_mapping*/
9296 0, /*tp_hash*/
9297 0, /*tp_call*/
9298 0, /*tp_str*/
9299 0, /*tp_getattro*/
9300 0, /*tp_setattro*/
9301 0, /*tp_as_buffer*/
9302#if (PY_VERSION_HEX < 0x03000000)
9303 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
9304#else
9305 Py_TPFLAGS_DEFAULT, /* tp_flags */
9306#endif
9307 0, /* tp_doc */
9308 0, /* tp_traverse */
9309 0, /* tp_clear */
9310 0, /* tp_richcompare */
9311 offsetof(DBSiteObject, in_weakreflist), /* tp_weaklistoffset */
9312 0, /*tp_iter*/
9313 0, /*tp_iternext*/
9314 DBSite_methods, /*tp_methods*/
9315 0, /*tp_members*/
9316};
9317#endif
Jesus Cea6557aac2010-03-22 14:22:26 +00009318
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009319statichere PyTypeObject DBEnv_Type = {
9320#if (PY_VERSION_HEX < 0x03000000)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009321 PyObject_HEAD_INIT(NULL)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009322 0, /*ob_size*/
9323#else
9324 PyVarObject_HEAD_INIT(NULL, 0)
9325#endif
9326 "DBEnv", /*tp_name*/
9327 sizeof(DBEnvObject), /*tp_basicsize*/
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009328 0, /*tp_itemsize*/
9329 /* methods */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009330 (destructor)DBEnv_dealloc, /*tp_dealloc*/
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009331 0, /*tp_print*/
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009332 0, /*tp_getattr*/
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009333 0, /*tp_setattr*/
9334 0, /*tp_compare*/
9335 0, /*tp_repr*/
9336 0, /*tp_as_number*/
9337 0, /*tp_as_sequence*/
9338 0, /*tp_as_mapping*/
9339 0, /*tp_hash*/
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009340 0, /* tp_call */
9341 0, /* tp_str */
9342 0, /* tp_getattro */
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009343 0, /* tp_setattro */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009344 0, /* tp_as_buffer */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009345#if (PY_VERSION_HEX < 0x03000000)
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009346 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009347#else
9348 Py_TPFLAGS_DEFAULT, /* tp_flags */
9349#endif
9350 0, /* tp_doc */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009351 0, /* tp_traverse */
9352 0, /* tp_clear */
9353 0, /* tp_richcompare */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009354 offsetof(DBEnvObject, in_weakreflist), /* tp_weaklistoffset */
9355 0, /* tp_iter */
9356 0, /* tp_iternext */
9357 DBEnv_methods, /* tp_methods */
9358 0, /* tp_members */
9359 DBEnv_getsets, /* tp_getsets */
9360};
9361
9362statichere PyTypeObject DBTxn_Type = {
9363#if (PY_VERSION_HEX < 0x03000000)
9364 PyObject_HEAD_INIT(NULL)
9365 0, /*ob_size*/
9366#else
9367 PyVarObject_HEAD_INIT(NULL, 0)
9368#endif
9369 "DBTxn", /*tp_name*/
9370 sizeof(DBTxnObject), /*tp_basicsize*/
9371 0, /*tp_itemsize*/
9372 /* methods */
9373 (destructor)DBTxn_dealloc, /*tp_dealloc*/
9374 0, /*tp_print*/
9375 0, /*tp_getattr*/
9376 0, /*tp_setattr*/
9377 0, /*tp_compare*/
9378 0, /*tp_repr*/
9379 0, /*tp_as_number*/
9380 0, /*tp_as_sequence*/
9381 0, /*tp_as_mapping*/
9382 0, /*tp_hash*/
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009383 0, /* tp_call */
9384 0, /* tp_str */
9385 0, /* tp_getattro */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009386 0, /* tp_setattro */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009387 0, /* tp_as_buffer */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009388#if (PY_VERSION_HEX < 0x03000000)
9389 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
9390#else
9391 Py_TPFLAGS_DEFAULT, /* tp_flags */
9392#endif
9393 0, /* tp_doc */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009394 0, /* tp_traverse */
9395 0, /* tp_clear */
9396 0, /* tp_richcompare */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009397 offsetof(DBTxnObject, in_weakreflist), /* tp_weaklistoffset */
9398 0, /*tp_iter*/
9399 0, /*tp_iternext*/
9400 DBTxn_methods, /*tp_methods*/
9401 0, /*tp_members*/
9402};
9403
9404
9405statichere PyTypeObject DBLock_Type = {
9406#if (PY_VERSION_HEX < 0x03000000)
9407 PyObject_HEAD_INIT(NULL)
9408 0, /*ob_size*/
9409#else
9410 PyVarObject_HEAD_INIT(NULL, 0)
9411#endif
9412 "DBLock", /*tp_name*/
9413 sizeof(DBLockObject), /*tp_basicsize*/
9414 0, /*tp_itemsize*/
9415 /* methods */
9416 (destructor)DBLock_dealloc, /*tp_dealloc*/
9417 0, /*tp_print*/
9418 0, /*tp_getattr*/
9419 0, /*tp_setattr*/
9420 0, /*tp_compare*/
9421 0, /*tp_repr*/
9422 0, /*tp_as_number*/
9423 0, /*tp_as_sequence*/
9424 0, /*tp_as_mapping*/
9425 0, /*tp_hash*/
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009426 0, /* tp_call */
9427 0, /* tp_str */
9428 0, /* tp_getattro */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009429 0, /* tp_setattro */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009430 0, /* tp_as_buffer */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009431#if (PY_VERSION_HEX < 0x03000000)
9432 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
9433#else
9434 Py_TPFLAGS_DEFAULT, /* tp_flags */
9435#endif
9436 0, /* tp_doc */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009437 0, /* tp_traverse */
9438 0, /* tp_clear */
9439 0, /* tp_richcompare */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009440 offsetof(DBLockObject, in_weakreflist), /* tp_weaklistoffset */
9441};
9442
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009443statichere PyTypeObject DBSequence_Type = {
9444#if (PY_VERSION_HEX < 0x03000000)
9445 PyObject_HEAD_INIT(NULL)
9446 0, /*ob_size*/
9447#else
9448 PyVarObject_HEAD_INIT(NULL, 0)
9449#endif
9450 "DBSequence", /*tp_name*/
9451 sizeof(DBSequenceObject), /*tp_basicsize*/
9452 0, /*tp_itemsize*/
9453 /* methods */
9454 (destructor)DBSequence_dealloc, /*tp_dealloc*/
9455 0, /*tp_print*/
9456 0, /*tp_getattr*/
9457 0, /*tp_setattr*/
9458 0, /*tp_compare*/
9459 0, /*tp_repr*/
9460 0, /*tp_as_number*/
9461 0, /*tp_as_sequence*/
9462 0, /*tp_as_mapping*/
9463 0, /*tp_hash*/
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009464 0, /* tp_call */
9465 0, /* tp_str */
9466 0, /* tp_getattro */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009467 0, /* tp_setattro */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009468 0, /* tp_as_buffer */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009469#if (PY_VERSION_HEX < 0x03000000)
9470 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
9471#else
9472 Py_TPFLAGS_DEFAULT, /* tp_flags */
9473#endif
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009474 0, /* tp_doc */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009475 0, /* tp_traverse */
9476 0, /* tp_clear */
9477 0, /* tp_richcompare */
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009478 offsetof(DBSequenceObject, in_weakreflist), /* tp_weaklistoffset */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009479 0, /*tp_iter*/
9480 0, /*tp_iternext*/
9481 DBSequence_methods, /*tp_methods*/
9482 0, /*tp_members*/
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009483};
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009484
9485/* --------------------------------------------------------------------- */
9486/* Module-level functions */
9487
9488static PyObject*
9489DB_construct(PyObject* self, PyObject* args, PyObject* kwargs)
9490{
9491 PyObject* dbenvobj = NULL;
9492 int flags = 0;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00009493 static char* kwnames[] = { "dbEnv", "flags", NULL};
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009494
Barry Warsaw9a0d7792002-12-30 20:53:52 +00009495 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Oi:DB", kwnames,
9496 &dbenvobj, &flags))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009497 return NULL;
9498 if (dbenvobj == Py_None)
9499 dbenvobj = NULL;
9500 else if (dbenvobj && !DBEnvObject_Check(dbenvobj)) {
9501 makeTypeError("DBEnv", dbenvobj);
9502 return NULL;
9503 }
9504
9505 return (PyObject* )newDBObject((DBEnvObject*)dbenvobj, flags);
9506}
9507
9508
9509static PyObject*
9510DBEnv_construct(PyObject* self, PyObject* args)
9511{
9512 int flags = 0;
9513 if (!PyArg_ParseTuple(args, "|i:DbEnv", &flags)) return NULL;
9514 return (PyObject* )newDBEnvObject(flags);
9515}
9516
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009517static PyObject*
9518DBSequence_construct(PyObject* self, PyObject* args, PyObject* kwargs)
9519{
Neal Norwitzb4fcf8d2006-06-11 05:44:18 +00009520 PyObject* dbobj;
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009521 int flags = 0;
9522 static char* kwnames[] = { "db", "flags", NULL};
9523
9524 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|i:DBSequence", kwnames, &dbobj, &flags))
9525 return NULL;
Neal Norwitzb4fcf8d2006-06-11 05:44:18 +00009526 if (!DBObject_Check(dbobj)) {
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009527 makeTypeError("DB", dbobj);
9528 return NULL;
9529 }
9530 return (PyObject* )newDBSequenceObject((DBObject*)dbobj, flags);
9531}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009532
9533static char bsddb_version_doc[] =
9534"Returns a tuple of major, minor, and patch release numbers of the\n\
9535underlying DB library.";
9536
9537static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009538bsddb_version(PyObject* self)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009539{
9540 int major, minor, patch;
9541
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009542 /* This should be instantaneous, no need to release the GIL */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009543 db_version(&major, &minor, &patch);
9544 return Py_BuildValue("(iii)", major, minor, patch);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009545}
9546
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009547#if (DBVER >= 50)
9548static PyObject*
9549bsddb_version_full(PyObject* self)
9550{
9551 char *version_string;
9552 int family, release, major, minor, patch;
9553
9554 /* This should be instantaneous, no need to release the GIL */
9555 version_string = db_full_version(&family, &release, &major, &minor, &patch);
9556 return Py_BuildValue("(siiiii)",
9557 version_string, family, release, major, minor, patch);
9558}
9559#endif
9560
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009561
9562/* List of functions defined in the module */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009563static PyMethodDef bsddb_methods[] = {
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009564 {"DB", (PyCFunction)DB_construct, METH_VARARGS | METH_KEYWORDS },
9565 {"DBEnv", (PyCFunction)DBEnv_construct, METH_VARARGS},
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009566 {"DBSequence", (PyCFunction)DBSequence_construct, METH_VARARGS | METH_KEYWORDS },
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009567 {"version", (PyCFunction)bsddb_version, METH_NOARGS, bsddb_version_doc},
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009568#if (DBVER >= 50)
9569 {"full_version", (PyCFunction)bsddb_version_full, METH_NOARGS},
9570#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009571 {NULL, NULL} /* sentinel */
9572};
9573
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009574
Gregory P. Smith39250532007-10-09 06:02:21 +00009575/* API structure */
9576static BSDDB_api bsddb_api;
9577
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009578
9579/* --------------------------------------------------------------------- */
9580/* Module initialization */
9581
9582
9583/* Convenience routine to export an integer value.
9584 * Errors are silently ignored, for better or for worse...
9585 */
9586#define ADD_INT(dict, NAME) _addIntToDict(dict, #NAME, NAME)
9587
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009588/*
9589** We can rename the module at import time, so the string allocated
9590** must be big enough, and any use of the name must use this particular
9591** string.
9592*/
Gregory P. Smith41631e82003-09-21 00:08:14 +00009593#define MODULE_NAME_MAX_LEN 11
9594static char _bsddbModuleName[MODULE_NAME_MAX_LEN+1] = "_bsddb";
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009595
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009596#if (PY_VERSION_HEX >= 0x03000000)
9597static struct PyModuleDef bsddbmodule = {
9598 PyModuleDef_HEAD_INIT,
9599 _bsddbModuleName, /* Name of module */
9600 NULL, /* module documentation, may be NULL */
9601 -1, /* size of per-interpreter state of the module,
9602 or -1 if the module keeps state in global variables. */
9603 bsddb_methods,
9604 NULL, /* Reload */
9605 NULL, /* Traverse */
9606 NULL, /* Clear */
9607 NULL /* Free */
9608};
9609#endif
9610
9611
9612#if (PY_VERSION_HEX < 0x03000000)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009613DL_EXPORT(void) init_bsddb(void)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009614#else
9615PyMODINIT_FUNC PyInit__bsddb(void) /* Note the two underscores */
9616#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009617{
9618 PyObject* m;
9619 PyObject* d;
Gregory P. Smith39250532007-10-09 06:02:21 +00009620 PyObject* py_api;
Jesus Cea6557aac2010-03-22 14:22:26 +00009621 PyObject* pybsddb_version_s;
9622 PyObject* db_version_s;
9623 PyObject* cvsid_s;
9624
9625#if (PY_VERSION_HEX < 0x03000000)
9626 pybsddb_version_s = PyString_FromString(PY_BSDDB_VERSION);
9627 db_version_s = PyString_FromString(DB_VERSION_STRING);
9628 cvsid_s = PyString_FromString(rcs_id);
9629#else
9630 /* This data should be ascii, so UTF-8 conversion is fine */
9631 pybsddb_version_s = PyUnicode_FromString(PY_BSDDB_VERSION);
9632 db_version_s = PyUnicode_FromString(DB_VERSION_STRING);
9633 cvsid_s = PyUnicode_FromString(rcs_id);
9634#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009635
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009636 /* Initialize object types */
9637 if ((PyType_Ready(&DB_Type) < 0)
9638 || (PyType_Ready(&DBCursor_Type) < 0)
Jesus Cea6557aac2010-03-22 14:22:26 +00009639 || (PyType_Ready(&DBLogCursor_Type) < 0)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009640 || (PyType_Ready(&DBEnv_Type) < 0)
9641 || (PyType_Ready(&DBTxn_Type) < 0)
9642 || (PyType_Ready(&DBLock_Type) < 0)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009643 || (PyType_Ready(&DBSequence_Type) < 0)
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009644#if (DBVER >= 52)
9645 || (PyType_Ready(&DBSite_Type) < 0)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009646#endif
9647 ) {
9648#if (PY_VERSION_HEX < 0x03000000)
9649 return;
9650#else
9651 return NULL;
9652#endif
9653 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009654
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009655 /* Create the module and add the functions */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009656#if (PY_VERSION_HEX < 0x03000000)
Gregory P. Smith41631e82003-09-21 00:08:14 +00009657 m = Py_InitModule(_bsddbModuleName, bsddb_methods);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009658#else
9659 m=PyModule_Create(&bsddbmodule);
9660#endif
9661 if (m == NULL) {
9662#if (PY_VERSION_HEX < 0x03000000)
9663 return;
9664#else
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009665 return NULL;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009666#endif
9667 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009668
9669 /* Add some symbolic constants to the module */
9670 d = PyModule_GetDict(m);
9671 PyDict_SetItemString(d, "__version__", pybsddb_version_s);
9672 PyDict_SetItemString(d, "cvsid", cvsid_s);
9673 PyDict_SetItemString(d, "DB_VERSION_STRING", db_version_s);
9674 Py_DECREF(pybsddb_version_s);
9675 pybsddb_version_s = NULL;
9676 Py_DECREF(cvsid_s);
9677 cvsid_s = NULL;
9678 Py_DECREF(db_version_s);
9679 db_version_s = NULL;
9680
9681 ADD_INT(d, DB_VERSION_MAJOR);
9682 ADD_INT(d, DB_VERSION_MINOR);
9683 ADD_INT(d, DB_VERSION_PATCH);
9684
9685 ADD_INT(d, DB_MAX_PAGES);
9686 ADD_INT(d, DB_MAX_RECORDS);
9687
Matthias Klose54cc5392010-03-15 12:46:18 +00009688#if (DBVER < 48)
Gregory P. Smith41631e82003-09-21 00:08:14 +00009689 ADD_INT(d, DB_RPCCLIENT);
Matthias Klose54cc5392010-03-15 12:46:18 +00009690#endif
9691
9692#if (DBVER < 48)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009693 ADD_INT(d, DB_XA_CREATE);
Matthias Klose54cc5392010-03-15 12:46:18 +00009694#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009695
9696 ADD_INT(d, DB_CREATE);
9697 ADD_INT(d, DB_NOMMAP);
9698 ADD_INT(d, DB_THREAD);
Jesus Ceaef9764f2008-05-13 18:45:46 +00009699#if (DBVER >= 45)
9700 ADD_INT(d, DB_MULTIVERSION);
9701#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009702
9703 ADD_INT(d, DB_FORCE);
9704 ADD_INT(d, DB_INIT_CDB);
9705 ADD_INT(d, DB_INIT_LOCK);
9706 ADD_INT(d, DB_INIT_LOG);
9707 ADD_INT(d, DB_INIT_MPOOL);
9708 ADD_INT(d, DB_INIT_TXN);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009709 ADD_INT(d, DB_JOINENV);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009710
Matthias Klose54cc5392010-03-15 12:46:18 +00009711#if (DBVER >= 48)
9712 ADD_INT(d, DB_GID_SIZE);
9713#else
Jesus Ceaef9764f2008-05-13 18:45:46 +00009714 ADD_INT(d, DB_XIDDATASIZE);
Matthias Klose54cc5392010-03-15 12:46:18 +00009715 /* Allow new code to work in old BDB releases */
9716 _addIntToDict(d, "DB_GID_SIZE", DB_XIDDATASIZE);
9717#endif
Jesus Ceaef9764f2008-05-13 18:45:46 +00009718
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009719 ADD_INT(d, DB_RECOVER);
9720 ADD_INT(d, DB_RECOVER_FATAL);
9721 ADD_INT(d, DB_TXN_NOSYNC);
9722 ADD_INT(d, DB_USE_ENVIRON);
9723 ADD_INT(d, DB_USE_ENVIRON_ROOT);
9724
9725 ADD_INT(d, DB_LOCKDOWN);
9726 ADD_INT(d, DB_PRIVATE);
9727 ADD_INT(d, DB_SYSTEM_MEM);
9728
9729 ADD_INT(d, DB_TXN_SYNC);
9730 ADD_INT(d, DB_TXN_NOWAIT);
9731
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009732#if (DBVER >= 51)
9733 ADD_INT(d, DB_TXN_BULK);
9734#endif
9735
9736#if (DBVER >= 48)
9737 ADD_INT(d, DB_CURSOR_BULK);
9738#endif
9739
Jesus Cea6557aac2010-03-22 14:22:26 +00009740#if (DBVER >= 46)
9741 ADD_INT(d, DB_TXN_WAIT);
9742#endif
9743
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009744 ADD_INT(d, DB_EXCL);
9745 ADD_INT(d, DB_FCNTL_LOCKING);
9746 ADD_INT(d, DB_ODDFILESIZE);
9747 ADD_INT(d, DB_RDWRMASTER);
9748 ADD_INT(d, DB_RDONLY);
9749 ADD_INT(d, DB_TRUNCATE);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009750 ADD_INT(d, DB_EXTENT);
9751 ADD_INT(d, DB_CDB_ALLDB);
9752 ADD_INT(d, DB_VERIFY);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009753 ADD_INT(d, DB_UPGRADE);
9754
Jesus Cea6557aac2010-03-22 14:22:26 +00009755 ADD_INT(d, DB_PRINTABLE);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009756 ADD_INT(d, DB_AGGRESSIVE);
9757 ADD_INT(d, DB_NOORDERCHK);
9758 ADD_INT(d, DB_ORDERCHKONLY);
9759 ADD_INT(d, DB_PR_PAGE);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009760
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009761 ADD_INT(d, DB_PR_RECOVERYTEST);
9762 ADD_INT(d, DB_SALVAGE);
9763
9764 ADD_INT(d, DB_LOCK_NORUN);
9765 ADD_INT(d, DB_LOCK_DEFAULT);
9766 ADD_INT(d, DB_LOCK_OLDEST);
9767 ADD_INT(d, DB_LOCK_RANDOM);
9768 ADD_INT(d, DB_LOCK_YOUNGEST);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009769 ADD_INT(d, DB_LOCK_MAXLOCKS);
9770 ADD_INT(d, DB_LOCK_MINLOCKS);
9771 ADD_INT(d, DB_LOCK_MINWRITE);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009772
Jesus Ceaef9764f2008-05-13 18:45:46 +00009773 ADD_INT(d, DB_LOCK_EXPIRE);
Jesus Ceaef9764f2008-05-13 18:45:46 +00009774 ADD_INT(d, DB_LOCK_MAXWRITE);
Jesus Ceaef9764f2008-05-13 18:45:46 +00009775
Barry Warsaw9a0d7792002-12-30 20:53:52 +00009776 _addIntToDict(d, "DB_LOCK_CONFLICT", 0);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009777
9778 ADD_INT(d, DB_LOCK_DUMP);
9779 ADD_INT(d, DB_LOCK_GET);
9780 ADD_INT(d, DB_LOCK_INHERIT);
9781 ADD_INT(d, DB_LOCK_PUT);
9782 ADD_INT(d, DB_LOCK_PUT_ALL);
9783 ADD_INT(d, DB_LOCK_PUT_OBJ);
9784
9785 ADD_INT(d, DB_LOCK_NG);
9786 ADD_INT(d, DB_LOCK_READ);
9787 ADD_INT(d, DB_LOCK_WRITE);
9788 ADD_INT(d, DB_LOCK_NOWAIT);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009789 ADD_INT(d, DB_LOCK_WAIT);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009790 ADD_INT(d, DB_LOCK_IWRITE);
9791 ADD_INT(d, DB_LOCK_IREAD);
9792 ADD_INT(d, DB_LOCK_IWR);
Gregory P. Smith29602d22006-01-24 09:46:48 +00009793#if (DBVER < 44)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009794 ADD_INT(d, DB_LOCK_DIRTY);
Gregory P. Smith29602d22006-01-24 09:46:48 +00009795#else
9796 ADD_INT(d, DB_LOCK_READ_UNCOMMITTED); /* renamed in 4.4 */
9797#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009798 ADD_INT(d, DB_LOCK_WWRITE);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009799
9800 ADD_INT(d, DB_LOCK_RECORD);
9801 ADD_INT(d, DB_LOCK_UPGRADE);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009802 ADD_INT(d, DB_LOCK_SWITCH);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009803 ADD_INT(d, DB_LOCK_UPGRADE_WRITE);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009804
9805 ADD_INT(d, DB_LOCK_NOWAIT);
9806 ADD_INT(d, DB_LOCK_RECORD);
9807 ADD_INT(d, DB_LOCK_UPGRADE);
9808
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009809 ADD_INT(d, DB_LSTAT_ABORTED);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009810 ADD_INT(d, DB_LSTAT_FREE);
9811 ADD_INT(d, DB_LSTAT_HELD);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009812
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009813 ADD_INT(d, DB_LSTAT_PENDING);
9814 ADD_INT(d, DB_LSTAT_WAITING);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009815
9816 ADD_INT(d, DB_ARCH_ABS);
9817 ADD_INT(d, DB_ARCH_DATA);
9818 ADD_INT(d, DB_ARCH_LOG);
Gregory P. Smith3dd20022006-06-05 00:31:01 +00009819 ADD_INT(d, DB_ARCH_REMOVE);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009820
9821 ADD_INT(d, DB_BTREE);
9822 ADD_INT(d, DB_HASH);
9823 ADD_INT(d, DB_RECNO);
9824 ADD_INT(d, DB_QUEUE);
9825 ADD_INT(d, DB_UNKNOWN);
9826
9827 ADD_INT(d, DB_DUP);
9828 ADD_INT(d, DB_DUPSORT);
9829 ADD_INT(d, DB_RECNUM);
9830 ADD_INT(d, DB_RENUMBER);
9831 ADD_INT(d, DB_REVSPLITOFF);
9832 ADD_INT(d, DB_SNAPSHOT);
9833
Jesus Cea6557aac2010-03-22 14:22:26 +00009834 ADD_INT(d, DB_INORDER);
Jesus Cea6557aac2010-03-22 14:22:26 +00009835
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009836 ADD_INT(d, DB_JOIN_NOSORT);
9837
9838 ADD_INT(d, DB_AFTER);
9839 ADD_INT(d, DB_APPEND);
9840 ADD_INT(d, DB_BEFORE);
Gregory P. Smith8b96a352007-01-05 01:59:42 +00009841#if (DBVER < 45)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009842 ADD_INT(d, DB_CACHED_COUNTS);
Gregory P. Smith8b96a352007-01-05 01:59:42 +00009843#endif
Jesus Ceaca3939c2008-05-22 15:27:38 +00009844
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009845 ADD_INT(d, DB_CONSUME);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009846 ADD_INT(d, DB_CONSUME_WAIT);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009847 ADD_INT(d, DB_CURRENT);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009848 ADD_INT(d, DB_FAST_STAT);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009849 ADD_INT(d, DB_FIRST);
9850 ADD_INT(d, DB_FLUSH);
9851 ADD_INT(d, DB_GET_BOTH);
Jesus Cea6557aac2010-03-22 14:22:26 +00009852 ADD_INT(d, DB_GET_BOTH_RANGE);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009853 ADD_INT(d, DB_GET_RECNO);
9854 ADD_INT(d, DB_JOIN_ITEM);
9855 ADD_INT(d, DB_KEYFIRST);
9856 ADD_INT(d, DB_KEYLAST);
9857 ADD_INT(d, DB_LAST);
9858 ADD_INT(d, DB_NEXT);
9859 ADD_INT(d, DB_NEXT_DUP);
9860 ADD_INT(d, DB_NEXT_NODUP);
9861 ADD_INT(d, DB_NODUPDATA);
9862 ADD_INT(d, DB_NOOVERWRITE);
9863 ADD_INT(d, DB_NOSYNC);
9864 ADD_INT(d, DB_POSITION);
9865 ADD_INT(d, DB_PREV);
9866 ADD_INT(d, DB_PREV_NODUP);
Jesus Cea6557aac2010-03-22 14:22:26 +00009867#if (DBVER >= 46)
9868 ADD_INT(d, DB_PREV_DUP);
9869#endif
Gregory P. Smith8b96a352007-01-05 01:59:42 +00009870#if (DBVER < 45)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009871 ADD_INT(d, DB_RECORDCOUNT);
Gregory P. Smith8b96a352007-01-05 01:59:42 +00009872#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009873 ADD_INT(d, DB_SET);
9874 ADD_INT(d, DB_SET_RANGE);
9875 ADD_INT(d, DB_SET_RECNO);
9876 ADD_INT(d, DB_WRITECURSOR);
9877
9878 ADD_INT(d, DB_OPFLAGS_MASK);
9879 ADD_INT(d, DB_RMW);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009880 ADD_INT(d, DB_DIRTY_READ);
9881 ADD_INT(d, DB_MULTIPLE);
9882 ADD_INT(d, DB_MULTIPLE_KEY);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009883
Gregory P. Smith29602d22006-01-24 09:46:48 +00009884#if (DBVER >= 44)
Jesus Cea6557aac2010-03-22 14:22:26 +00009885 ADD_INT(d, DB_IMMUTABLE_KEY);
Gregory P. Smith29602d22006-01-24 09:46:48 +00009886 ADD_INT(d, DB_READ_UNCOMMITTED); /* replaces DB_DIRTY_READ in 4.4 */
9887 ADD_INT(d, DB_READ_COMMITTED);
9888#endif
9889
Jesus Cea6557aac2010-03-22 14:22:26 +00009890#if (DBVER >= 44)
9891 ADD_INT(d, DB_FREELIST_ONLY);
9892 ADD_INT(d, DB_FREE_SPACE);
9893#endif
9894
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009895 ADD_INT(d, DB_DONOTINDEX);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009896
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009897 ADD_INT(d, DB_KEYEMPTY);
9898 ADD_INT(d, DB_KEYEXIST);
9899 ADD_INT(d, DB_LOCK_DEADLOCK);
9900 ADD_INT(d, DB_LOCK_NOTGRANTED);
9901 ADD_INT(d, DB_NOSERVER);
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009902#if (DBVER < 52)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009903 ADD_INT(d, DB_NOSERVER_HOME);
9904 ADD_INT(d, DB_NOSERVER_ID);
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009905#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009906 ADD_INT(d, DB_NOTFOUND);
9907 ADD_INT(d, DB_OLD_VERSION);
9908 ADD_INT(d, DB_RUNRECOVERY);
9909 ADD_INT(d, DB_VERIFY_BAD);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009910 ADD_INT(d, DB_PAGE_NOTFOUND);
9911 ADD_INT(d, DB_SECONDARY_BAD);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009912 ADD_INT(d, DB_STAT_CLEAR);
9913 ADD_INT(d, DB_REGION_INIT);
9914 ADD_INT(d, DB_NOLOCKING);
9915 ADD_INT(d, DB_YIELDCPU);
9916 ADD_INT(d, DB_PANIC_ENVIRONMENT);
9917 ADD_INT(d, DB_NOPANIC);
Jesus Ceaef9764f2008-05-13 18:45:46 +00009918 ADD_INT(d, DB_OVERWRITE);
Jesus Cea6557aac2010-03-22 14:22:26 +00009919
Jesus Cea6557aac2010-03-22 14:22:26 +00009920 ADD_INT(d, DB_STAT_SUBSYSTEM);
9921 ADD_INT(d, DB_STAT_MEMP_HASH);
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009922 ADD_INT(d, DB_STAT_LOCK_CONF);
9923 ADD_INT(d, DB_STAT_LOCK_LOCKERS);
9924 ADD_INT(d, DB_STAT_LOCK_OBJECTS);
9925 ADD_INT(d, DB_STAT_LOCK_PARAMS);
Jesus Ceaef9764f2008-05-13 18:45:46 +00009926
Jesus Cea6557aac2010-03-22 14:22:26 +00009927#if (DBVER >= 48)
9928 ADD_INT(d, DB_OVERWRITE_DUP);
9929#endif
9930
9931#if (DBVER >= 47)
9932 ADD_INT(d, DB_FOREIGN_ABORT);
9933 ADD_INT(d, DB_FOREIGN_CASCADE);
9934 ADD_INT(d, DB_FOREIGN_NULLIFY);
9935#endif
9936
9937#if (DBVER >= 44)
Gregory P. Smithaae141a2007-11-01 21:08:14 +00009938 ADD_INT(d, DB_REGISTER);
9939#endif
9940
Jesus Cea6557aac2010-03-22 14:22:26 +00009941 ADD_INT(d, DB_EID_INVALID);
9942 ADD_INT(d, DB_EID_BROADCAST);
9943
Gregory P. Smith41631e82003-09-21 00:08:14 +00009944 ADD_INT(d, DB_TIME_NOTGRANTED);
9945 ADD_INT(d, DB_TXN_NOT_DURABLE);
9946 ADD_INT(d, DB_TXN_WRITE_NOSYNC);
Gregory P. Smith41631e82003-09-21 00:08:14 +00009947 ADD_INT(d, DB_DIRECT_DB);
9948 ADD_INT(d, DB_INIT_REP);
9949 ADD_INT(d, DB_ENCRYPT);
9950 ADD_INT(d, DB_CHKSUM);
Gregory P. Smith41631e82003-09-21 00:08:14 +00009951
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009952#if (DBVER < 47)
Jesus Ceaca3939c2008-05-22 15:27:38 +00009953 ADD_INT(d, DB_LOG_AUTOREMOVE);
9954 ADD_INT(d, DB_DIRECT_LOG);
9955#endif
9956
9957#if (DBVER >= 47)
9958 ADD_INT(d, DB_LOG_DIRECT);
9959 ADD_INT(d, DB_LOG_DSYNC);
9960 ADD_INT(d, DB_LOG_IN_MEMORY);
9961 ADD_INT(d, DB_LOG_AUTO_REMOVE);
9962 ADD_INT(d, DB_LOG_ZERO);
9963#endif
9964
Jesus Ceaef9764f2008-05-13 18:45:46 +00009965#if (DBVER >= 44)
9966 ADD_INT(d, DB_DSYNC_DB);
9967#endif
9968
9969#if (DBVER >= 45)
9970 ADD_INT(d, DB_TXN_SNAPSHOT);
9971#endif
9972
Jesus Ceaef9764f2008-05-13 18:45:46 +00009973 ADD_INT(d, DB_VERB_DEADLOCK);
9974#if (DBVER >= 46)
9975 ADD_INT(d, DB_VERB_FILEOPS);
9976 ADD_INT(d, DB_VERB_FILEOPS_ALL);
9977#endif
9978 ADD_INT(d, DB_VERB_RECOVERY);
9979#if (DBVER >= 44)
9980 ADD_INT(d, DB_VERB_REGISTER);
9981#endif
9982 ADD_INT(d, DB_VERB_REPLICATION);
9983 ADD_INT(d, DB_VERB_WAITSFOR);
Jesus Ceaef9764f2008-05-13 18:45:46 +00009984
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009985#if (DBVER >= 50)
9986 ADD_INT(d, DB_VERB_REP_SYSTEM);
9987#endif
9988
9989#if (DBVER >= 47)
9990 ADD_INT(d, DB_VERB_REP_ELECT);
9991 ADD_INT(d, DB_VERB_REP_LEASE);
9992 ADD_INT(d, DB_VERB_REP_MISC);
9993 ADD_INT(d, DB_VERB_REP_MSGS);
9994 ADD_INT(d, DB_VERB_REP_SYNC);
9995 ADD_INT(d, DB_VERB_REPMGR_CONNFAIL);
9996 ADD_INT(d, DB_VERB_REPMGR_MISC);
9997#endif
9998
Jesus Ceaef9764f2008-05-13 18:45:46 +00009999#if (DBVER >= 45)
10000 ADD_INT(d, DB_EVENT_PANIC);
10001 ADD_INT(d, DB_EVENT_REP_CLIENT);
10002#if (DBVER >= 46)
10003 ADD_INT(d, DB_EVENT_REP_ELECTED);
10004#endif
10005 ADD_INT(d, DB_EVENT_REP_MASTER);
10006 ADD_INT(d, DB_EVENT_REP_NEWMASTER);
10007#if (DBVER >= 46)
10008 ADD_INT(d, DB_EVENT_REP_PERM_FAILED);
10009#endif
10010 ADD_INT(d, DB_EVENT_REP_STARTUPDONE);
10011 ADD_INT(d, DB_EVENT_WRITE_FAILED);
10012#endif
10013
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010014#if (DBVER >= 50)
10015 ADD_INT(d, DB_REPMGR_CONF_ELECTIONS);
10016 ADD_INT(d, DB_EVENT_REP_MASTER_FAILURE);
10017 ADD_INT(d, DB_EVENT_REP_DUPMASTER);
10018 ADD_INT(d, DB_EVENT_REP_ELECTION_FAILED);
10019#endif
10020#if (DBVER >= 48)
10021 ADD_INT(d, DB_EVENT_REG_ALIVE);
10022 ADD_INT(d, DB_EVENT_REG_PANIC);
10023#endif
10024
10025#if (DBVER >=52)
10026 ADD_INT(d, DB_EVENT_REP_SITE_ADDED);
10027 ADD_INT(d, DB_EVENT_REP_SITE_REMOVED);
10028 ADD_INT(d, DB_EVENT_REP_LOCAL_SITE_REMOVED);
10029 ADD_INT(d, DB_EVENT_REP_CONNECT_BROKEN);
10030 ADD_INT(d, DB_EVENT_REP_CONNECT_ESTD);
10031 ADD_INT(d, DB_EVENT_REP_CONNECT_TRY_FAILED);
10032 ADD_INT(d, DB_EVENT_REP_INIT_DONE);
10033
10034 ADD_INT(d, DB_MEM_LOCK);
10035 ADD_INT(d, DB_MEM_LOCKOBJECT);
10036 ADD_INT(d, DB_MEM_LOCKER);
10037 ADD_INT(d, DB_MEM_LOGID);
10038 ADD_INT(d, DB_MEM_TRANSACTION);
10039 ADD_INT(d, DB_MEM_THREAD);
10040
10041 ADD_INT(d, DB_BOOTSTRAP_HELPER);
10042 ADD_INT(d, DB_GROUP_CREATOR);
10043 ADD_INT(d, DB_LEGACY);
10044 ADD_INT(d, DB_LOCAL_SITE);
10045 ADD_INT(d, DB_REPMGR_PEER);
10046#endif
10047
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010048 ADD_INT(d, DB_REP_DUPMASTER);
10049 ADD_INT(d, DB_REP_HOLDELECTION);
10050#if (DBVER >= 44)
10051 ADD_INT(d, DB_REP_IGNORE);
10052 ADD_INT(d, DB_REP_JOIN_FAILURE);
10053#endif
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010054 ADD_INT(d, DB_REP_ISPERM);
10055 ADD_INT(d, DB_REP_NOTPERM);
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010056 ADD_INT(d, DB_REP_NEWSITE);
10057
Jesus Ceaef9764f2008-05-13 18:45:46 +000010058 ADD_INT(d, DB_REP_MASTER);
10059 ADD_INT(d, DB_REP_CLIENT);
Jesus Cea6557aac2010-03-22 14:22:26 +000010060
10061 ADD_INT(d, DB_REP_PERMANENT);
10062
10063#if (DBVER >= 44)
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010064#if (DBVER >= 50)
10065 ADD_INT(d, DB_REP_CONF_AUTOINIT);
10066#else
Jesus Cea6557aac2010-03-22 14:22:26 +000010067 ADD_INT(d, DB_REP_CONF_NOAUTOINIT);
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010068#endif /* 5.0 */
10069#endif /* 4.4 */
10070#if (DBVER >= 44)
Jesus Cea6557aac2010-03-22 14:22:26 +000010071 ADD_INT(d, DB_REP_CONF_DELAYCLIENT);
10072 ADD_INT(d, DB_REP_CONF_BULK);
10073 ADD_INT(d, DB_REP_CONF_NOWAIT);
10074 ADD_INT(d, DB_REP_ANYWHERE);
10075 ADD_INT(d, DB_REP_REREQUEST);
10076#endif
10077
Jesus Cea6557aac2010-03-22 14:22:26 +000010078 ADD_INT(d, DB_REP_NOBUFFER);
Jesus Cea6557aac2010-03-22 14:22:26 +000010079
10080#if (DBVER >= 46)
10081 ADD_INT(d, DB_REP_LEASE_EXPIRED);
10082 ADD_INT(d, DB_IGNORE_LEASE);
10083#endif
10084
10085#if (DBVER >= 47)
10086 ADD_INT(d, DB_REP_CONF_LEASE);
10087 ADD_INT(d, DB_REPMGR_CONF_2SITE_STRICT);
10088#endif
10089
Jesus Ceaef9764f2008-05-13 18:45:46 +000010090#if (DBVER >= 45)
10091 ADD_INT(d, DB_REP_ELECTION);
10092
10093 ADD_INT(d, DB_REP_ACK_TIMEOUT);
10094 ADD_INT(d, DB_REP_CONNECTION_RETRY);
10095 ADD_INT(d, DB_REP_ELECTION_TIMEOUT);
10096 ADD_INT(d, DB_REP_ELECTION_RETRY);
10097#endif
10098#if (DBVER >= 46)
10099 ADD_INT(d, DB_REP_CHECKPOINT_DELAY);
10100 ADD_INT(d, DB_REP_FULL_ELECTION_TIMEOUT);
Jesus Cea6557aac2010-03-22 14:22:26 +000010101 ADD_INT(d, DB_REP_LEASE_TIMEOUT);
10102#endif
10103#if (DBVER >= 47)
10104 ADD_INT(d, DB_REP_HEARTBEAT_MONITOR);
10105 ADD_INT(d, DB_REP_HEARTBEAT_SEND);
Jesus Ceaef9764f2008-05-13 18:45:46 +000010106#endif
Jesus Ceaef9764f2008-05-13 18:45:46 +000010107
10108#if (DBVER >= 45)
10109 ADD_INT(d, DB_REPMGR_PEER);
10110 ADD_INT(d, DB_REPMGR_ACKS_ALL);
10111 ADD_INT(d, DB_REPMGR_ACKS_ALL_PEERS);
10112 ADD_INT(d, DB_REPMGR_ACKS_NONE);
10113 ADD_INT(d, DB_REPMGR_ACKS_ONE);
10114 ADD_INT(d, DB_REPMGR_ACKS_ONE_PEER);
10115 ADD_INT(d, DB_REPMGR_ACKS_QUORUM);
10116 ADD_INT(d, DB_REPMGR_CONNECTED);
10117 ADD_INT(d, DB_REPMGR_DISCONNECTED);
Jesus Ceaef9764f2008-05-13 18:45:46 +000010118 ADD_INT(d, DB_STAT_ALL);
10119#endif
10120
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010121#if (DBVER >= 51)
10122 ADD_INT(d, DB_REPMGR_ACKS_ALL_AVAILABLE);
10123#endif
10124
10125#if (DBVER >= 48)
10126 ADD_INT(d, DB_REP_CONF_INMEM);
10127#endif
10128
10129 ADD_INT(d, DB_TIMEOUT);
10130
10131#if (DBVER >= 50)
10132 ADD_INT(d, DB_FORCESYNC);
10133#endif
10134
10135#if (DBVER >= 48)
10136 ADD_INT(d, DB_FAILCHK);
10137#endif
10138
10139#if (DBVER >= 51)
10140 ADD_INT(d, DB_HOTBACKUP_IN_PROGRESS);
10141#endif
10142
Gregory P. Smith8b7e9172004-12-13 09:51:23 +000010143 ADD_INT(d, DB_BUFFER_SMALL);
Gregory P. Smithf0547d02006-06-05 17:38:04 +000010144 ADD_INT(d, DB_SEQ_DEC);
10145 ADD_INT(d, DB_SEQ_INC);
10146 ADD_INT(d, DB_SEQ_WRAP);
Gregory P. Smith8b7e9172004-12-13 09:51:23 +000010147
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010148#if (DBVER < 47)
Jesus Ceaca3939c2008-05-22 15:27:38 +000010149 ADD_INT(d, DB_LOG_INMEMORY);
10150 ADD_INT(d, DB_DSYNC_LOG);
10151#endif
10152
Barry Warsaw9a0d7792002-12-30 20:53:52 +000010153 ADD_INT(d, DB_ENCRYPT_AES);
10154 ADD_INT(d, DB_AUTO_COMMIT);
Jesus Cea6557aac2010-03-22 14:22:26 +000010155 ADD_INT(d, DB_PRIORITY_VERY_LOW);
10156 ADD_INT(d, DB_PRIORITY_LOW);
10157 ADD_INT(d, DB_PRIORITY_DEFAULT);
10158 ADD_INT(d, DB_PRIORITY_HIGH);
10159 ADD_INT(d, DB_PRIORITY_VERY_HIGH);
10160
10161#if (DBVER >= 46)
10162 ADD_INT(d, DB_PRIORITY_UNCHANGED);
Barry Warsaw9a0d7792002-12-30 20:53:52 +000010163#endif
10164
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010165 ADD_INT(d, EINVAL);
10166 ADD_INT(d, EACCES);
10167 ADD_INT(d, ENOSPC);
10168 ADD_INT(d, ENOMEM);
10169 ADD_INT(d, EAGAIN);
10170 ADD_INT(d, EBUSY);
10171 ADD_INT(d, EEXIST);
10172 ADD_INT(d, ENOENT);
10173 ADD_INT(d, EPERM);
10174
Barry Warsaw1baa9822003-03-31 19:51:29 +000010175 ADD_INT(d, DB_SET_LOCK_TIMEOUT);
10176 ADD_INT(d, DB_SET_TXN_TIMEOUT);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010177
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010178#if (DBVER >= 48)
10179 ADD_INT(d, DB_SET_REG_TIMEOUT);
10180#endif
10181
Gregory P. Smith7f5b6f42006-04-08 07:10:51 +000010182 /* The exception name must be correct for pickled exception *
10183 * objects to unpickle properly. */
10184#ifdef PYBSDDB_STANDALONE /* different value needed for standalone pybsddb */
10185#define PYBSDDB_EXCEPTION_BASE "bsddb3.db."
10186#else
10187#define PYBSDDB_EXCEPTION_BASE "bsddb.db."
10188#endif
10189
10190 /* All the rest of the exceptions derive only from DBError */
10191#define MAKE_EX(name) name = PyErr_NewException(PYBSDDB_EXCEPTION_BASE #name, DBError, NULL); \
10192 PyDict_SetItemString(d, #name, name)
10193
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010194 /* The base exception class is DBError */
Gregory P. Smith7f5b6f42006-04-08 07:10:51 +000010195 DBError = NULL; /* used in MAKE_EX so that it derives from nothing */
10196 MAKE_EX(DBError);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010197
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010198#if (PY_VERSION_HEX < 0x03000000)
Gregory P. Smithe9477062005-06-04 06:46:59 +000010199 /* Some magic to make DBNotFoundError and DBKeyEmptyError derive
10200 * from both DBError and KeyError, since the API only supports
10201 * using one base class. */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010202 PyDict_SetItemString(d, "KeyError", PyExc_KeyError);
Gregory P. Smithe9477062005-06-04 06:46:59 +000010203 PyRun_String("class DBNotFoundError(DBError, KeyError): pass\n"
Antoine Pitrouc83ea132010-05-09 14:46:46 +000010204 "class DBKeyEmptyError(DBError, KeyError): pass",
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010205 Py_file_input, d, d);
10206 DBNotFoundError = PyDict_GetItemString(d, "DBNotFoundError");
Gregory P. Smithe9477062005-06-04 06:46:59 +000010207 DBKeyEmptyError = PyDict_GetItemString(d, "DBKeyEmptyError");
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010208 PyDict_DelItemString(d, "KeyError");
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010209#else
10210 /* Since Python 2.5, PyErr_NewException() accepts a tuple, to be able to
10211 ** derive from several classes. We use this new API only for Python 3.0,
10212 ** though.
10213 */
10214 {
10215 PyObject* bases;
10216
10217 bases = PyTuple_Pack(2, DBError, PyExc_KeyError);
10218
10219#define MAKE_EX2(name) name = PyErr_NewException(PYBSDDB_EXCEPTION_BASE #name, bases, NULL); \
10220 PyDict_SetItemString(d, #name, name)
10221 MAKE_EX2(DBNotFoundError);
10222 MAKE_EX2(DBKeyEmptyError);
10223
10224#undef MAKE_EX2
10225
10226 Py_XDECREF(bases);
10227 }
10228#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010229
Gregory P. Smithe2767172003-11-02 08:06:29 +000010230 MAKE_EX(DBCursorClosedError);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010231 MAKE_EX(DBKeyExistError);
10232 MAKE_EX(DBLockDeadlockError);
10233 MAKE_EX(DBLockNotGrantedError);
10234 MAKE_EX(DBOldVersionError);
10235 MAKE_EX(DBRunRecoveryError);
10236 MAKE_EX(DBVerifyBadError);
10237 MAKE_EX(DBNoServerError);
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010238#if (DBVER < 52)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010239 MAKE_EX(DBNoServerHomeError);
10240 MAKE_EX(DBNoServerIDError);
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010241#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010242 MAKE_EX(DBPageNotFoundError);
10243 MAKE_EX(DBSecondaryBadError);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010244
10245 MAKE_EX(DBInvalidArgError);
10246 MAKE_EX(DBAccessError);
10247 MAKE_EX(DBNoSpaceError);
10248 MAKE_EX(DBNoMemoryError);
10249 MAKE_EX(DBAgainError);
10250 MAKE_EX(DBBusyError);
10251 MAKE_EX(DBFileExistsError);
10252 MAKE_EX(DBNoSuchFileError);
10253 MAKE_EX(DBPermissionsError);
10254
Jesus Ceaef9764f2008-05-13 18:45:46 +000010255 MAKE_EX(DBRepHandleDeadError);
Jesus Cea6557aac2010-03-22 14:22:26 +000010256#if (DBVER >= 44)
10257 MAKE_EX(DBRepLockoutError);
10258#endif
Jesus Ceaef9764f2008-05-13 18:45:46 +000010259
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010260 MAKE_EX(DBRepUnavailError);
10261
Jesus Cea6557aac2010-03-22 14:22:26 +000010262#if (DBVER >= 46)
10263 MAKE_EX(DBRepLeaseExpiredError);
10264#endif
10265
10266#if (DBVER >= 47)
10267 MAKE_EX(DBForeignConflictError);
10268#endif
10269
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010270#undef MAKE_EX
10271
Jesus Cea6557aac2010-03-22 14:22:26 +000010272 /* Initialise the C API structure and add it to the module */
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010273 bsddb_api.api_version = PYBSDDB_API_VERSION;
Jesus Cea6557aac2010-03-22 14:22:26 +000010274 bsddb_api.db_type = &DB_Type;
10275 bsddb_api.dbcursor_type = &DBCursor_Type;
10276 bsddb_api.dblogcursor_type = &DBLogCursor_Type;
10277 bsddb_api.dbenv_type = &DBEnv_Type;
10278 bsddb_api.dbtxn_type = &DBTxn_Type;
10279 bsddb_api.dblock_type = &DBLock_Type;
Jesus Cea6557aac2010-03-22 14:22:26 +000010280 bsddb_api.dbsequence_type = &DBSequence_Type;
Jesus Cea6557aac2010-03-22 14:22:26 +000010281 bsddb_api.makeDBError = makeDBError;
Gregory P. Smith39250532007-10-09 06:02:21 +000010282
Jesus Cea6557aac2010-03-22 14:22:26 +000010283 /*
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010284 ** Capsules exist from Python 2.7 and 3.1.
10285 ** We don't support Python 3.0 anymore, so...
10286 ** #if (PY_VERSION_HEX < ((PY_MAJOR_VERSION < 3) ? 0x02070000 : 0x03020000))
Jesus Cea6557aac2010-03-22 14:22:26 +000010287 */
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010288#if (PY_VERSION_HEX < 0x02070000)
Gregory P. Smith39250532007-10-09 06:02:21 +000010289 py_api = PyCObject_FromVoidPtr((void*)&bsddb_api, NULL);
Jesus Cea6557aac2010-03-22 14:22:26 +000010290#else
10291 {
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010292 /*
10293 ** The data must outlive the call!!. So, the static definition.
10294 ** The buffer must be big enough...
10295 */
10296 static char py_api_name[MODULE_NAME_MAX_LEN+10];
Jesus Cea6557aac2010-03-22 14:22:26 +000010297
10298 strcpy(py_api_name, _bsddbModuleName);
10299 strcat(py_api_name, ".api");
10300
10301 py_api = PyCapsule_New((void*)&bsddb_api, py_api_name, NULL);
10302 }
10303#endif
10304
Jesus Cea84f2c322010-11-05 00:13:50 +000010305 /* Check error control */
10306 /*
10307 ** PyErr_NoMemory();
10308 ** py_api = NULL;
10309 */
10310
10311 if (py_api) {
10312 PyDict_SetItemString(d, "api", py_api);
10313 Py_DECREF(py_api);
10314 } else { /* Something bad happened */
10315 PyErr_WriteUnraisable(m);
Jesus Ceabf088f82010-11-08 12:57:59 +000010316 if(PyErr_Warn(PyExc_RuntimeWarning,
10317 "_bsddb/_pybsddb C API will be not available")) {
10318 PyErr_WriteUnraisable(m);
10319 }
Jesus Cea84f2c322010-11-05 00:13:50 +000010320 PyErr_Clear();
10321 }
Gregory P. Smith39250532007-10-09 06:02:21 +000010322
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010323 /* Check for errors */
10324 if (PyErr_Occurred()) {
10325 PyErr_Print();
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010326 Py_FatalError("can't initialize module _bsddb/_pybsddb");
10327 Py_DECREF(m);
10328 m = NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010329 }
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010330#if (PY_VERSION_HEX < 0x03000000)
10331 return;
10332#else
10333 return m;
10334#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010335}
Gregory P. Smith41631e82003-09-21 00:08:14 +000010336
10337/* allow this module to be named _pybsddb so that it can be installed
10338 * and imported on top of python >= 2.3 that includes its own older
10339 * copy of the library named _bsddb without importing the old version. */
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010340#if (PY_VERSION_HEX < 0x03000000)
Gregory P. Smith41631e82003-09-21 00:08:14 +000010341DL_EXPORT(void) init_pybsddb(void)
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010342#else
10343PyMODINIT_FUNC PyInit__pybsddb(void) /* Note the two underscores */
10344#endif
Gregory P. Smith41631e82003-09-21 00:08:14 +000010345{
10346 strncpy(_bsddbModuleName, "_pybsddb", MODULE_NAME_MAX_LEN);
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010347#if (PY_VERSION_HEX < 0x03000000)
Gregory P. Smith41631e82003-09-21 00:08:14 +000010348 init_bsddb();
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010349#else
10350 return PyInit__bsddb(); /* Note the two underscores */
10351#endif
Gregory P. Smith41631e82003-09-21 00:08:14 +000010352}