blob: 408efc3f636927ecd46c24c9774690fec4a8f0fb [file] [log] [blame]
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001/*----------------------------------------------------------------------
2 Copyright (c) 1999-2001, Digital Creations, Fredericksburg, VA, USA
3 and Andrew Kuchling. All rights reserved.
4
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are
7 met:
8
9 o Redistributions of source code must retain the above copyright
10 notice, this list of conditions, and the disclaimer that follows.
11
12 o Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions, and the following disclaimer in
14 the documentation and/or other materials provided with the
15 distribution.
16
17 o Neither the name of Digital Creations nor the names of its
18 contributors may be used to endorse or promote products derived
19 from this software without specific prior written permission.
20
21 THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS AND CONTRIBUTORS *AS
22 IS* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
23 TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
24 PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL
25 CREATIONS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
28 OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
29 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
30 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
31 USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
32 DAMAGE.
33------------------------------------------------------------------------*/
34
35
36/*
37 * Handwritten code to wrap version 3.x of the Berkeley DB library,
Barry Warsaw9a0d7792002-12-30 20:53:52 +000038 * written to replace a SWIG-generated file. It has since been updated
Jesus Ceaef9764f2008-05-13 18:45:46 +000039 * to compile with Berkeley DB versions 3.2 through 4.2.
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000040 *
41 * This module was started by Andrew Kuchling to remove the dependency
Gregory P. Smithf8057852007-09-09 20:25:00 +000042 * on SWIG in a package by Gregory P. Smith who based his work on a
43 * similar package by Robin Dunn <robin@alldunn.com> which wrapped
44 * Berkeley DB 2.7.x.
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000045 *
Barry Warsaw9a0d7792002-12-30 20:53:52 +000046 * Development of this module then returned full circle back to Robin Dunn
47 * who worked on behalf of Digital Creations to complete the wrapping of
48 * the DB 3.x API and to build a solid unit test suite. Robin has
49 * since gone onto other projects (wxPython).
50 *
Jesus Ceaef9764f2008-05-13 18:45:46 +000051 * Gregory P. Smith <greg@krypto.org> was once again the maintainer.
52 *
Jesus Ceaca3939c2008-05-22 15:27:38 +000053 * Since January 2008, new maintainer is Jesus Cea <jcea@jcea.es>.
Jesus Ceaef9764f2008-05-13 18:45:46 +000054 * Jesus Cea licenses this code to PSF under a Contributor Agreement.
Barry Warsaw9a0d7792002-12-30 20:53:52 +000055 *
56 * Use the pybsddb-users@lists.sf.net mailing list for all questions.
Barry Warsawc74e4a52003-04-24 14:28:08 +000057 * Things can change faster than the header of this file is updated. This
58 * file is shared with the PyBSDDB project at SourceForge:
59 *
60 * http://pybsddb.sf.net
61 *
62 * This file should remain backward compatible with Python 2.1, but see PEP
63 * 291 for the most current backward compatibility requirements:
64 *
65 * http://www.python.org/peps/pep-0291.html
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000066 *
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070067 * This module contains 7 types:
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000068 *
69 * DB (Database)
70 * DBCursor (Database Cursor)
71 * DBEnv (database environment)
72 * DBTxn (An explicit database transaction)
73 * DBLock (A lock handle)
Gregory P. Smithf0547d02006-06-05 17:38:04 +000074 * DBSequence (Sequence)
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070075 * DBSite (Site)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000076 *
Jesus Cea6557aac2010-03-22 14:22:26 +000077 * More datatypes added:
78 *
79 * DBLogCursor (Log Cursor)
80 *
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000081 */
82
83/* --------------------------------------------------------------------- */
84
85/*
86 * Portions of this module, associated unit tests and build scripts are the
87 * result of a contract with The Written Word (http://thewrittenword.com/)
88 * Many thanks go out to them for causing me to raise the bar on quality and
89 * functionality, resulting in a better bsddb3 package for all of us to use.
90 *
91 * --Robin
92 */
93
94/* --------------------------------------------------------------------- */
95
Gregory P. Smitha703a212003-11-03 01:04:41 +000096#include <stddef.h> /* for offsetof() */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000097#include <Python.h>
Gregory P. Smith39250532007-10-09 06:02:21 +000098
99#define COMPILING_BSDDB_C
100#include "bsddb.h"
101#undef COMPILING_BSDDB_C
102
103static char *rcs_id = "$Id$";
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000104
105/* --------------------------------------------------------------------- */
106/* Various macro definitions */
107
Gregory P. Smith7f5b6f42006-04-08 07:10:51 +0000108#if (PY_VERSION_HEX < 0x02050000)
Neal Norwitz09a29fa2006-06-12 02:05:55 +0000109typedef int Py_ssize_t;
Gregory P. Smith7f5b6f42006-04-08 07:10:51 +0000110#endif
111
Gregory P. Smith572226c2008-05-26 19:03:35 +0000112#if (PY_VERSION_HEX < 0x02060000) /* really: before python trunk r63675 */
113/* This code now uses PyBytes* API function names instead of PyString*.
114 * These #defines map to their equivalent on earlier python versions. */
115#define PyBytes_FromStringAndSize PyString_FromStringAndSize
116#define PyBytes_FromString PyString_FromString
117#define PyBytes_AsStringAndSize PyString_AsStringAndSize
118#define PyBytes_Check PyString_Check
119#define PyBytes_GET_SIZE PyString_GET_SIZE
120#define PyBytes_AS_STRING PyString_AS_STRING
121#endif
122
Jesus Ceac5a11fa2008-07-23 11:38:42 +0000123#if (PY_VERSION_HEX >= 0x03000000)
124#define NUMBER_Check PyLong_Check
125#define NUMBER_AsLong PyLong_AsLong
126#define NUMBER_FromLong PyLong_FromLong
127#else
128#define NUMBER_Check PyInt_Check
129#define NUMBER_AsLong PyInt_AsLong
130#define NUMBER_FromLong PyInt_FromLong
131#endif
132
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000133#ifdef WITH_THREAD
134
135/* These are for when calling Python --> C */
136#define MYDB_BEGIN_ALLOW_THREADS Py_BEGIN_ALLOW_THREADS;
137#define MYDB_END_ALLOW_THREADS Py_END_ALLOW_THREADS;
138
139/* and these are for calling C --> Python */
Mark Hammonda69d4092003-04-22 23:13:27 +0000140#define MYDB_BEGIN_BLOCK_THREADS \
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000141 PyGILState_STATE __savestate = PyGILState_Ensure();
Mark Hammonda69d4092003-04-22 23:13:27 +0000142#define MYDB_END_BLOCK_THREADS \
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000143 PyGILState_Release(__savestate);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000144
145#else
Mark Hammonda69d4092003-04-22 23:13:27 +0000146/* Compiled without threads - avoid all this cruft */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000147#define MYDB_BEGIN_ALLOW_THREADS
148#define MYDB_END_ALLOW_THREADS
149#define MYDB_BEGIN_BLOCK_THREADS
150#define MYDB_END_BLOCK_THREADS
151
152#endif
153
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000154/* --------------------------------------------------------------------- */
155/* Exceptions */
156
157static PyObject* DBError; /* Base class, all others derive from this */
Gregory P. Smithe2767172003-11-02 08:06:29 +0000158static PyObject* DBCursorClosedError; /* raised when trying to use a closed cursor object */
Gregory P. Smithe9477062005-06-04 06:46:59 +0000159static PyObject* DBKeyEmptyError; /* DB_KEYEMPTY: also derives from KeyError */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000160static PyObject* DBKeyExistError; /* DB_KEYEXIST */
161static PyObject* DBLockDeadlockError; /* DB_LOCK_DEADLOCK */
162static PyObject* DBLockNotGrantedError; /* DB_LOCK_NOTGRANTED */
163static PyObject* DBNotFoundError; /* DB_NOTFOUND: also derives from KeyError */
164static PyObject* DBOldVersionError; /* DB_OLD_VERSION */
165static PyObject* DBRunRecoveryError; /* DB_RUNRECOVERY */
166static PyObject* DBVerifyBadError; /* DB_VERIFY_BAD */
167static PyObject* DBNoServerError; /* DB_NOSERVER */
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -0700168#if (DBVER < 52)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000169static PyObject* DBNoServerHomeError; /* DB_NOSERVER_HOME */
170static PyObject* DBNoServerIDError; /* DB_NOSERVER_ID */
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -0700171#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000172static PyObject* DBPageNotFoundError; /* DB_PAGE_NOTFOUND */
173static PyObject* DBSecondaryBadError; /* DB_SECONDARY_BAD */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000174
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000175static PyObject* DBInvalidArgError; /* EINVAL */
176static PyObject* DBAccessError; /* EACCES */
177static PyObject* DBNoSpaceError; /* ENOSPC */
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -0700178static PyObject* DBNoMemoryError; /* DB_BUFFER_SMALL */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000179static PyObject* DBAgainError; /* EAGAIN */
180static PyObject* DBBusyError; /* EBUSY */
181static PyObject* DBFileExistsError; /* EEXIST */
182static PyObject* DBNoSuchFileError; /* ENOENT */
183static PyObject* DBPermissionsError; /* EPERM */
184
Jesus Ceaef9764f2008-05-13 18:45:46 +0000185static PyObject* DBRepHandleDeadError; /* DB_REP_HANDLE_DEAD */
Jesus Cea6557aac2010-03-22 14:22:26 +0000186#if (DBVER >= 44)
187static PyObject* DBRepLockoutError; /* DB_REP_LOCKOUT */
188#endif
189
190#if (DBVER >= 46)
191static PyObject* DBRepLeaseExpiredError; /* DB_REP_LEASE_EXPIRED */
192#endif
193
194#if (DBVER >= 47)
195static PyObject* DBForeignConflictError; /* DB_FOREIGN_CONFLICT */
196#endif
197
Jesus Ceaef9764f2008-05-13 18:45:46 +0000198
Jesus Ceac5a11fa2008-07-23 11:38:42 +0000199static PyObject* DBRepUnavailError; /* DB_REP_UNAVAIL */
200
Matthias Klose54cc5392010-03-15 12:46:18 +0000201#if (DBVER < 48)
202#define DB_GID_SIZE DB_XIDDATASIZE
203#endif
204
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000205
206/* --------------------------------------------------------------------- */
207/* Structure definitions */
208
Gregory P. Smith39250532007-10-09 06:02:21 +0000209#if PYTHON_API_VERSION < 1010
210#error "Python 2.1 or later required"
Gregory P. Smitha703a212003-11-03 01:04:41 +0000211#endif
212
Gregory P. Smith31c50652004-06-28 01:20:40 +0000213
Gregory P. Smith39250532007-10-09 06:02:21 +0000214/* Defaults for moduleFlags in DBEnvObject and DBObject. */
Gregory P. Smith455d46f2003-07-09 04:45:59 +0000215#define DEFAULT_GET_RETURNS_NONE 1
Gregory P. Smitha703a212003-11-03 01:04:41 +0000216#define DEFAULT_CURSOR_SET_RETURNS_NONE 1 /* 0 in pybsddb < 4.2, python < 2.4 */
Gregory P. Smith455d46f2003-07-09 04:45:59 +0000217
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000218
Jesus Ceac5a11fa2008-07-23 11:38:42 +0000219/* See comment in Python 2.6 "object.h" */
220#ifndef staticforward
221#define staticforward static
222#endif
223#ifndef statichere
224#define statichere static
225#endif
226
227staticforward PyTypeObject DB_Type, DBCursor_Type, DBEnv_Type, DBTxn_Type,
Jesus Cea6557aac2010-03-22 14:22:26 +0000228 DBLock_Type, DBLogCursor_Type;
Jesus Ceaef9764f2008-05-13 18:45:46 +0000229staticforward PyTypeObject DBSequence_Type;
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -0700230#if (DBVER >= 52)
231staticforward PyTypeObject DBSite_Type;
Jesus Ceaef9764f2008-05-13 18:45:46 +0000232#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000233
Martin v. Löwis83c92012008-04-24 13:17:24 +0000234#ifndef Py_TYPE
Gregory P. Smithfc006692007-11-05 09:06:28 +0000235/* for compatibility with Python 2.5 and earlier */
Christian Heimese93237d2007-12-19 02:37:44 +0000236#define Py_TYPE(ob) (((PyObject*)(ob))->ob_type)
Gregory P. Smithfc006692007-11-05 09:06:28 +0000237#endif
238
Christian Heimese93237d2007-12-19 02:37:44 +0000239#define DBObject_Check(v) (Py_TYPE(v) == &DB_Type)
240#define DBCursorObject_Check(v) (Py_TYPE(v) == &DBCursor_Type)
Jesus Cea6557aac2010-03-22 14:22:26 +0000241#define DBLogCursorObject_Check(v) (Py_TYPE(v) == &DBLogCursor_Type)
Christian Heimese93237d2007-12-19 02:37:44 +0000242#define DBEnvObject_Check(v) (Py_TYPE(v) == &DBEnv_Type)
243#define DBTxnObject_Check(v) (Py_TYPE(v) == &DBTxn_Type)
244#define DBLockObject_Check(v) (Py_TYPE(v) == &DBLock_Type)
Christian Heimese93237d2007-12-19 02:37:44 +0000245#define DBSequenceObject_Check(v) (Py_TYPE(v) == &DBSequence_Type)
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -0700246#if (DBVER >= 52)
247#define DBSiteObject_Check(v) (Py_TYPE(v) == &DBSite_Type)
Gregory P. Smithf0547d02006-06-05 17:38:04 +0000248#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000249
Jesus Ceaef9764f2008-05-13 18:45:46 +0000250#if (DBVER < 46)
251 #define _DBC_close(dbc) dbc->c_close(dbc)
252 #define _DBC_count(dbc,a,b) dbc->c_count(dbc,a,b)
253 #define _DBC_del(dbc,a) dbc->c_del(dbc,a)
254 #define _DBC_dup(dbc,a,b) dbc->c_dup(dbc,a,b)
255 #define _DBC_get(dbc,a,b,c) dbc->c_get(dbc,a,b,c)
256 #define _DBC_pget(dbc,a,b,c,d) dbc->c_pget(dbc,a,b,c,d)
257 #define _DBC_put(dbc,a,b,c) dbc->c_put(dbc,a,b,c)
258#else
259 #define _DBC_close(dbc) dbc->close(dbc)
260 #define _DBC_count(dbc,a,b) dbc->count(dbc,a,b)
261 #define _DBC_del(dbc,a) dbc->del(dbc,a)
262 #define _DBC_dup(dbc,a,b) dbc->dup(dbc,a,b)
263 #define _DBC_get(dbc,a,b,c) dbc->get(dbc,a,b,c)
264 #define _DBC_pget(dbc,a,b,c,d) dbc->pget(dbc,a,b,c,d)
265 #define _DBC_put(dbc,a,b,c) dbc->put(dbc,a,b,c)
266#endif
267
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000268
269/* --------------------------------------------------------------------- */
270/* Utility macros and functions */
271
Jesus Ceaef9764f2008-05-13 18:45:46 +0000272#define INSERT_IN_DOUBLE_LINKED_LIST(backlink,object) \
273 { \
274 object->sibling_next=backlink; \
275 object->sibling_prev_p=&(backlink); \
276 backlink=object; \
277 if (object->sibling_next) { \
278 object->sibling_next->sibling_prev_p=&(object->sibling_next); \
279 } \
280 }
281
282#define EXTRACT_FROM_DOUBLE_LINKED_LIST(object) \
283 { \
284 if (object->sibling_next) { \
285 object->sibling_next->sibling_prev_p=object->sibling_prev_p; \
286 } \
287 *(object->sibling_prev_p)=object->sibling_next; \
288 }
289
290#define EXTRACT_FROM_DOUBLE_LINKED_LIST_MAYBE_NULL(object) \
291 { \
292 if (object->sibling_next) { \
293 object->sibling_next->sibling_prev_p=object->sibling_prev_p; \
294 } \
295 if (object->sibling_prev_p) { \
296 *(object->sibling_prev_p)=object->sibling_next; \
297 } \
298 }
299
300#define INSERT_IN_DOUBLE_LINKED_LIST_TXN(backlink,object) \
301 { \
302 object->sibling_next_txn=backlink; \
303 object->sibling_prev_p_txn=&(backlink); \
304 backlink=object; \
305 if (object->sibling_next_txn) { \
306 object->sibling_next_txn->sibling_prev_p_txn= \
307 &(object->sibling_next_txn); \
308 } \
309 }
310
311#define EXTRACT_FROM_DOUBLE_LINKED_LIST_TXN(object) \
312 { \
313 if (object->sibling_next_txn) { \
314 object->sibling_next_txn->sibling_prev_p_txn= \
315 object->sibling_prev_p_txn; \
316 } \
317 *(object->sibling_prev_p_txn)=object->sibling_next_txn; \
318 }
319
320
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000321#define RETURN_IF_ERR() \
322 if (makeDBError(err)) { \
323 return NULL; \
324 }
325
326#define RETURN_NONE() Py_INCREF(Py_None); return Py_None;
327
Gregory P. Smithe2767172003-11-02 08:06:29 +0000328#define _CHECK_OBJECT_NOT_CLOSED(nonNull, pyErrObj, name) \
329 if ((nonNull) == NULL) { \
330 PyObject *errTuple = NULL; \
331 errTuple = Py_BuildValue("(is)", 0, #name " object has been closed"); \
Jesus Ceac5a11fa2008-07-23 11:38:42 +0000332 if (errTuple) { \
333 PyErr_SetObject((pyErrObj), errTuple); \
334 Py_DECREF(errTuple); \
335 } \
Gregory P. Smithe2767172003-11-02 08:06:29 +0000336 return NULL; \
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000337 }
338
Gregory P. Smithe2767172003-11-02 08:06:29 +0000339#define CHECK_DB_NOT_CLOSED(dbobj) \
340 _CHECK_OBJECT_NOT_CLOSED(dbobj->db, DBError, DB)
341
342#define CHECK_ENV_NOT_CLOSED(env) \
343 _CHECK_OBJECT_NOT_CLOSED(env->db_env, DBError, DBEnv)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000344
345#define CHECK_CURSOR_NOT_CLOSED(curs) \
Gregory P. Smithe2767172003-11-02 08:06:29 +0000346 _CHECK_OBJECT_NOT_CLOSED(curs->dbc, DBCursorClosedError, DBCursor)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000347
Jesus Cea6557aac2010-03-22 14:22:26 +0000348#define CHECK_LOGCURSOR_NOT_CLOSED(logcurs) \
349 _CHECK_OBJECT_NOT_CLOSED(logcurs->logc, DBCursorClosedError, DBLogCursor)
350
Gregory P. Smithf0547d02006-06-05 17:38:04 +0000351#define CHECK_SEQUENCE_NOT_CLOSED(curs) \
352 _CHECK_OBJECT_NOT_CLOSED(curs->sequence, DBError, DBSequence)
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -0700353
354#if (DBVER >= 52)
355#define CHECK_SITE_NOT_CLOSED(db_site) \
356 _CHECK_OBJECT_NOT_CLOSED(db_site->site, DBError, DBSite)
Gregory P. Smithf0547d02006-06-05 17:38:04 +0000357#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000358
359#define CHECK_DBFLAG(mydb, flag) (((mydb)->flags & (flag)) || \
360 (((mydb)->myenvobj != NULL) && ((mydb)->myenvobj->flags & (flag))))
361
362#define CLEAR_DBT(dbt) (memset(&(dbt), 0, sizeof(dbt)))
363
364#define FREE_DBT(dbt) if ((dbt.flags & (DB_DBT_MALLOC|DB_DBT_REALLOC)) && \
Gregory P. Smithdc5af702004-06-27 23:32:34 +0000365 dbt.data != NULL) { free(dbt.data); dbt.data = NULL; }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000366
367
368static int makeDBError(int err);
369
370
371/* Return the access method type of the DBObject */
372static int _DB_get_type(DBObject* self)
373{
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000374 DBTYPE type;
375 int err;
Jesus Ceac5a11fa2008-07-23 11:38:42 +0000376
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000377 err = self->db->get_type(self->db, &type);
378 if (makeDBError(err)) {
379 return -1;
380 }
381 return type;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000382}
383
384
385/* Create a DBT structure (containing key and data values) from Python
386 strings. Returns 1 on success, 0 on an error. */
387static int make_dbt(PyObject* obj, DBT* dbt)
388{
389 CLEAR_DBT(*dbt);
390 if (obj == Py_None) {
391 /* no need to do anything, the structure has already been zeroed */
392 }
393 else if (!PyArg_Parse(obj, "s#", &dbt->data, &dbt->size)) {
394 PyErr_SetString(PyExc_TypeError,
Jesus Cea4907d272008-08-31 14:00:51 +0000395#if (PY_VERSION_HEX < 0x03000000)
Gregory P. Smithdc5af702004-06-27 23:32:34 +0000396 "Data values must be of type string or None.");
Jesus Cea4907d272008-08-31 14:00:51 +0000397#else
398 "Data values must be of type bytes or None.");
399#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000400 return 0;
401 }
402 return 1;
403}
404
405
406/* Recno and Queue DBs can have integer keys. This function figures out
407 what's been given, verifies that it's allowed, and then makes the DBT.
408
Gregory P. Smithdc5af702004-06-27 23:32:34 +0000409 Caller MUST call FREE_DBT(key) when done. */
Barry Warsaw9a0d7792002-12-30 20:53:52 +0000410static int
411make_key_dbt(DBObject* self, PyObject* keyobj, DBT* key, int* pflags)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000412{
413 db_recno_t recno;
414 int type;
415
416 CLEAR_DBT(*key);
Gustavo Niemeyerf073b752004-01-20 15:24:29 +0000417 if (keyobj == Py_None) {
Gustavo Niemeyer024f2de2004-01-20 15:14:55 +0000418 type = _DB_get_type(self);
Gustavo Niemeyer8974f722004-01-20 15:20:03 +0000419 if (type == -1)
420 return 0;
Gustavo Niemeyer024f2de2004-01-20 15:14:55 +0000421 if (type == DB_RECNO || type == DB_QUEUE) {
422 PyErr_SetString(
423 PyExc_TypeError,
424 "None keys not allowed for Recno and Queue DB's");
425 return 0;
426 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000427 /* no need to do anything, the structure has already been zeroed */
428 }
429
Christian Heimes593daf52008-05-26 12:51:38 +0000430 else if (PyBytes_Check(keyobj)) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000431 /* verify access method type */
432 type = _DB_get_type(self);
433 if (type == -1)
434 return 0;
435 if (type == DB_RECNO || type == DB_QUEUE) {
Barry Warsaw9a0d7792002-12-30 20:53:52 +0000436 PyErr_SetString(
437 PyExc_TypeError,
Jesus Cea4907d272008-08-31 14:00:51 +0000438#if (PY_VERSION_HEX < 0x03000000)
Barry Warsaw9a0d7792002-12-30 20:53:52 +0000439 "String keys not allowed for Recno and Queue DB's");
Jesus Cea4907d272008-08-31 14:00:51 +0000440#else
441 "Bytes keys not allowed for Recno and Queue DB's");
442#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000443 return 0;
444 }
445
Gregory P. Smith10bed542007-10-09 06:50:43 +0000446 /*
447 * NOTE(gps): I don't like doing a data copy here, it seems
448 * wasteful. But without a clean way to tell FREE_DBT if it
449 * should free key->data or not we have to. Other places in
450 * the code check for DB_THREAD and forceably set DBT_MALLOC
451 * when we otherwise would leave flags 0 to indicate that.
452 */
Christian Heimes593daf52008-05-26 12:51:38 +0000453 key->data = malloc(PyBytes_GET_SIZE(keyobj));
Gregory P. Smith10bed542007-10-09 06:50:43 +0000454 if (key->data == NULL) {
455 PyErr_SetString(PyExc_MemoryError, "Key memory allocation failed");
456 return 0;
457 }
Christian Heimes593daf52008-05-26 12:51:38 +0000458 memcpy(key->data, PyBytes_AS_STRING(keyobj),
459 PyBytes_GET_SIZE(keyobj));
Gregory P. Smith10bed542007-10-09 06:50:43 +0000460 key->flags = DB_DBT_REALLOC;
Christian Heimes593daf52008-05-26 12:51:38 +0000461 key->size = PyBytes_GET_SIZE(keyobj);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000462 }
463
Jesus Ceac5a11fa2008-07-23 11:38:42 +0000464 else if (NUMBER_Check(keyobj)) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000465 /* verify access method type */
466 type = _DB_get_type(self);
467 if (type == -1)
468 return 0;
469 if (type == DB_BTREE && pflags != NULL) {
Barry Warsaw9a0d7792002-12-30 20:53:52 +0000470 /* if BTREE then an Integer key is allowed with the
471 * DB_SET_RECNO flag */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000472 *pflags |= DB_SET_RECNO;
473 }
474 else if (type != DB_RECNO && type != DB_QUEUE) {
Barry Warsaw9a0d7792002-12-30 20:53:52 +0000475 PyErr_SetString(
476 PyExc_TypeError,
477 "Integer keys only allowed for Recno and Queue DB's");
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000478 return 0;
479 }
480
Barry Warsaw9a0d7792002-12-30 20:53:52 +0000481 /* Make a key out of the requested recno, use allocated space so DB
482 * will be able to realloc room for the real key if needed. */
Jesus Ceac5a11fa2008-07-23 11:38:42 +0000483 recno = NUMBER_AsLong(keyobj);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000484 key->data = malloc(sizeof(db_recno_t));
485 if (key->data == NULL) {
486 PyErr_SetString(PyExc_MemoryError, "Key memory allocation failed");
487 return 0;
488 }
489 key->ulen = key->size = sizeof(db_recno_t);
490 memcpy(key->data, &recno, sizeof(db_recno_t));
491 key->flags = DB_DBT_REALLOC;
492 }
493 else {
494 PyErr_Format(PyExc_TypeError,
Jesus Cea4907d272008-08-31 14:00:51 +0000495#if (PY_VERSION_HEX < 0x03000000)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000496 "String or Integer object expected for key, %s found",
Jesus Cea4907d272008-08-31 14:00:51 +0000497#else
498 "Bytes or Integer object expected for key, %s found",
499#endif
Christian Heimese93237d2007-12-19 02:37:44 +0000500 Py_TYPE(keyobj)->tp_name);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000501 return 0;
502 }
503
504 return 1;
505}
506
507
508/* Add partial record access to an existing DBT data struct.
509 If dlen and doff are set, then the DB_DBT_PARTIAL flag will be set
510 and the data storage/retrieval will be done using dlen and doff. */
511static int add_partial_dbt(DBT* d, int dlen, int doff) {
512 /* if neither were set we do nothing (-1 is the default value) */
513 if ((dlen == -1) && (doff == -1)) {
514 return 1;
515 }
516
517 if ((dlen < 0) || (doff < 0)) {
518 PyErr_SetString(PyExc_TypeError, "dlen and doff must both be >= 0");
519 return 0;
520 }
521
522 d->flags = d->flags | DB_DBT_PARTIAL;
523 d->dlen = (unsigned int) dlen;
524 d->doff = (unsigned int) doff;
525 return 1;
526}
527
Gregory P. Smith8b7e9172004-12-13 09:51:23 +0000528/* a safe strcpy() without the zeroing behaviour and semantics of strncpy. */
529/* TODO: make this use the native libc strlcpy() when available (BSD) */
530unsigned int our_strlcpy(char* dest, const char* src, unsigned int n)
531{
532 unsigned int srclen, copylen;
533
534 srclen = strlen(src);
535 if (n <= 0)
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000536 return srclen;
Gregory P. Smith8b7e9172004-12-13 09:51:23 +0000537 copylen = (srclen > n-1) ? n-1 : srclen;
538 /* populate dest[0] thru dest[copylen-1] */
539 memcpy(dest, src, copylen);
540 /* guarantee null termination */
541 dest[copylen] = 0;
542
543 return srclen;
544}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000545
Barry Warsaw9a0d7792002-12-30 20:53:52 +0000546/* Callback used to save away more information about errors from the DB
547 * library. */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000548static char _db_errmsg[1024];
Gregory P. Smith8b7e9172004-12-13 09:51:23 +0000549static void _db_errorCallback(const DB_ENV *db_env,
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000550 const char* prefix, const char* msg)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000551{
Gregory P. Smith8b7e9172004-12-13 09:51:23 +0000552 our_strlcpy(_db_errmsg, msg, sizeof(_db_errmsg));
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000553}
554
555
Jesus Ceaef9764f2008-05-13 18:45:46 +0000556/*
557** We need these functions because some results
558** are undefined if pointer is NULL. Some other
559** give None instead of "".
560**
561** This functions are static and will be
562** -I hope- inlined.
563*/
564static const char *DummyString = "This string is a simple placeholder";
565static PyObject *Build_PyString(const char *p,int s)
566{
567 if (!p) {
568 p=DummyString;
569 assert(s==0);
570 }
Christian Heimes593daf52008-05-26 12:51:38 +0000571 return PyBytes_FromStringAndSize(p,s);
Jesus Ceaef9764f2008-05-13 18:45:46 +0000572}
573
574static PyObject *BuildValue_S(const void *p,int s)
575{
576 if (!p) {
577 p=DummyString;
578 assert(s==0);
579 }
Jesus Cea4907d272008-08-31 14:00:51 +0000580 return PyBytes_FromStringAndSize(p, s);
Jesus Ceaef9764f2008-05-13 18:45:46 +0000581}
582
583static PyObject *BuildValue_SS(const void *p1,int s1,const void *p2,int s2)
584{
Jesus Cea4907d272008-08-31 14:00:51 +0000585PyObject *a, *b, *r;
586
Jesus Ceaef9764f2008-05-13 18:45:46 +0000587 if (!p1) {
588 p1=DummyString;
589 assert(s1==0);
590 }
591 if (!p2) {
592 p2=DummyString;
593 assert(s2==0);
594 }
Jesus Cea4907d272008-08-31 14:00:51 +0000595
596 if (!(a = PyBytes_FromStringAndSize(p1, s1))) {
597 return NULL;
598 }
599 if (!(b = PyBytes_FromStringAndSize(p2, s2))) {
600 Py_DECREF(a);
601 return NULL;
602 }
603
Jesus Cea4907d272008-08-31 14:00:51 +0000604 r = PyTuple_Pack(2, a, b) ;
Jesus Cea4907d272008-08-31 14:00:51 +0000605 Py_DECREF(a);
606 Py_DECREF(b);
607 return r;
Jesus Ceaef9764f2008-05-13 18:45:46 +0000608}
609
610static PyObject *BuildValue_IS(int i,const void *p,int s)
611{
Jesus Cea4907d272008-08-31 14:00:51 +0000612 PyObject *a, *r;
613
Jesus Ceaef9764f2008-05-13 18:45:46 +0000614 if (!p) {
615 p=DummyString;
616 assert(s==0);
617 }
Jesus Cea4907d272008-08-31 14:00:51 +0000618
619 if (!(a = PyBytes_FromStringAndSize(p, s))) {
620 return NULL;
621 }
622
623 r = Py_BuildValue("iO", i, a);
624 Py_DECREF(a);
625 return r;
Jesus Ceaef9764f2008-05-13 18:45:46 +0000626}
627
Jesus Cea4907d272008-08-31 14:00:51 +0000628static PyObject *BuildValue_LS(long l,const void *p,int s)
Jesus Ceaef9764f2008-05-13 18:45:46 +0000629{
Jesus Cea4907d272008-08-31 14:00:51 +0000630 PyObject *a, *r;
631
Jesus Ceaef9764f2008-05-13 18:45:46 +0000632 if (!p) {
633 p=DummyString;
634 assert(s==0);
635 }
Jesus Cea4907d272008-08-31 14:00:51 +0000636
637 if (!(a = PyBytes_FromStringAndSize(p, s))) {
638 return NULL;
639 }
640
641 r = Py_BuildValue("lO", l, a);
642 Py_DECREF(a);
643 return r;
Jesus Ceaef9764f2008-05-13 18:45:46 +0000644}
645
646
647
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000648/* make a nice exception object to raise for errors. */
649static int makeDBError(int err)
650{
651 char errTxt[2048]; /* really big, just in case... */
Barry Warsaw9a0d7792002-12-30 20:53:52 +0000652 PyObject *errObj = NULL;
653 PyObject *errTuple = NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000654 int exceptionRaised = 0;
Neal Norwitzdce937f2006-07-23 08:01:43 +0000655 unsigned int bytes_left;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000656
657 switch (err) {
Jesus Cea6557aac2010-03-22 14:22:26 +0000658 case 0: /* successful, no error */
659 return 0;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000660
661 case DB_KEYEMPTY: errObj = DBKeyEmptyError; break;
662 case DB_KEYEXIST: errObj = DBKeyExistError; break;
663 case DB_LOCK_DEADLOCK: errObj = DBLockDeadlockError; break;
664 case DB_LOCK_NOTGRANTED: errObj = DBLockNotGrantedError; break;
665 case DB_NOTFOUND: errObj = DBNotFoundError; break;
666 case DB_OLD_VERSION: errObj = DBOldVersionError; break;
667 case DB_RUNRECOVERY: errObj = DBRunRecoveryError; break;
668 case DB_VERIFY_BAD: errObj = DBVerifyBadError; break;
669 case DB_NOSERVER: errObj = DBNoServerError; break;
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -0700670#if (DBVER < 52)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000671 case DB_NOSERVER_HOME: errObj = DBNoServerHomeError; break;
672 case DB_NOSERVER_ID: errObj = DBNoServerIDError; break;
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -0700673#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000674 case DB_PAGE_NOTFOUND: errObj = DBPageNotFoundError; break;
675 case DB_SECONDARY_BAD: errObj = DBSecondaryBadError; break;
Gregory P. Smith8b7e9172004-12-13 09:51:23 +0000676 case DB_BUFFER_SMALL: errObj = DBNoMemoryError; break;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000677
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000678 case ENOMEM: errObj = PyExc_MemoryError; break;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000679 case EINVAL: errObj = DBInvalidArgError; break;
680 case EACCES: errObj = DBAccessError; break;
681 case ENOSPC: errObj = DBNoSpaceError; break;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000682 case EAGAIN: errObj = DBAgainError; break;
683 case EBUSY : errObj = DBBusyError; break;
684 case EEXIST: errObj = DBFileExistsError; break;
685 case ENOENT: errObj = DBNoSuchFileError; break;
686 case EPERM : errObj = DBPermissionsError; break;
687
Jesus Ceaef9764f2008-05-13 18:45:46 +0000688 case DB_REP_HANDLE_DEAD : errObj = DBRepHandleDeadError; break;
Jesus Cea6557aac2010-03-22 14:22:26 +0000689#if (DBVER >= 44)
690 case DB_REP_LOCKOUT : errObj = DBRepLockoutError; break;
691#endif
692
693#if (DBVER >= 46)
694 case DB_REP_LEASE_EXPIRED : errObj = DBRepLeaseExpiredError; break;
695#endif
696
697#if (DBVER >= 47)
698 case DB_FOREIGN_CONFLICT : errObj = DBForeignConflictError; break;
699#endif
Jesus Ceaef9764f2008-05-13 18:45:46 +0000700
Jesus Ceac5a11fa2008-07-23 11:38:42 +0000701 case DB_REP_UNAVAIL : errObj = DBRepUnavailError; break;
702
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000703 default: errObj = DBError; break;
704 }
705
706 if (errObj != NULL) {
Neal Norwitzdce937f2006-07-23 08:01:43 +0000707 bytes_left = our_strlcpy(errTxt, db_strerror(err), sizeof(errTxt));
708 /* Ensure that bytes_left never goes negative */
709 if (_db_errmsg[0] && bytes_left < (sizeof(errTxt) - 4)) {
710 bytes_left = sizeof(errTxt) - bytes_left - 4 - 1;
711 assert(bytes_left >= 0);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000712 strcat(errTxt, " -- ");
Neal Norwitzdce937f2006-07-23 08:01:43 +0000713 strncat(errTxt, _db_errmsg, bytes_left);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000714 }
Neal Norwitzdce937f2006-07-23 08:01:43 +0000715 _db_errmsg[0] = 0;
Barry Warsaw9a0d7792002-12-30 20:53:52 +0000716
Jesus Ceac5a11fa2008-07-23 11:38:42 +0000717 errTuple = Py_BuildValue("(is)", err, errTxt);
718 if (errTuple == NULL) {
719 Py_DECREF(errObj);
720 return !0;
721 }
Barry Warsaw9a0d7792002-12-30 20:53:52 +0000722 PyErr_SetObject(errObj, errTuple);
Jesus Ceac5a11fa2008-07-23 11:38:42 +0000723 Py_DECREF(errTuple);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000724 }
725
726 return ((errObj != NULL) || exceptionRaised);
727}
728
729
730
731/* set a type exception */
732static void makeTypeError(char* expected, PyObject* found)
733{
734 PyErr_Format(PyExc_TypeError, "Expected %s argument, %s found.",
Christian Heimese93237d2007-12-19 02:37:44 +0000735 expected, Py_TYPE(found)->tp_name);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000736}
737
738
739/* verify that an obj is either None or a DBTxn, and set the txn pointer */
740static int checkTxnObj(PyObject* txnobj, DB_TXN** txn)
741{
742 if (txnobj == Py_None || txnobj == NULL) {
743 *txn = NULL;
744 return 1;
745 }
746 if (DBTxnObject_Check(txnobj)) {
747 *txn = ((DBTxnObject*)txnobj)->txn;
748 return 1;
749 }
750 else
751 makeTypeError("DBTxn", txnobj);
752 return 0;
753}
754
755
756/* Delete a key from a database
757 Returns 0 on success, -1 on an error. */
758static int _DB_delete(DBObject* self, DB_TXN *txn, DBT *key, int flags)
759{
760 int err;
761
762 MYDB_BEGIN_ALLOW_THREADS;
763 err = self->db->del(self->db, txn, key, 0);
764 MYDB_END_ALLOW_THREADS;
765 if (makeDBError(err)) {
766 return -1;
767 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000768 return 0;
769}
770
771
772/* Store a key into a database
773 Returns 0 on success, -1 on an error. */
774static int _DB_put(DBObject* self, DB_TXN *txn, DBT *key, DBT *data, int flags)
775{
776 int err;
777
778 MYDB_BEGIN_ALLOW_THREADS;
779 err = self->db->put(self->db, txn, key, data, flags);
780 MYDB_END_ALLOW_THREADS;
781 if (makeDBError(err)) {
782 return -1;
783 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000784 return 0;
785}
786
787/* Get a key/data pair from a cursor */
788static PyObject* _DBCursor_get(DBCursorObject* self, int extra_flags,
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000789 PyObject *args, PyObject *kwargs, char *format)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000790{
791 int err;
792 PyObject* retval = NULL;
793 DBT key, data;
794 int dlen = -1;
795 int doff = -1;
796 int flags = 0;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +0000797 static char* kwnames[] = { "flags", "dlen", "doff", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000798
799 if (!PyArg_ParseTupleAndKeywords(args, kwargs, format, kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000800 &flags, &dlen, &doff))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000801 return NULL;
802
803 CHECK_CURSOR_NOT_CLOSED(self);
804
805 flags |= extra_flags;
806 CLEAR_DBT(key);
807 CLEAR_DBT(data);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000808 if (!add_partial_dbt(&data, dlen, doff))
809 return NULL;
810
811 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +0000812 err = _DBC_get(self->dbc, &key, &data, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000813 MYDB_END_ALLOW_THREADS;
814
Gregory P. Smithe9477062005-06-04 06:46:59 +0000815 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000816 && self->mydb->moduleFlags.getReturnsNone) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000817 Py_INCREF(Py_None);
818 retval = Py_None;
819 }
820 else if (makeDBError(err)) {
821 retval = NULL;
822 }
823 else { /* otherwise, success! */
824
825 /* if Recno or Queue, return the key as an Int */
826 switch (_DB_get_type(self->mydb)) {
827 case -1:
828 retval = NULL;
829 break;
830
831 case DB_RECNO:
832 case DB_QUEUE:
Jesus Ceaef9764f2008-05-13 18:45:46 +0000833 retval = BuildValue_IS(*((db_recno_t*)key.data), data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000834 break;
835 case DB_HASH:
836 case DB_BTREE:
837 default:
Jesus Ceaef9764f2008-05-13 18:45:46 +0000838 retval = BuildValue_SS(key.data, key.size, data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000839 break;
840 }
841 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000842 return retval;
843}
844
845
846/* add an integer to a dictionary using the given name as a key */
847static void _addIntToDict(PyObject* dict, char *name, int value)
848{
Jesus Ceac5a11fa2008-07-23 11:38:42 +0000849 PyObject* v = NUMBER_FromLong((long) value);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000850 if (!v || PyDict_SetItemString(dict, name, v))
851 PyErr_Clear();
852
853 Py_XDECREF(v);
854}
Kristján Valur Jónssonbd77c032007-04-26 15:24:54 +0000855
856/* The same, when the value is a time_t */
857static void _addTimeTToDict(PyObject* dict, char *name, time_t value)
858{
859 PyObject* v;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000860 /* if the value fits in regular int, use that. */
Jesus Ceaef9764f2008-05-13 18:45:46 +0000861#ifdef PY_LONG_LONG
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000862 if (sizeof(time_t) > sizeof(long))
863 v = PyLong_FromLongLong((PY_LONG_LONG) value);
864 else
Kristján Valur Jónssonbd77c032007-04-26 15:24:54 +0000865#endif
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000866 v = NUMBER_FromLong((long) value);
Kristján Valur Jónssonbd77c032007-04-26 15:24:54 +0000867 if (!v || PyDict_SetItemString(dict, name, v))
868 PyErr_Clear();
869
870 Py_XDECREF(v);
871}
872
Gregory P. Smithf0547d02006-06-05 17:38:04 +0000873/* add an db_seq_t to a dictionary using the given name as a key */
874static void _addDb_seq_tToDict(PyObject* dict, char *name, db_seq_t value)
875{
876 PyObject* v = PyLong_FromLongLong(value);
877 if (!v || PyDict_SetItemString(dict, name, v))
878 PyErr_Clear();
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000879
Gregory P. Smithf0547d02006-06-05 17:38:04 +0000880 Py_XDECREF(v);
881}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000882
Jesus Ceaef9764f2008-05-13 18:45:46 +0000883static void _addDB_lsnToDict(PyObject* dict, char *name, DB_LSN value)
884{
885 PyObject *v = Py_BuildValue("(ll)",value.file,value.offset);
886 if (!v || PyDict_SetItemString(dict, name, v))
887 PyErr_Clear();
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000888
Jesus Ceaef9764f2008-05-13 18:45:46 +0000889 Py_XDECREF(v);
890}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000891
892/* --------------------------------------------------------------------- */
893/* Allocators and deallocators */
894
895static DBObject*
896newDBObject(DBEnvObject* arg, int flags)
897{
898 DBObject* self;
899 DB_ENV* db_env = NULL;
900 int err;
901
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000902 self = PyObject_New(DBObject, &DB_Type);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000903 if (self == NULL)
904 return NULL;
905
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000906 self->flags = 0;
907 self->setflags = 0;
908 self->myenvobj = NULL;
Jesus Ceac5a11fa2008-07-23 11:38:42 +0000909 self->db = NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +0000910 self->children_cursors = NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +0000911 self->children_sequences = NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000912 self->associateCallback = NULL;
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +0000913 self->btCompareCallback = NULL;
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -0700914 self->dupCompareCallback = NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000915 self->primaryDBType = 0;
Jesus Ceac5a11fa2008-07-23 11:38:42 +0000916 Py_INCREF(Py_None);
Jesus Cea4907d272008-08-31 14:00:51 +0000917 self->private_obj = Py_None;
Gregory P. Smith31c50652004-06-28 01:20:40 +0000918 self->in_weakreflist = NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000919
920 /* keep a reference to our python DBEnv object */
921 if (arg) {
922 Py_INCREF(arg);
923 self->myenvobj = arg;
924 db_env = arg->db_env;
Jesus Ceaef9764f2008-05-13 18:45:46 +0000925 INSERT_IN_DOUBLE_LINKED_LIST(self->myenvobj->children_dbs,self);
926 } else {
927 self->sibling_prev_p=NULL;
928 self->sibling_next=NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000929 }
Jesus Ceaef9764f2008-05-13 18:45:46 +0000930 self->txn=NULL;
931 self->sibling_prev_p_txn=NULL;
932 self->sibling_next_txn=NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000933
934 if (self->myenvobj)
Gregory P. Smith455d46f2003-07-09 04:45:59 +0000935 self->moduleFlags = self->myenvobj->moduleFlags;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000936 else
Gregory P. Smith455d46f2003-07-09 04:45:59 +0000937 self->moduleFlags.getReturnsNone = DEFAULT_GET_RETURNS_NONE;
938 self->moduleFlags.cursorSetReturnsNone = DEFAULT_CURSOR_SET_RETURNS_NONE;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000939
940 MYDB_BEGIN_ALLOW_THREADS;
941 err = db_create(&self->db, db_env, flags);
Neal Norwitzdce937f2006-07-23 08:01:43 +0000942 if (self->db != NULL) {
943 self->db->set_errcall(self->db, _db_errorCallback);
Neal Norwitzdce937f2006-07-23 08:01:43 +0000944 self->db->app_private = (void*)self;
Neal Norwitzdce937f2006-07-23 08:01:43 +0000945 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000946 MYDB_END_ALLOW_THREADS;
Gregory P. Smith31c50652004-06-28 01:20:40 +0000947 /* TODO add a weakref(self) to the self->myenvobj->open_child_weakrefs
948 * list so that a DBEnv can refuse to close without aborting any open
Gregory P. Smithf0547d02006-06-05 17:38:04 +0000949 * DBTxns and closing any open DBs first. */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000950 if (makeDBError(err)) {
951 if (self->myenvobj) {
Serhiy Storchaka98a97222014-02-09 13:14:04 +0200952 Py_CLEAR(self->myenvobj);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000953 }
Gregory P. Smith664782e2008-05-17 06:12:02 +0000954 Py_DECREF(self);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000955 self = NULL;
956 }
957 return self;
958}
959
960
Jesus Ceaef9764f2008-05-13 18:45:46 +0000961/* Forward declaration */
Jesus Cea5cd5f122008-09-23 18:54:08 +0000962static PyObject *DB_close_internal(DBObject* self, int flags, int do_not_close);
Jesus Ceaef9764f2008-05-13 18:45:46 +0000963
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000964static void
965DB_dealloc(DBObject* self)
966{
Jesus Ceaef9764f2008-05-13 18:45:46 +0000967 PyObject *dummy;
968
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000969 if (self->db != NULL) {
Jesus Cea5cd5f122008-09-23 18:54:08 +0000970 dummy=DB_close_internal(self, 0, 0);
971 /*
972 ** Raising exceptions while doing
973 ** garbage collection is a fatal error.
974 */
975 if (dummy)
976 Py_DECREF(dummy);
977 else
978 PyErr_Clear();
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000979 }
Gregory P. Smith31c50652004-06-28 01:20:40 +0000980 if (self->in_weakreflist != NULL) {
981 PyObject_ClearWeakRefs((PyObject *) self);
982 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000983 if (self->myenvobj) {
Serhiy Storchaka98a97222014-02-09 13:14:04 +0200984 Py_CLEAR(self->myenvobj);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000985 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000986 if (self->associateCallback != NULL) {
Serhiy Storchaka98a97222014-02-09 13:14:04 +0200987 Py_CLEAR(self->associateCallback);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000988 }
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +0000989 if (self->btCompareCallback != NULL) {
Serhiy Storchaka98a97222014-02-09 13:14:04 +0200990 Py_CLEAR(self->btCompareCallback);
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +0000991 }
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -0700992 if (self->dupCompareCallback != NULL) {
Serhiy Storchaka98a97222014-02-09 13:14:04 +0200993 Py_CLEAR(self->dupCompareCallback);
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -0700994 }
Jesus Cea4907d272008-08-31 14:00:51 +0000995 Py_DECREF(self->private_obj);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000996 PyObject_Del(self);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000997}
998
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000999static DBCursorObject*
Jesus Ceaef9764f2008-05-13 18:45:46 +00001000newDBCursorObject(DBC* dbc, DBTxnObject *txn, DBObject* db)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001001{
Neal Norwitzb4a55812004-07-09 23:30:57 +00001002 DBCursorObject* self = PyObject_New(DBCursorObject, &DBCursor_Type);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001003 if (self == NULL)
1004 return NULL;
1005
1006 self->dbc = dbc;
1007 self->mydb = db;
Jesus Ceaef9764f2008-05-13 18:45:46 +00001008
1009 INSERT_IN_DOUBLE_LINKED_LIST(self->mydb->children_cursors,self);
1010 if (txn && ((PyObject *)txn!=Py_None)) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001011 INSERT_IN_DOUBLE_LINKED_LIST_TXN(txn->children_cursors,self);
1012 self->txn=txn;
Jesus Ceaef9764f2008-05-13 18:45:46 +00001013 } else {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001014 self->txn=NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00001015 }
1016
Gregory P. Smitha703a212003-11-03 01:04:41 +00001017 self->in_weakreflist = NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001018 Py_INCREF(self->mydb);
1019 return self;
1020}
1021
1022
Jesus Ceaef9764f2008-05-13 18:45:46 +00001023/* Forward declaration */
1024static PyObject *DBC_close_internal(DBCursorObject* self);
1025
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001026static void
1027DBCursor_dealloc(DBCursorObject* self)
1028{
Jesus Ceaef9764f2008-05-13 18:45:46 +00001029 PyObject *dummy;
Gregory P. Smitha703a212003-11-03 01:04:41 +00001030
Jesus Ceaef9764f2008-05-13 18:45:46 +00001031 if (self->dbc != NULL) {
Jesus Cea5cd5f122008-09-23 18:54:08 +00001032 dummy=DBC_close_internal(self);
1033 /*
1034 ** Raising exceptions while doing
1035 ** garbage collection is a fatal error.
1036 */
1037 if (dummy)
1038 Py_DECREF(dummy);
1039 else
1040 PyErr_Clear();
Jesus Ceaef9764f2008-05-13 18:45:46 +00001041 }
Gregory P. Smitha703a212003-11-03 01:04:41 +00001042 if (self->in_weakreflist != NULL) {
1043 PyObject_ClearWeakRefs((PyObject *) self);
1044 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00001045 Py_DECREF(self->mydb);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001046 PyObject_Del(self);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001047}
1048
1049
Jesus Cea6557aac2010-03-22 14:22:26 +00001050static DBLogCursorObject*
1051newDBLogCursorObject(DB_LOGC* dblogc, DBEnvObject* env)
1052{
1053 DBLogCursorObject* self;
1054
1055 self = PyObject_New(DBLogCursorObject, &DBLogCursor_Type);
1056
1057 if (self == NULL)
1058 return NULL;
1059
1060 self->logc = dblogc;
1061 self->env = env;
1062
1063 INSERT_IN_DOUBLE_LINKED_LIST(self->env->children_logcursors, self);
1064
1065 self->in_weakreflist = NULL;
1066 Py_INCREF(self->env);
1067 return self;
1068}
1069
1070
1071/* Forward declaration */
1072static PyObject *DBLogCursor_close_internal(DBLogCursorObject* self);
1073
1074static void
1075DBLogCursor_dealloc(DBLogCursorObject* self)
1076{
1077 PyObject *dummy;
1078
1079 if (self->logc != NULL) {
1080 dummy = DBLogCursor_close_internal(self);
1081 /*
1082 ** Raising exceptions while doing
1083 ** garbage collection is a fatal error.
1084 */
1085 if (dummy)
1086 Py_DECREF(dummy);
1087 else
1088 PyErr_Clear();
1089 }
1090 if (self->in_weakreflist != NULL) {
1091 PyObject_ClearWeakRefs((PyObject *) self);
1092 }
1093 Py_DECREF(self->env);
1094 PyObject_Del(self);
1095}
1096
1097
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001098static DBEnvObject*
1099newDBEnvObject(int flags)
1100{
1101 int err;
Neal Norwitzb4a55812004-07-09 23:30:57 +00001102 DBEnvObject* self = PyObject_New(DBEnvObject, &DBEnv_Type);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001103 if (self == NULL)
1104 return NULL;
1105
Jesus Cea5cd5f122008-09-23 18:54:08 +00001106 self->db_env = NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001107 self->closed = 1;
1108 self->flags = flags;
Gregory P. Smith455d46f2003-07-09 04:45:59 +00001109 self->moduleFlags.getReturnsNone = DEFAULT_GET_RETURNS_NONE;
1110 self->moduleFlags.cursorSetReturnsNone = DEFAULT_CURSOR_SET_RETURNS_NONE;
Jesus Ceaef9764f2008-05-13 18:45:46 +00001111 self->children_dbs = NULL;
1112 self->children_txns = NULL;
Jesus Cea6557aac2010-03-22 14:22:26 +00001113 self->children_logcursors = NULL ;
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07001114#if (DBVER >= 52)
1115 self->children_sites = NULL;
1116#endif
Jesus Ceac5a11fa2008-07-23 11:38:42 +00001117 Py_INCREF(Py_None);
Jesus Cea4907d272008-08-31 14:00:51 +00001118 self->private_obj = Py_None;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00001119 Py_INCREF(Py_None);
1120 self->rep_transport = Py_None;
Gregory P. Smith31c50652004-06-28 01:20:40 +00001121 self->in_weakreflist = NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00001122 self->event_notifyCallback = NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00001123
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001124 MYDB_BEGIN_ALLOW_THREADS;
1125 err = db_env_create(&self->db_env, flags);
1126 MYDB_END_ALLOW_THREADS;
1127 if (makeDBError(err)) {
Gregory P. Smith664782e2008-05-17 06:12:02 +00001128 Py_DECREF(self);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001129 self = NULL;
1130 }
1131 else {
1132 self->db_env->set_errcall(self->db_env, _db_errorCallback);
Jesus Cea4907d272008-08-31 14:00:51 +00001133 self->db_env->app_private = self;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001134 }
1135 return self;
1136}
1137
Jesus Ceaef9764f2008-05-13 18:45:46 +00001138/* Forward declaration */
1139static PyObject *DBEnv_close_internal(DBEnvObject* self, int flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001140
1141static void
1142DBEnv_dealloc(DBEnvObject* self)
1143{
Jesus Ceaef9764f2008-05-13 18:45:46 +00001144 PyObject *dummy;
1145
Jesus Ceaac25fab2008-09-03 17:50:32 +00001146 if (self->db_env) {
Jesus Cea5cd5f122008-09-23 18:54:08 +00001147 dummy=DBEnv_close_internal(self, 0);
1148 /*
1149 ** Raising exceptions while doing
1150 ** garbage collection is a fatal error.
1151 */
1152 if (dummy)
1153 Py_DECREF(dummy);
1154 else
1155 PyErr_Clear();
Jesus Ceaef9764f2008-05-13 18:45:46 +00001156 }
1157
Serhiy Storchaka98a97222014-02-09 13:14:04 +02001158 Py_CLEAR(self->event_notifyCallback);
Jesus Ceaef9764f2008-05-13 18:45:46 +00001159
Gregory P. Smith31c50652004-06-28 01:20:40 +00001160 if (self->in_weakreflist != NULL) {
1161 PyObject_ClearWeakRefs((PyObject *) self);
1162 }
Jesus Cea4907d272008-08-31 14:00:51 +00001163 Py_DECREF(self->private_obj);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00001164 Py_DECREF(self->rep_transport);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001165 PyObject_Del(self);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001166}
1167
1168
1169static DBTxnObject*
Jesus Ceaef9764f2008-05-13 18:45:46 +00001170newDBTxnObject(DBEnvObject* myenv, DBTxnObject *parent, DB_TXN *txn, int flags)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001171{
1172 int err;
Gregory P. Smith664782e2008-05-17 06:12:02 +00001173 DB_TXN *parent_txn = NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00001174
Neal Norwitzb4a55812004-07-09 23:30:57 +00001175 DBTxnObject* self = PyObject_New(DBTxnObject, &DBTxn_Type);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001176 if (self == NULL)
1177 return NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00001178
Gregory P. Smith31c50652004-06-28 01:20:40 +00001179 self->in_weakreflist = NULL;
Gregory P. Smith664782e2008-05-17 06:12:02 +00001180 self->children_txns = NULL;
1181 self->children_dbs = NULL;
1182 self->children_cursors = NULL;
1183 self->children_sequences = NULL;
1184 self->flag_prepare = 0;
1185 self->parent_txn = NULL;
1186 self->env = NULL;
Jesus Cea6557aac2010-03-22 14:22:26 +00001187 /* We initialize just in case "txn_begin" fails */
1188 self->txn = NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001189
Jesus Ceaef9764f2008-05-13 18:45:46 +00001190 if (parent && ((PyObject *)parent!=Py_None)) {
Gregory P. Smith664782e2008-05-17 06:12:02 +00001191 parent_txn = parent->txn;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001192 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00001193
1194 if (txn) {
Gregory P. Smith664782e2008-05-17 06:12:02 +00001195 self->txn = txn;
Jesus Ceaef9764f2008-05-13 18:45:46 +00001196 } else {
1197 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00001198 err = myenv->db_env->txn_begin(myenv->db_env, parent_txn, &(self->txn), flags);
Jesus Ceaef9764f2008-05-13 18:45:46 +00001199 MYDB_END_ALLOW_THREADS;
1200
1201 if (makeDBError(err)) {
Jesus Cea6557aac2010-03-22 14:22:26 +00001202 /* Free object half initialized */
Gregory P. Smith664782e2008-05-17 06:12:02 +00001203 Py_DECREF(self);
Jesus Ceaef9764f2008-05-13 18:45:46 +00001204 return NULL;
1205 }
1206 }
1207
Gregory P. Smith664782e2008-05-17 06:12:02 +00001208 /* Can't use 'parent' because could be 'parent==Py_None' */
1209 if (parent_txn) {
1210 self->parent_txn = parent;
Jesus Ceaef9764f2008-05-13 18:45:46 +00001211 Py_INCREF(parent);
1212 self->env = NULL;
Gregory P. Smith664782e2008-05-17 06:12:02 +00001213 INSERT_IN_DOUBLE_LINKED_LIST(parent->children_txns, self);
Jesus Ceaef9764f2008-05-13 18:45:46 +00001214 } else {
Gregory P. Smith664782e2008-05-17 06:12:02 +00001215 self->parent_txn = NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00001216 Py_INCREF(myenv);
1217 self->env = myenv;
Gregory P. Smith664782e2008-05-17 06:12:02 +00001218 INSERT_IN_DOUBLE_LINKED_LIST(myenv->children_txns, self);
Jesus Ceaef9764f2008-05-13 18:45:46 +00001219 }
1220
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001221 return self;
1222}
1223
Jesus Ceaef9764f2008-05-13 18:45:46 +00001224/* Forward declaration */
1225static PyObject *
1226DBTxn_abort_discard_internal(DBTxnObject* self, int discard);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001227
1228static void
1229DBTxn_dealloc(DBTxnObject* self)
1230{
Jesus Ceaef9764f2008-05-13 18:45:46 +00001231 PyObject *dummy;
1232
1233 if (self->txn) {
1234 int flag_prepare = self->flag_prepare;
Jesus Cea5cd5f122008-09-23 18:54:08 +00001235
Jesus Cea6557aac2010-03-22 14:22:26 +00001236 dummy=DBTxn_abort_discard_internal(self, 0);
Jesus Cea5cd5f122008-09-23 18:54:08 +00001237 /*
1238 ** Raising exceptions while doing
1239 ** garbage collection is a fatal error.
1240 */
1241 if (dummy)
1242 Py_DECREF(dummy);
1243 else
1244 PyErr_Clear();
1245
Jesus Ceaef9764f2008-05-13 18:45:46 +00001246 if (!flag_prepare) {
1247 PyErr_Warn(PyExc_RuntimeWarning,
1248 "DBTxn aborted in destructor. No prior commit() or abort().");
1249 }
1250 }
1251
Gregory P. Smith31c50652004-06-28 01:20:40 +00001252 if (self->in_weakreflist != NULL) {
1253 PyObject_ClearWeakRefs((PyObject *) self);
1254 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001255
Jesus Ceaef9764f2008-05-13 18:45:46 +00001256 if (self->env) {
1257 Py_DECREF(self->env);
1258 } else {
Jesus Cea6557aac2010-03-22 14:22:26 +00001259 /*
1260 ** We can have "self->env==NULL" and "self->parent_txn==NULL"
1261 ** if something happens when creating the transaction object
1262 ** and we abort the object while half done.
1263 */
1264 Py_XDECREF(self->parent_txn);
Gregory P. Smith31c50652004-06-28 01:20:40 +00001265 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001266 PyObject_Del(self);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001267}
1268
1269
1270static DBLockObject*
1271newDBLockObject(DBEnvObject* myenv, u_int32_t locker, DBT* obj,
1272 db_lockmode_t lock_mode, int flags)
1273{
1274 int err;
Neal Norwitzb4a55812004-07-09 23:30:57 +00001275 DBLockObject* self = PyObject_New(DBLockObject, &DBLock_Type);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001276 if (self == NULL)
1277 return NULL;
Gregory P. Smith31c50652004-06-28 01:20:40 +00001278 self->in_weakreflist = NULL;
Jesus Cea6557aac2010-03-22 14:22:26 +00001279 self->lock_initialized = 0; /* Just in case the call fails */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001280
1281 MYDB_BEGIN_ALLOW_THREADS;
Barry Warsaw9a0d7792002-12-30 20:53:52 +00001282 err = myenv->db_env->lock_get(myenv->db_env, locker, flags, obj, lock_mode,
1283 &self->lock);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001284 MYDB_END_ALLOW_THREADS;
1285 if (makeDBError(err)) {
Gregory P. Smith664782e2008-05-17 06:12:02 +00001286 Py_DECREF(self);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001287 self = NULL;
Jesus Cea6557aac2010-03-22 14:22:26 +00001288 } else {
1289 self->lock_initialized = 1;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001290 }
1291
1292 return self;
1293}
1294
1295
1296static void
1297DBLock_dealloc(DBLockObject* self)
1298{
Gregory P. Smith31c50652004-06-28 01:20:40 +00001299 if (self->in_weakreflist != NULL) {
1300 PyObject_ClearWeakRefs((PyObject *) self);
1301 }
Gregory P. Smith31c50652004-06-28 01:20:40 +00001302 /* TODO: is this lock held? should we release it? */
Jesus Cea6557aac2010-03-22 14:22:26 +00001303 /* CAUTION: The lock can be not initialized if the creation has failed */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001304
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001305 PyObject_Del(self);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001306}
1307
1308
Gregory P. Smithf0547d02006-06-05 17:38:04 +00001309static DBSequenceObject*
1310newDBSequenceObject(DBObject* mydb, int flags)
1311{
1312 int err;
1313 DBSequenceObject* self = PyObject_New(DBSequenceObject, &DBSequence_Type);
1314 if (self == NULL)
1315 return NULL;
1316 Py_INCREF(mydb);
1317 self->mydb = mydb;
Gregory P. Smithf0547d02006-06-05 17:38:04 +00001318
Jesus Ceaef9764f2008-05-13 18:45:46 +00001319 INSERT_IN_DOUBLE_LINKED_LIST(self->mydb->children_sequences,self);
Gregory P. Smith664782e2008-05-17 06:12:02 +00001320 self->txn = NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00001321
1322 self->in_weakreflist = NULL;
Jesus Cea6557aac2010-03-22 14:22:26 +00001323 self->sequence = NULL; /* Just in case the call fails */
Gregory P. Smithf0547d02006-06-05 17:38:04 +00001324
1325 MYDB_BEGIN_ALLOW_THREADS;
1326 err = db_sequence_create(&self->sequence, self->mydb->db, flags);
1327 MYDB_END_ALLOW_THREADS;
1328 if (makeDBError(err)) {
Gregory P. Smith664782e2008-05-17 06:12:02 +00001329 Py_DECREF(self);
Gregory P. Smithf0547d02006-06-05 17:38:04 +00001330 self = NULL;
1331 }
1332
1333 return self;
1334}
1335
Jesus Ceaef9764f2008-05-13 18:45:46 +00001336/* Forward declaration */
1337static PyObject
1338*DBSequence_close_internal(DBSequenceObject* self, int flags, int do_not_close);
Gregory P. Smithf0547d02006-06-05 17:38:04 +00001339
1340static void
1341DBSequence_dealloc(DBSequenceObject* self)
1342{
Jesus Ceaef9764f2008-05-13 18:45:46 +00001343 PyObject *dummy;
1344
1345 if (self->sequence != NULL) {
1346 dummy=DBSequence_close_internal(self,0,0);
Jesus Cea5cd5f122008-09-23 18:54:08 +00001347 /*
1348 ** Raising exceptions while doing
1349 ** garbage collection is a fatal error.
1350 */
1351 if (dummy)
1352 Py_DECREF(dummy);
1353 else
1354 PyErr_Clear();
Jesus Ceaef9764f2008-05-13 18:45:46 +00001355 }
1356
Gregory P. Smithf0547d02006-06-05 17:38:04 +00001357 if (self->in_weakreflist != NULL) {
1358 PyObject_ClearWeakRefs((PyObject *) self);
1359 }
Gregory P. Smithf0547d02006-06-05 17:38:04 +00001360
1361 Py_DECREF(self->mydb);
1362 PyObject_Del(self);
1363}
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07001364
1365#if (DBVER >= 52)
1366static DBSiteObject*
1367newDBSiteObject(DB_SITE* sitep, DBEnvObject* env)
1368{
1369 DBSiteObject* self;
1370
1371 self = PyObject_New(DBSiteObject, &DBSite_Type);
1372
1373 if (self == NULL)
1374 return NULL;
1375
1376 self->site = sitep;
1377 self->env = env;
1378
1379 INSERT_IN_DOUBLE_LINKED_LIST(self->env->children_sites, self);
1380
1381 self->in_weakreflist = NULL;
1382 Py_INCREF(self->env);
1383 return self;
1384}
1385
1386/* Forward declaration */
1387static PyObject *DBSite_close_internal(DBSiteObject* self);
1388
1389static void
1390DBSite_dealloc(DBSiteObject* self)
1391{
1392 PyObject *dummy;
1393
1394 if (self->site != NULL) {
1395 dummy = DBSite_close_internal(self);
1396 /*
1397 ** Raising exceptions while doing
1398 ** garbage collection is a fatal error.
1399 */
1400 if (dummy)
1401 Py_DECREF(dummy);
1402 else
1403 PyErr_Clear();
1404 }
1405 if (self->in_weakreflist != NULL) {
1406 PyObject_ClearWeakRefs((PyObject *) self);
1407 }
1408 Py_DECREF(self->env);
1409 PyObject_Del(self);
1410}
Gregory P. Smithf0547d02006-06-05 17:38:04 +00001411#endif
1412
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001413/* --------------------------------------------------------------------- */
1414/* DB methods */
1415
1416static PyObject*
Jesus Cea4907d272008-08-31 14:00:51 +00001417DB_append(DBObject* self, PyObject* args, PyObject* kwargs)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001418{
1419 PyObject* txnobj = NULL;
1420 PyObject* dataobj;
1421 db_recno_t recno;
1422 DBT key, data;
1423 DB_TXN *txn = NULL;
Jesus Cea4907d272008-08-31 14:00:51 +00001424 static char* kwnames[] = { "data", "txn", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001425
Jesus Cea4907d272008-08-31 14:00:51 +00001426 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O:append", kwnames,
1427 &dataobj, &txnobj))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001428 return NULL;
1429
1430 CHECK_DB_NOT_CLOSED(self);
1431
1432 /* make a dummy key out of a recno */
1433 recno = 0;
1434 CLEAR_DBT(key);
1435 key.data = &recno;
1436 key.size = sizeof(recno);
1437 key.ulen = key.size;
1438 key.flags = DB_DBT_USERMEM;
1439
1440 if (!make_dbt(dataobj, &data)) return NULL;
1441 if (!checkTxnObj(txnobj, &txn)) return NULL;
1442
1443 if (-1 == _DB_put(self, txn, &key, &data, DB_APPEND))
1444 return NULL;
1445
Jesus Ceac5a11fa2008-07-23 11:38:42 +00001446 return NUMBER_FromLong(recno);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001447}
1448
1449
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001450static int
Barry Warsaw9a0d7792002-12-30 20:53:52 +00001451_db_associateCallback(DB* db, const DBT* priKey, const DBT* priData,
1452 DBT* secKey)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001453{
1454 int retval = DB_DONOTINDEX;
1455 DBObject* secondaryDB = (DBObject*)db->app_private;
1456 PyObject* callback = secondaryDB->associateCallback;
1457 int type = secondaryDB->primaryDBType;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001458 PyObject* args;
Thomas Wouters89ba3812006-03-07 14:14:51 +00001459 PyObject* result = NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001460
1461
1462 if (callback != NULL) {
1463 MYDB_BEGIN_BLOCK_THREADS;
1464
Thomas Woutersb3153832006-03-08 01:47:19 +00001465 if (type == DB_RECNO || type == DB_QUEUE)
Jesus Ceaef9764f2008-05-13 18:45:46 +00001466 args = BuildValue_LS(*((db_recno_t*)priKey->data), priData->data, priData->size);
Thomas Woutersb3153832006-03-08 01:47:19 +00001467 else
Jesus Ceaef9764f2008-05-13 18:45:46 +00001468 args = BuildValue_SS(priKey->data, priKey->size, priData->data, priData->size);
Thomas Wouters098f6942006-03-07 14:13:17 +00001469 if (args != NULL) {
Thomas Wouters098f6942006-03-07 14:13:17 +00001470 result = PyEval_CallObject(callback, args);
1471 }
1472 if (args == NULL || result == NULL) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001473 PyErr_Print();
1474 }
1475 else if (result == Py_None) {
1476 retval = DB_DONOTINDEX;
1477 }
Jesus Ceac5a11fa2008-07-23 11:38:42 +00001478 else if (NUMBER_Check(result)) {
1479 retval = NUMBER_AsLong(result);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001480 }
Christian Heimes593daf52008-05-26 12:51:38 +00001481 else if (PyBytes_Check(result)) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001482 char* data;
Martin v. Löwis18e16552006-02-15 17:27:45 +00001483 Py_ssize_t size;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001484
1485 CLEAR_DBT(*secKey);
Christian Heimes593daf52008-05-26 12:51:38 +00001486 PyBytes_AsStringAndSize(result, &data, &size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001487 secKey->flags = DB_DBT_APPMALLOC; /* DB will free */
1488 secKey->data = malloc(size); /* TODO, check this */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001489 if (secKey->data) {
1490 memcpy(secKey->data, data, size);
1491 secKey->size = size;
1492 retval = 0;
1493 }
1494 else {
1495 PyErr_SetString(PyExc_MemoryError,
Barry Warsaw9a0d7792002-12-30 20:53:52 +00001496 "malloc failed in _db_associateCallback");
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001497 PyErr_Print();
1498 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001499 }
Jesus Cea6557aac2010-03-22 14:22:26 +00001500#if (DBVER >= 46)
1501 else if (PyList_Check(result))
1502 {
1503 char* data;
1504 Py_ssize_t size;
1505 int i, listlen;
1506 DBT* dbts;
1507
1508 listlen = PyList_Size(result);
1509
1510 dbts = (DBT *)malloc(sizeof(DBT) * listlen);
1511
1512 for (i=0; i<listlen; i++)
1513 {
1514 if (!PyBytes_Check(PyList_GetItem(result, i)))
1515 {
1516 PyErr_SetString(
1517 PyExc_TypeError,
1518#if (PY_VERSION_HEX < 0x03000000)
1519"The list returned by DB->associate callback should be a list of strings.");
1520#else
1521"The list returned by DB->associate callback should be a list of bytes.");
1522#endif
1523 PyErr_Print();
1524 }
1525
1526 PyBytes_AsStringAndSize(
1527 PyList_GetItem(result, i),
1528 &data, &size);
1529
1530 CLEAR_DBT(dbts[i]);
1531 dbts[i].data = malloc(size); /* TODO, check this */
1532
1533 if (dbts[i].data)
1534 {
1535 memcpy(dbts[i].data, data, size);
1536 dbts[i].size = size;
1537 dbts[i].ulen = dbts[i].size;
1538 dbts[i].flags = DB_DBT_APPMALLOC; /* DB will free */
1539 }
1540 else
1541 {
1542 PyErr_SetString(PyExc_MemoryError,
1543 "malloc failed in _db_associateCallback (list)");
1544 PyErr_Print();
1545 }
1546 }
1547
1548 CLEAR_DBT(*secKey);
1549
1550 secKey->data = dbts;
1551 secKey->size = listlen;
1552 secKey->flags = DB_DBT_APPMALLOC | DB_DBT_MULTIPLE;
1553 retval = 0;
1554 }
1555#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001556 else {
Barry Warsaw9a0d7792002-12-30 20:53:52 +00001557 PyErr_SetString(
1558 PyExc_TypeError,
Jesus Cea6557aac2010-03-22 14:22:26 +00001559#if (PY_VERSION_HEX < 0x03000000)
1560"DB associate callback should return DB_DONOTINDEX/string/list of strings.");
1561#else
1562"DB associate callback should return DB_DONOTINDEX/bytes/list of bytes.");
1563#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001564 PyErr_Print();
1565 }
1566
Thomas Woutersb3153832006-03-08 01:47:19 +00001567 Py_XDECREF(args);
1568 Py_XDECREF(result);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001569
1570 MYDB_END_BLOCK_THREADS;
1571 }
1572 return retval;
1573}
1574
1575
1576static PyObject*
1577DB_associate(DBObject* self, PyObject* args, PyObject* kwargs)
1578{
1579 int err, flags=0;
1580 DBObject* secondaryDB;
1581 PyObject* callback;
Barry Warsaw9a0d7792002-12-30 20:53:52 +00001582 PyObject *txnobj = NULL;
1583 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00001584 static char* kwnames[] = {"secondaryDB", "callback", "flags", "txn",
Jeremy Hyltonaf68c872005-12-10 18:50:16 +00001585 NULL};
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001586
Barry Warsaw9a0d7792002-12-30 20:53:52 +00001587 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|iO:associate", kwnames,
1588 &secondaryDB, &callback, &flags,
1589 &txnobj)) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001590 return NULL;
Barry Warsaw9a0d7792002-12-30 20:53:52 +00001591 }
1592
Barry Warsaw9a0d7792002-12-30 20:53:52 +00001593 if (!checkTxnObj(txnobj, &txn)) return NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001594
1595 CHECK_DB_NOT_CLOSED(self);
1596 if (!DBObject_Check(secondaryDB)) {
1597 makeTypeError("DB", (PyObject*)secondaryDB);
1598 return NULL;
1599 }
Gregory P. Smith91116b62005-06-06 10:28:06 +00001600 CHECK_DB_NOT_CLOSED(secondaryDB);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001601 if (callback == Py_None) {
1602 callback = NULL;
1603 }
1604 else if (!PyCallable_Check(callback)) {
1605 makeTypeError("Callable", callback);
1606 return NULL;
1607 }
1608
1609 /* Save a reference to the callback in the secondary DB. */
Gregory P. Smith692ca9a2005-06-06 09:55:06 +00001610 Py_XDECREF(secondaryDB->associateCallback);
Thomas Woutersb3153832006-03-08 01:47:19 +00001611 Py_XINCREF(callback);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001612 secondaryDB->associateCallback = callback;
1613 secondaryDB->primaryDBType = _DB_get_type(self);
1614
Martin v. Löwisb2c7aff2002-11-23 11:26:07 +00001615 /* PyEval_InitThreads is called here due to a quirk in python 1.5
1616 * - 2.2.1 (at least) according to Russell Williamson <merel@wt.net>:
1617 * The global interepreter lock is not initialized until the first
1618 * thread is created using thread.start_new_thread() or fork() is
1619 * called. that would cause the ALLOW_THREADS here to segfault due
1620 * to a null pointer reference if no threads or child processes
1621 * have been created. This works around that and is a no-op if
1622 * threads have already been initialized.
1623 * (see pybsddb-users mailing list post on 2002-08-07)
1624 */
Gregory P. Smithaa71f5f2003-01-17 07:56:16 +00001625#ifdef WITH_THREAD
Martin v. Löwisb2c7aff2002-11-23 11:26:07 +00001626 PyEval_InitThreads();
Gregory P. Smithaa71f5f2003-01-17 07:56:16 +00001627#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001628 MYDB_BEGIN_ALLOW_THREADS;
Barry Warsaw9a0d7792002-12-30 20:53:52 +00001629 err = self->db->associate(self->db,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001630 txn,
Barry Warsaw9a0d7792002-12-30 20:53:52 +00001631 secondaryDB->db,
1632 _db_associateCallback,
1633 flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001634 MYDB_END_ALLOW_THREADS;
1635
1636 if (err) {
Serhiy Storchaka98a97222014-02-09 13:14:04 +02001637 Py_CLEAR(secondaryDB->associateCallback);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001638 secondaryDB->primaryDBType = 0;
1639 }
1640
1641 RETURN_IF_ERR();
1642 RETURN_NONE();
1643}
1644
1645
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001646static PyObject*
Jesus Cea5cd5f122008-09-23 18:54:08 +00001647DB_close_internal(DBObject* self, int flags, int do_not_close)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001648{
Jesus Ceaef9764f2008-05-13 18:45:46 +00001649 PyObject *dummy;
Jesus Cea5cd5f122008-09-23 18:54:08 +00001650 int err = 0;
Jesus Ceaef9764f2008-05-13 18:45:46 +00001651
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001652 if (self->db != NULL) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00001653 /* Can be NULL if db is not in an environment */
1654 EXTRACT_FROM_DOUBLE_LINKED_LIST_MAYBE_NULL(self);
Jesus Cea4907d272008-08-31 14:00:51 +00001655
Jesus Ceaef9764f2008-05-13 18:45:46 +00001656 if (self->txn) {
1657 EXTRACT_FROM_DOUBLE_LINKED_LIST_TXN(self);
1658 self->txn=NULL;
1659 }
1660
1661 while(self->children_cursors) {
1662 dummy=DBC_close_internal(self->children_cursors);
1663 Py_XDECREF(dummy);
1664 }
1665
Jesus Ceaef9764f2008-05-13 18:45:46 +00001666 while(self->children_sequences) {
1667 dummy=DBSequence_close_internal(self->children_sequences,0,0);
1668 Py_XDECREF(dummy);
1669 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00001670
Jesus Cea5cd5f122008-09-23 18:54:08 +00001671 /*
1672 ** "do_not_close" is used to dispose all related objects in the
1673 ** tree, without actually releasing the "root" object.
1674 ** This is done, for example, because function calls like
1675 ** "DB.verify()" implicitly close the underlying handle. So
1676 ** the handle doesn't need to be closed, but related objects
1677 ** must be cleaned up.
1678 */
1679 if (!do_not_close) {
1680 MYDB_BEGIN_ALLOW_THREADS;
1681 err = self->db->close(self->db, flags);
1682 MYDB_END_ALLOW_THREADS;
1683 self->db = NULL;
1684 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001685 RETURN_IF_ERR();
1686 }
1687 RETURN_NONE();
1688}
1689
Jesus Ceaef9764f2008-05-13 18:45:46 +00001690static PyObject*
1691DB_close(DBObject* self, PyObject* args)
1692{
1693 int flags=0;
1694 if (!PyArg_ParseTuple(args,"|i:close", &flags))
1695 return NULL;
Jesus Cea5cd5f122008-09-23 18:54:08 +00001696 return DB_close_internal(self, flags, 0);
Jesus Ceaef9764f2008-05-13 18:45:46 +00001697}
1698
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001699
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001700static PyObject*
1701_DB_consume(DBObject* self, PyObject* args, PyObject* kwargs, int consume_flag)
1702{
1703 int err, flags=0, type;
1704 PyObject* txnobj = NULL;
1705 PyObject* retval = NULL;
1706 DBT key, data;
1707 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00001708 static char* kwnames[] = { "txn", "flags", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001709
1710 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Oi:consume", kwnames,
1711 &txnobj, &flags))
1712 return NULL;
1713
1714 CHECK_DB_NOT_CLOSED(self);
1715 type = _DB_get_type(self);
1716 if (type == -1)
1717 return NULL;
1718 if (type != DB_QUEUE) {
Barry Warsaw9a0d7792002-12-30 20:53:52 +00001719 PyErr_SetString(PyExc_TypeError,
1720 "Consume methods only allowed for Queue DB's");
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001721 return NULL;
1722 }
1723 if (!checkTxnObj(txnobj, &txn))
1724 return NULL;
1725
1726 CLEAR_DBT(key);
1727 CLEAR_DBT(data);
1728 if (CHECK_DBFLAG(self, DB_THREAD)) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00001729 /* Tell Berkeley DB to malloc the return value (thread safe) */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001730 data.flags = DB_DBT_MALLOC;
1731 key.flags = DB_DBT_MALLOC;
1732 }
1733
1734 MYDB_BEGIN_ALLOW_THREADS;
1735 err = self->db->get(self->db, txn, &key, &data, flags|consume_flag);
1736 MYDB_END_ALLOW_THREADS;
1737
Gregory P. Smithe9477062005-06-04 06:46:59 +00001738 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001739 && self->moduleFlags.getReturnsNone) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001740 err = 0;
1741 Py_INCREF(Py_None);
1742 retval = Py_None;
1743 }
1744 else if (!err) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00001745 retval = BuildValue_SS(key.data, key.size, data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001746 FREE_DBT(key);
1747 FREE_DBT(data);
1748 }
1749
1750 RETURN_IF_ERR();
1751 return retval;
1752}
1753
1754static PyObject*
1755DB_consume(DBObject* self, PyObject* args, PyObject* kwargs, int consume_flag)
1756{
1757 return _DB_consume(self, args, kwargs, DB_CONSUME);
1758}
1759
1760static PyObject*
Barry Warsaw9a0d7792002-12-30 20:53:52 +00001761DB_consume_wait(DBObject* self, PyObject* args, PyObject* kwargs,
1762 int consume_flag)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001763{
1764 return _DB_consume(self, args, kwargs, DB_CONSUME_WAIT);
1765}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001766
1767
1768static PyObject*
1769DB_cursor(DBObject* self, PyObject* args, PyObject* kwargs)
1770{
1771 int err, flags=0;
1772 DBC* dbc;
1773 PyObject* txnobj = NULL;
1774 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00001775 static char* kwnames[] = { "txn", "flags", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001776
1777 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Oi:cursor", kwnames,
1778 &txnobj, &flags))
1779 return NULL;
1780 CHECK_DB_NOT_CLOSED(self);
1781 if (!checkTxnObj(txnobj, &txn))
1782 return NULL;
1783
1784 MYDB_BEGIN_ALLOW_THREADS;
1785 err = self->db->cursor(self->db, txn, &dbc, flags);
1786 MYDB_END_ALLOW_THREADS;
1787 RETURN_IF_ERR();
Jesus Ceaef9764f2008-05-13 18:45:46 +00001788 return (PyObject*) newDBCursorObject(dbc, (DBTxnObject *)txnobj, self);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001789}
1790
1791
1792static PyObject*
1793DB_delete(DBObject* self, PyObject* args, PyObject* kwargs)
1794{
1795 PyObject* txnobj = NULL;
1796 int flags = 0;
1797 PyObject* keyobj;
1798 DBT key;
1799 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00001800 static char* kwnames[] = { "key", "txn", "flags", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001801
1802 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|Oi:delete", kwnames,
1803 &keyobj, &txnobj, &flags))
1804 return NULL;
1805 CHECK_DB_NOT_CLOSED(self);
1806 if (!make_key_dbt(self, keyobj, &key, NULL))
1807 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00001808 if (!checkTxnObj(txnobj, &txn)) {
1809 FREE_DBT(key);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001810 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00001811 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001812
Gregory P. Smithdc5af702004-06-27 23:32:34 +00001813 if (-1 == _DB_delete(self, txn, &key, 0)) {
1814 FREE_DBT(key);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001815 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00001816 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001817
1818 FREE_DBT(key);
1819 RETURN_NONE();
1820}
1821
1822
Jesus Cea6557aac2010-03-22 14:22:26 +00001823#if (DBVER >= 47)
1824/*
1825** This function is available since Berkeley DB 4.4,
1826** but 4.6 version is so buggy that we only support
1827** it from BDB 4.7 and newer.
1828*/
1829static PyObject*
1830DB_compact(DBObject* self, PyObject* args, PyObject* kwargs)
1831{
1832 PyObject* txnobj = NULL;
1833 PyObject *startobj = NULL, *stopobj = NULL;
1834 int flags = 0;
1835 DB_TXN *txn = NULL;
1836 DBT *start_p = NULL, *stop_p = NULL;
1837 DBT start, stop;
1838 int err;
1839 DB_COMPACT c_data = { 0 };
1840 static char* kwnames[] = { "txn", "start", "stop", "flags",
1841 "compact_fillpercent", "compact_pages",
1842 "compact_timeout", NULL };
1843
1844
1845 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OOOiiiI:compact", kwnames,
1846 &txnobj, &startobj, &stopobj, &flags,
1847 &c_data.compact_fillpercent,
1848 &c_data.compact_pages,
1849 &c_data.compact_timeout))
1850 return NULL;
1851
1852 CHECK_DB_NOT_CLOSED(self);
1853 if (!checkTxnObj(txnobj, &txn)) {
1854 return NULL;
1855 }
1856
1857 if (startobj && make_key_dbt(self, startobj, &start, NULL)) {
1858 start_p = &start;
1859 }
1860 if (stopobj && make_key_dbt(self, stopobj, &stop, NULL)) {
1861 stop_p = &stop;
1862 }
1863
1864 MYDB_BEGIN_ALLOW_THREADS;
1865 err = self->db->compact(self->db, txn, start_p, stop_p, &c_data,
1866 flags, NULL);
1867 MYDB_END_ALLOW_THREADS;
1868
1869 if (startobj)
1870 FREE_DBT(start);
1871 if (stopobj)
1872 FREE_DBT(stop);
1873
1874 RETURN_IF_ERR();
1875
1876 return PyLong_FromUnsignedLong(c_data.compact_pages_truncated);
1877}
1878#endif
1879
1880
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001881static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00001882DB_fd(DBObject* self)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001883{
1884 int err, the_fd;
1885
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001886 CHECK_DB_NOT_CLOSED(self);
1887
1888 MYDB_BEGIN_ALLOW_THREADS;
1889 err = self->db->fd(self->db, &the_fd);
1890 MYDB_END_ALLOW_THREADS;
1891 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00001892 return NUMBER_FromLong(the_fd);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001893}
1894
1895
Jesus Cea6557aac2010-03-22 14:22:26 +00001896#if (DBVER >= 46)
1897static PyObject*
1898DB_exists(DBObject* self, PyObject* args, PyObject* kwargs)
1899{
1900 int err, flags=0;
1901 PyObject* txnobj = NULL;
1902 PyObject* keyobj;
1903 DBT key;
1904 DB_TXN *txn;
1905
1906 static char* kwnames[] = {"key", "txn", "flags", NULL};
1907
1908 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|Oi:exists", kwnames,
1909 &keyobj, &txnobj, &flags))
1910 return NULL;
1911
1912 CHECK_DB_NOT_CLOSED(self);
1913 if (!make_key_dbt(self, keyobj, &key, NULL))
1914 return NULL;
1915 if (!checkTxnObj(txnobj, &txn)) {
1916 FREE_DBT(key);
1917 return NULL;
1918 }
1919
1920 MYDB_BEGIN_ALLOW_THREADS;
1921 err = self->db->exists(self->db, txn, &key, flags);
1922 MYDB_END_ALLOW_THREADS;
1923
1924 FREE_DBT(key);
1925
1926 if (!err) {
1927 Py_INCREF(Py_True);
1928 return Py_True;
1929 }
1930 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)) {
1931 Py_INCREF(Py_False);
1932 return Py_False;
1933 }
1934
1935 /*
1936 ** If we reach there, there was an error. The
1937 ** "return" should be unreachable.
1938 */
1939 RETURN_IF_ERR();
1940 assert(0); /* This coude SHOULD be unreachable */
1941 return NULL;
1942}
1943#endif
1944
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001945static PyObject*
1946DB_get(DBObject* self, PyObject* args, PyObject* kwargs)
1947{
1948 int err, flags=0;
1949 PyObject* txnobj = NULL;
1950 PyObject* keyobj;
1951 PyObject* dfltobj = NULL;
1952 PyObject* retval = NULL;
1953 int dlen = -1;
1954 int doff = -1;
1955 DBT key, data;
1956 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00001957 static char* kwnames[] = {"key", "default", "txn", "flags", "dlen",
Jeremy Hyltonaf68c872005-12-10 18:50:16 +00001958 "doff", NULL};
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001959
1960 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|OOiii:get", kwnames,
Barry Warsaw9a0d7792002-12-30 20:53:52 +00001961 &keyobj, &dfltobj, &txnobj, &flags, &dlen,
1962 &doff))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001963 return NULL;
1964
1965 CHECK_DB_NOT_CLOSED(self);
1966 if (!make_key_dbt(self, keyobj, &key, &flags))
1967 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00001968 if (!checkTxnObj(txnobj, &txn)) {
1969 FREE_DBT(key);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001970 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00001971 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001972
1973 CLEAR_DBT(data);
1974 if (CHECK_DBFLAG(self, DB_THREAD)) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00001975 /* Tell Berkeley DB to malloc the return value (thread safe) */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001976 data.flags = DB_DBT_MALLOC;
1977 }
Gregory P. Smithdc5af702004-06-27 23:32:34 +00001978 if (!add_partial_dbt(&data, dlen, doff)) {
1979 FREE_DBT(key);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001980 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00001981 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001982
1983 MYDB_BEGIN_ALLOW_THREADS;
1984 err = self->db->get(self->db, txn, &key, &data, flags);
1985 MYDB_END_ALLOW_THREADS;
1986
Gregory P. Smithe9477062005-06-04 06:46:59 +00001987 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY) && (dfltobj != NULL)) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001988 err = 0;
1989 Py_INCREF(dfltobj);
1990 retval = dfltobj;
1991 }
Gregory P. Smithe9477062005-06-04 06:46:59 +00001992 else if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001993 && self->moduleFlags.getReturnsNone) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001994 err = 0;
1995 Py_INCREF(Py_None);
1996 retval = Py_None;
1997 }
1998 else if (!err) {
1999 if (flags & DB_SET_RECNO) /* return both key and data */
Jesus Ceaef9764f2008-05-13 18:45:46 +00002000 retval = BuildValue_SS(key.data, key.size, data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002001 else /* return just the data */
Jesus Ceaef9764f2008-05-13 18:45:46 +00002002 retval = Build_PyString(data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002003 FREE_DBT(data);
2004 }
Gregory P. Smithdc5af702004-06-27 23:32:34 +00002005 FREE_DBT(key);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002006
2007 RETURN_IF_ERR();
2008 return retval;
2009}
2010
Gregory P. Smith19699a92004-06-28 04:06:49 +00002011static PyObject*
2012DB_pget(DBObject* self, PyObject* args, PyObject* kwargs)
2013{
2014 int err, flags=0;
2015 PyObject* txnobj = NULL;
2016 PyObject* keyobj;
2017 PyObject* dfltobj = NULL;
2018 PyObject* retval = NULL;
2019 int dlen = -1;
2020 int doff = -1;
2021 DBT key, pkey, data;
2022 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002023 static char* kwnames[] = {"key", "default", "txn", "flags", "dlen",
Jeremy Hyltonaf68c872005-12-10 18:50:16 +00002024 "doff", NULL};
Gregory P. Smith19699a92004-06-28 04:06:49 +00002025
2026 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|OOiii:pget", kwnames,
2027 &keyobj, &dfltobj, &txnobj, &flags, &dlen,
2028 &doff))
2029 return NULL;
2030
2031 CHECK_DB_NOT_CLOSED(self);
2032 if (!make_key_dbt(self, keyobj, &key, &flags))
2033 return NULL;
2034 if (!checkTxnObj(txnobj, &txn)) {
2035 FREE_DBT(key);
2036 return NULL;
2037 }
2038
2039 CLEAR_DBT(data);
2040 if (CHECK_DBFLAG(self, DB_THREAD)) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00002041 /* Tell Berkeley DB to malloc the return value (thread safe) */
Gregory P. Smith19699a92004-06-28 04:06:49 +00002042 data.flags = DB_DBT_MALLOC;
2043 }
2044 if (!add_partial_dbt(&data, dlen, doff)) {
2045 FREE_DBT(key);
2046 return NULL;
2047 }
2048
2049 CLEAR_DBT(pkey);
2050 pkey.flags = DB_DBT_MALLOC;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002051
Gregory P. Smith19699a92004-06-28 04:06:49 +00002052 MYDB_BEGIN_ALLOW_THREADS;
2053 err = self->db->pget(self->db, txn, &key, &pkey, &data, flags);
2054 MYDB_END_ALLOW_THREADS;
2055
Gregory P. Smithe9477062005-06-04 06:46:59 +00002056 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY) && (dfltobj != NULL)) {
Gregory P. Smith19699a92004-06-28 04:06:49 +00002057 err = 0;
2058 Py_INCREF(dfltobj);
2059 retval = dfltobj;
2060 }
Gregory P. Smithe9477062005-06-04 06:46:59 +00002061 else if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002062 && self->moduleFlags.getReturnsNone) {
Gregory P. Smith19699a92004-06-28 04:06:49 +00002063 err = 0;
2064 Py_INCREF(Py_None);
2065 retval = Py_None;
2066 }
2067 else if (!err) {
2068 PyObject *pkeyObj;
2069 PyObject *dataObj;
Jesus Ceaef9764f2008-05-13 18:45:46 +00002070 dataObj = Build_PyString(data.data, data.size);
Gregory P. Smith19699a92004-06-28 04:06:49 +00002071
2072 if (self->primaryDBType == DB_RECNO ||
2073 self->primaryDBType == DB_QUEUE)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002074 pkeyObj = NUMBER_FromLong(*(int *)pkey.data);
Gregory P. Smith19699a92004-06-28 04:06:49 +00002075 else
Jesus Ceaef9764f2008-05-13 18:45:46 +00002076 pkeyObj = Build_PyString(pkey.data, pkey.size);
Gregory P. Smith19699a92004-06-28 04:06:49 +00002077
2078 if (flags & DB_SET_RECNO) /* return key , pkey and data */
2079 {
2080 PyObject *keyObj;
2081 int type = _DB_get_type(self);
2082 if (type == DB_RECNO || type == DB_QUEUE)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002083 keyObj = NUMBER_FromLong(*(int *)key.data);
Gregory P. Smith19699a92004-06-28 04:06:49 +00002084 else
Jesus Ceaef9764f2008-05-13 18:45:46 +00002085 keyObj = Build_PyString(key.data, key.size);
Gregory P. Smith4e414d82006-01-24 19:55:02 +00002086 retval = PyTuple_Pack(3, keyObj, pkeyObj, dataObj);
Thomas Woutersb3153832006-03-08 01:47:19 +00002087 Py_DECREF(keyObj);
Gregory P. Smith19699a92004-06-28 04:06:49 +00002088 }
2089 else /* return just the pkey and data */
2090 {
Gregory P. Smith4e414d82006-01-24 19:55:02 +00002091 retval = PyTuple_Pack(2, pkeyObj, dataObj);
Gregory P. Smith19699a92004-06-28 04:06:49 +00002092 }
Thomas Woutersb3153832006-03-08 01:47:19 +00002093 Py_DECREF(dataObj);
2094 Py_DECREF(pkeyObj);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002095 FREE_DBT(pkey);
Gregory P. Smith19699a92004-06-28 04:06:49 +00002096 FREE_DBT(data);
2097 }
2098 FREE_DBT(key);
2099
2100 RETURN_IF_ERR();
2101 return retval;
2102}
2103
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002104
2105/* Return size of entry */
2106static PyObject*
2107DB_get_size(DBObject* self, PyObject* args, PyObject* kwargs)
2108{
2109 int err, flags=0;
2110 PyObject* txnobj = NULL;
2111 PyObject* keyobj;
2112 PyObject* retval = NULL;
2113 DBT key, data;
2114 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002115 static char* kwnames[] = { "key", "txn", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002116
2117 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O:get_size", kwnames,
2118 &keyobj, &txnobj))
2119 return NULL;
2120 CHECK_DB_NOT_CLOSED(self);
2121 if (!make_key_dbt(self, keyobj, &key, &flags))
2122 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00002123 if (!checkTxnObj(txnobj, &txn)) {
2124 FREE_DBT(key);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002125 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00002126 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002127 CLEAR_DBT(data);
2128
Gregory P. Smith8b7e9172004-12-13 09:51:23 +00002129 /* We don't allocate any memory, forcing a DB_BUFFER_SMALL error and
2130 thus getting the record size. */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002131 data.flags = DB_DBT_USERMEM;
2132 data.ulen = 0;
2133 MYDB_BEGIN_ALLOW_THREADS;
2134 err = self->db->get(self->db, txn, &key, &data, flags);
2135 MYDB_END_ALLOW_THREADS;
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07002136 if ((err == DB_BUFFER_SMALL) || (err == 0)) {
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002137 retval = NUMBER_FromLong((long)data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002138 err = 0;
2139 }
2140
2141 FREE_DBT(key);
2142 FREE_DBT(data);
2143 RETURN_IF_ERR();
2144 return retval;
2145}
2146
2147
2148static PyObject*
2149DB_get_both(DBObject* self, PyObject* args, PyObject* kwargs)
2150{
2151 int err, flags=0;
2152 PyObject* txnobj = NULL;
2153 PyObject* keyobj;
2154 PyObject* dataobj;
2155 PyObject* retval = NULL;
2156 DBT key, data;
Neal Norwitz994ebed2007-06-03 20:32:50 +00002157 void *orig_data;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002158 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002159 static char* kwnames[] = { "key", "data", "txn", "flags", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002160
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002161 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|Oi:get_both", kwnames,
2162 &keyobj, &dataobj, &txnobj, &flags))
2163 return NULL;
2164
2165 CHECK_DB_NOT_CLOSED(self);
2166 if (!make_key_dbt(self, keyobj, &key, NULL))
2167 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00002168 if ( !make_dbt(dataobj, &data) ||
2169 !checkTxnObj(txnobj, &txn) )
2170 {
2171 FREE_DBT(key);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002172 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00002173 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002174
2175 flags |= DB_GET_BOTH;
Neal Norwitz994ebed2007-06-03 20:32:50 +00002176 orig_data = data.data;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002177
2178 if (CHECK_DBFLAG(self, DB_THREAD)) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00002179 /* Tell Berkeley DB to malloc the return value (thread safe) */
Neal Norwitz994ebed2007-06-03 20:32:50 +00002180 /* XXX(nnorwitz): At least 4.4.20 and 4.5.20 require this flag. */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002181 data.flags = DB_DBT_MALLOC;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002182 }
2183
2184 MYDB_BEGIN_ALLOW_THREADS;
2185 err = self->db->get(self->db, txn, &key, &data, flags);
2186 MYDB_END_ALLOW_THREADS;
2187
Gregory P. Smithe9477062005-06-04 06:46:59 +00002188 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002189 && self->moduleFlags.getReturnsNone) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002190 err = 0;
2191 Py_INCREF(Py_None);
2192 retval = Py_None;
2193 }
2194 else if (!err) {
Neal Norwitz994ebed2007-06-03 20:32:50 +00002195 /* XXX(nnorwitz): can we do: retval = dataobj; Py_INCREF(retval); */
Jesus Ceaef9764f2008-05-13 18:45:46 +00002196 retval = Build_PyString(data.data, data.size);
Neal Norwitz994ebed2007-06-03 20:32:50 +00002197
2198 /* Even though the flags require DB_DBT_MALLOC, data is not always
2199 allocated. 4.4: allocated, 4.5: *not* allocated. :-( */
2200 if (data.data != orig_data)
2201 FREE_DBT(data);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002202 }
2203
2204 FREE_DBT(key);
2205 RETURN_IF_ERR();
2206 return retval;
2207}
2208
2209
2210static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002211DB_get_byteswapped(DBObject* self)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002212{
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002213 int err = 0;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002214 int retval = -1;
2215
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002216 CHECK_DB_NOT_CLOSED(self);
2217
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002218 MYDB_BEGIN_ALLOW_THREADS;
2219 err = self->db->get_byteswapped(self->db, &retval);
2220 MYDB_END_ALLOW_THREADS;
2221 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002222 return NUMBER_FromLong(retval);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002223}
2224
2225
2226static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002227DB_get_type(DBObject* self)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002228{
2229 int type;
2230
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002231 CHECK_DB_NOT_CLOSED(self);
2232
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002233 type = _DB_get_type(self);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002234 if (type == -1)
2235 return NULL;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002236 return NUMBER_FromLong(type);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002237}
2238
2239
2240static PyObject*
2241DB_join(DBObject* self, PyObject* args)
2242{
2243 int err, flags=0;
2244 int length, x;
2245 PyObject* cursorsObj;
2246 DBC** cursors;
2247 DBC* dbc;
2248
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002249 if (!PyArg_ParseTuple(args,"O|i:join", &cursorsObj, &flags))
2250 return NULL;
2251
2252 CHECK_DB_NOT_CLOSED(self);
2253
2254 if (!PySequence_Check(cursorsObj)) {
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002255 PyErr_SetString(PyExc_TypeError,
2256 "Sequence of DBCursor objects expected");
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002257 return NULL;
2258 }
2259
2260 length = PyObject_Length(cursorsObj);
2261 cursors = malloc((length+1) * sizeof(DBC*));
Neal Norwitz5aa96892006-08-13 18:11:43 +00002262 if (!cursors) {
Jesus Cea6557aac2010-03-22 14:22:26 +00002263 PyErr_NoMemory();
2264 return NULL;
Neal Norwitz5aa96892006-08-13 18:11:43 +00002265 }
2266
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002267 cursors[length] = NULL;
2268 for (x=0; x<length; x++) {
2269 PyObject* item = PySequence_GetItem(cursorsObj, x);
Thomas Woutersb3153832006-03-08 01:47:19 +00002270 if (item == NULL) {
2271 free(cursors);
2272 return NULL;
2273 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002274 if (!DBCursorObject_Check(item)) {
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002275 PyErr_SetString(PyExc_TypeError,
2276 "Sequence of DBCursor objects expected");
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002277 free(cursors);
2278 return NULL;
2279 }
2280 cursors[x] = ((DBCursorObject*)item)->dbc;
Thomas Woutersb2820ae2006-03-12 00:01:38 +00002281 Py_DECREF(item);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002282 }
2283
2284 MYDB_BEGIN_ALLOW_THREADS;
2285 err = self->db->join(self->db, cursors, &dbc, flags);
2286 MYDB_END_ALLOW_THREADS;
2287 free(cursors);
2288 RETURN_IF_ERR();
2289
Gregory P. Smith7441e652003-11-03 21:35:31 +00002290 /* FIXME: this is a buggy interface. The returned cursor
2291 contains internal references to the passed in cursors
2292 but does not hold python references to them or prevent
2293 them from being closed prematurely. This can cause
2294 python to crash when things are done in the wrong order. */
Jesus Ceaef9764f2008-05-13 18:45:46 +00002295 return (PyObject*) newDBCursorObject(dbc, NULL, self);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002296}
2297
2298
2299static PyObject*
2300DB_key_range(DBObject* self, PyObject* args, PyObject* kwargs)
2301{
2302 int err, flags=0;
2303 PyObject* txnobj = NULL;
2304 PyObject* keyobj;
2305 DBT key;
2306 DB_TXN *txn = NULL;
2307 DB_KEY_RANGE range;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002308 static char* kwnames[] = { "key", "txn", "flags", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002309
2310 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|Oi:key_range", kwnames,
2311 &keyobj, &txnobj, &flags))
2312 return NULL;
2313 CHECK_DB_NOT_CLOSED(self);
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002314 if (!make_dbt(keyobj, &key))
2315 /* BTree only, don't need to allow for an int key */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002316 return NULL;
2317 if (!checkTxnObj(txnobj, &txn))
2318 return NULL;
2319
2320 MYDB_BEGIN_ALLOW_THREADS;
2321 err = self->db->key_range(self->db, txn, &key, &range, flags);
2322 MYDB_END_ALLOW_THREADS;
2323
2324 RETURN_IF_ERR();
2325 return Py_BuildValue("ddd", range.less, range.equal, range.greater);
2326}
2327
2328
2329static PyObject*
2330DB_open(DBObject* self, PyObject* args, PyObject* kwargs)
2331{
2332 int err, type = DB_UNKNOWN, flags=0, mode=0660;
2333 char* filename = NULL;
2334 char* dbname = NULL;
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002335 PyObject *txnobj = NULL;
2336 DB_TXN *txn = NULL;
2337 /* with dbname */
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002338 static char* kwnames[] = {
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002339 "filename", "dbname", "dbtype", "flags", "mode", "txn", NULL};
2340 /* without dbname */
Tim Peters85b10522006-02-28 18:33:35 +00002341 static char* kwnames_basic[] = {
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002342 "filename", "dbtype", "flags", "mode", "txn", NULL};
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002343
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002344 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "z|ziiiO:open", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002345 &filename, &dbname, &type, &flags, &mode,
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002346 &txnobj))
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002347 {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002348 PyErr_Clear();
2349 type = DB_UNKNOWN; flags = 0; mode = 0660;
2350 filename = NULL; dbname = NULL;
2351 if (!PyArg_ParseTupleAndKeywords(args, kwargs,"z|iiiO:open",
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002352 kwnames_basic,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002353 &filename, &type, &flags, &mode,
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002354 &txnobj))
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002355 return NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002356 }
2357
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002358 if (!checkTxnObj(txnobj, &txn)) return NULL;
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002359
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002360 if (NULL == self->db) {
Thomas Woutersb3153832006-03-08 01:47:19 +00002361 PyObject *t = Py_BuildValue("(is)", 0,
2362 "Cannot call open() twice for DB object");
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002363 if (t) {
2364 PyErr_SetObject(DBError, t);
2365 Py_DECREF(t);
2366 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002367 return NULL;
2368 }
2369
Jesus Ceaef9764f2008-05-13 18:45:46 +00002370 if (txn) { /* Can't use 'txnobj' because could be 'txnobj==Py_None' */
2371 INSERT_IN_DOUBLE_LINKED_LIST_TXN(((DBTxnObject *)txnobj)->children_dbs,self);
2372 self->txn=(DBTxnObject *)txnobj;
2373 } else {
2374 self->txn=NULL;
2375 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00002376
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002377 MYDB_BEGIN_ALLOW_THREADS;
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002378 err = self->db->open(self->db, txn, filename, dbname, type, flags, mode);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002379 MYDB_END_ALLOW_THREADS;
Jesus Cea6557aac2010-03-22 14:22:26 +00002380
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002381 if (makeDBError(err)) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00002382 PyObject *dummy;
2383
Jesus Cea5cd5f122008-09-23 18:54:08 +00002384 dummy=DB_close_internal(self, 0, 0);
Jesus Ceaef9764f2008-05-13 18:45:46 +00002385 Py_XDECREF(dummy);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002386 return NULL;
2387 }
2388
Gregory P. Smithec10a4a2007-11-05 02:32:26 +00002389 self->db->get_flags(self->db, &self->setflags);
2390
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002391 self->flags = flags;
Jesus Ceaef9764f2008-05-13 18:45:46 +00002392
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002393 RETURN_NONE();
2394}
2395
2396
2397static PyObject*
2398DB_put(DBObject* self, PyObject* args, PyObject* kwargs)
2399{
2400 int flags=0;
2401 PyObject* txnobj = NULL;
2402 int dlen = -1;
2403 int doff = -1;
2404 PyObject* keyobj, *dataobj, *retval;
2405 DBT key, data;
2406 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002407 static char* kwnames[] = { "key", "data", "txn", "flags", "dlen",
Jeremy Hyltonaf68c872005-12-10 18:50:16 +00002408 "doff", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002409
2410 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|Oiii:put", kwnames,
2411 &keyobj, &dataobj, &txnobj, &flags, &dlen, &doff))
2412 return NULL;
2413
2414 CHECK_DB_NOT_CLOSED(self);
Gregory P. Smithdc5af702004-06-27 23:32:34 +00002415 if (!make_key_dbt(self, keyobj, &key, NULL))
2416 return NULL;
2417 if ( !make_dbt(dataobj, &data) ||
2418 !add_partial_dbt(&data, dlen, doff) ||
2419 !checkTxnObj(txnobj, &txn) )
2420 {
2421 FREE_DBT(key);
2422 return NULL;
2423 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002424
2425 if (-1 == _DB_put(self, txn, &key, &data, flags)) {
2426 FREE_DBT(key);
2427 return NULL;
2428 }
2429
2430 if (flags & DB_APPEND)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002431 retval = NUMBER_FromLong(*((db_recno_t*)key.data));
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002432 else {
2433 retval = Py_None;
2434 Py_INCREF(retval);
2435 }
2436 FREE_DBT(key);
2437 return retval;
2438}
2439
2440
2441
2442static PyObject*
2443DB_remove(DBObject* self, PyObject* args, PyObject* kwargs)
2444{
2445 char* filename;
2446 char* database = NULL;
2447 int err, flags=0;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002448 static char* kwnames[] = { "filename", "dbname", "flags", NULL};
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002449
2450 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|zi:remove", kwnames,
2451 &filename, &database, &flags))
2452 return NULL;
2453 CHECK_DB_NOT_CLOSED(self);
2454
Jesus Cea4907d272008-08-31 14:00:51 +00002455 EXTRACT_FROM_DOUBLE_LINKED_LIST_MAYBE_NULL(self);
2456
2457 MYDB_BEGIN_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002458 err = self->db->remove(self->db, filename, database, flags);
Jesus Cea4907d272008-08-31 14:00:51 +00002459 MYDB_END_ALLOW_THREADS;
2460
Gregory P. Smithf655dff2003-05-15 00:13:18 +00002461 self->db = NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002462 RETURN_IF_ERR();
2463 RETURN_NONE();
2464}
2465
2466
2467
2468static PyObject*
2469DB_rename(DBObject* self, PyObject* args)
2470{
2471 char* filename;
2472 char* database;
2473 char* newname;
2474 int err, flags=0;
2475
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002476 if (!PyArg_ParseTuple(args, "sss|i:rename", &filename, &database, &newname,
2477 &flags))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002478 return NULL;
2479 CHECK_DB_NOT_CLOSED(self);
2480
2481 MYDB_BEGIN_ALLOW_THREADS;
2482 err = self->db->rename(self->db, filename, database, newname, flags);
2483 MYDB_END_ALLOW_THREADS;
2484 RETURN_IF_ERR();
2485 RETURN_NONE();
2486}
2487
2488
2489static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002490DB_get_private(DBObject* self)
2491{
2492 /* We can give out the private field even if db is closed */
Jesus Cea4907d272008-08-31 14:00:51 +00002493 Py_INCREF(self->private_obj);
2494 return self->private_obj;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002495}
2496
2497static PyObject*
Jesus Cea4907d272008-08-31 14:00:51 +00002498DB_set_private(DBObject* self, PyObject* private_obj)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002499{
2500 /* We can set the private field even if db is closed */
Jesus Cea4907d272008-08-31 14:00:51 +00002501 Py_DECREF(self->private_obj);
2502 Py_INCREF(private_obj);
2503 self->private_obj = private_obj;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002504 RETURN_NONE();
2505}
2506
Jesus Cea6557aac2010-03-22 14:22:26 +00002507#if (DBVER >= 46)
2508static PyObject*
2509DB_set_priority(DBObject* self, PyObject* args)
2510{
2511 int err, priority;
2512
2513 if (!PyArg_ParseTuple(args,"i:set_priority", &priority))
2514 return NULL;
2515 CHECK_DB_NOT_CLOSED(self);
2516
2517 MYDB_BEGIN_ALLOW_THREADS;
2518 err = self->db->set_priority(self->db, priority);
2519 MYDB_END_ALLOW_THREADS;
2520 RETURN_IF_ERR();
2521 RETURN_NONE();
2522}
2523
2524static PyObject*
2525DB_get_priority(DBObject* self)
2526{
2527 int err = 0;
2528 DB_CACHE_PRIORITY priority;
2529
2530 CHECK_DB_NOT_CLOSED(self);
2531
2532 MYDB_BEGIN_ALLOW_THREADS;
2533 err = self->db->get_priority(self->db, &priority);
2534 MYDB_END_ALLOW_THREADS;
2535 RETURN_IF_ERR();
2536 return NUMBER_FromLong(priority);
2537}
2538#endif
2539
2540static PyObject*
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07002541DB_get_dbname(DBObject* self)
2542{
2543 int err;
2544 const char *filename, *dbname;
2545
2546 CHECK_DB_NOT_CLOSED(self);
2547
2548 MYDB_BEGIN_ALLOW_THREADS;
2549 err = self->db->get_dbname(self->db, &filename, &dbname);
2550 MYDB_END_ALLOW_THREADS;
2551 RETURN_IF_ERR();
2552 /* If "dbname==NULL", it is correctly converted to "None" */
2553 return Py_BuildValue("(ss)", filename, dbname);
2554}
2555
2556static PyObject*
2557DB_get_open_flags(DBObject* self)
2558{
2559 int err;
2560 unsigned int flags;
2561
2562 CHECK_DB_NOT_CLOSED(self);
2563
2564 MYDB_BEGIN_ALLOW_THREADS;
2565 err = self->db->get_open_flags(self->db, &flags);
2566 MYDB_END_ALLOW_THREADS;
2567 RETURN_IF_ERR();
2568 return NUMBER_FromLong(flags);
2569}
2570
2571static PyObject*
Jesus Cea6557aac2010-03-22 14:22:26 +00002572DB_set_q_extentsize(DBObject* self, PyObject* args)
2573{
2574 int err;
2575 u_int32_t extentsize;
2576
2577 if (!PyArg_ParseTuple(args,"i:set_q_extentsize", &extentsize))
2578 return NULL;
2579 CHECK_DB_NOT_CLOSED(self);
2580
2581 MYDB_BEGIN_ALLOW_THREADS;
2582 err = self->db->set_q_extentsize(self->db, extentsize);
2583 MYDB_END_ALLOW_THREADS;
2584 RETURN_IF_ERR();
2585 RETURN_NONE();
2586}
2587
Jesus Cea6557aac2010-03-22 14:22:26 +00002588static PyObject*
2589DB_get_q_extentsize(DBObject* self)
2590{
2591 int err = 0;
2592 u_int32_t extentsize;
2593
2594 CHECK_DB_NOT_CLOSED(self);
2595
2596 MYDB_BEGIN_ALLOW_THREADS;
2597 err = self->db->get_q_extentsize(self->db, &extentsize);
2598 MYDB_END_ALLOW_THREADS;
2599 RETURN_IF_ERR();
2600 return NUMBER_FromLong(extentsize);
2601}
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002602
2603static PyObject*
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002604DB_set_bt_minkey(DBObject* self, PyObject* args)
2605{
2606 int err, minkey;
2607
Jesus Cea6557aac2010-03-22 14:22:26 +00002608 if (!PyArg_ParseTuple(args,"i:set_bt_minkey", &minkey))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002609 return NULL;
2610 CHECK_DB_NOT_CLOSED(self);
2611
2612 MYDB_BEGIN_ALLOW_THREADS;
2613 err = self->db->set_bt_minkey(self->db, minkey);
2614 MYDB_END_ALLOW_THREADS;
2615 RETURN_IF_ERR();
2616 RETURN_NONE();
2617}
2618
Jesus Cea6557aac2010-03-22 14:22:26 +00002619static PyObject*
2620DB_get_bt_minkey(DBObject* self)
2621{
2622 int err;
2623 u_int32_t bt_minkey;
2624
2625 CHECK_DB_NOT_CLOSED(self);
2626
2627 MYDB_BEGIN_ALLOW_THREADS;
2628 err = self->db->get_bt_minkey(self->db, &bt_minkey);
2629 MYDB_END_ALLOW_THREADS;
2630 RETURN_IF_ERR();
2631 return NUMBER_FromLong(bt_minkey);
2632}
Jesus Cea6557aac2010-03-22 14:22:26 +00002633
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002634static int
Georg Brandlef1701f2006-03-07 14:57:48 +00002635_default_cmp(const DBT *leftKey,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002636 const DBT *rightKey)
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002637{
2638 int res;
2639 int lsize = leftKey->size, rsize = rightKey->size;
2640
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002641 res = memcmp(leftKey->data, rightKey->data,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002642 lsize < rsize ? lsize : rsize);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002643
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002644 if (res == 0) {
2645 if (lsize < rsize) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002646 res = -1;
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002647 }
2648 else if (lsize > rsize) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002649 res = 1;
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002650 }
2651 }
2652 return res;
2653}
2654
2655static int
Jesus Ceaef9764f2008-05-13 18:45:46 +00002656_db_compareCallback(DB* db,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002657 const DBT *leftKey,
2658 const DBT *rightKey)
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002659{
2660 int res = 0;
2661 PyObject *args;
Thomas Woutersb2820ae2006-03-12 00:01:38 +00002662 PyObject *result = NULL;
Georg Brandlef1701f2006-03-07 14:57:48 +00002663 DBObject *self = (DBObject *)db->app_private;
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002664
2665 if (self == NULL || self->btCompareCallback == NULL) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002666 MYDB_BEGIN_BLOCK_THREADS;
2667 PyErr_SetString(PyExc_TypeError,
2668 (self == 0
2669 ? "DB_bt_compare db is NULL."
2670 : "DB_bt_compare callback is NULL."));
2671 /* we're in a callback within the DB code, we can't raise */
2672 PyErr_Print();
2673 res = _default_cmp(leftKey, rightKey);
2674 MYDB_END_BLOCK_THREADS;
Georg Brandlef1701f2006-03-07 14:57:48 +00002675 } else {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002676 MYDB_BEGIN_BLOCK_THREADS;
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002677
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002678 args = BuildValue_SS(leftKey->data, leftKey->size, rightKey->data, rightKey->size);
2679 if (args != NULL) {
2680 result = PyEval_CallObject(self->btCompareCallback, args);
2681 }
2682 if (args == NULL || result == NULL) {
2683 /* we're in a callback within the DB code, we can't raise */
2684 PyErr_Print();
2685 res = _default_cmp(leftKey, rightKey);
2686 } else if (NUMBER_Check(result)) {
2687 res = NUMBER_AsLong(result);
2688 } else {
2689 PyErr_SetString(PyExc_TypeError,
2690 "DB_bt_compare callback MUST return an int.");
2691 /* we're in a callback within the DB code, we can't raise */
2692 PyErr_Print();
2693 res = _default_cmp(leftKey, rightKey);
2694 }
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002695
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002696 Py_XDECREF(args);
2697 Py_XDECREF(result);
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002698
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002699 MYDB_END_BLOCK_THREADS;
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002700 }
2701 return res;
2702}
2703
2704static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002705DB_set_bt_compare(DBObject* self, PyObject* comparator)
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002706{
2707 int err;
Thomas Woutersb3153832006-03-08 01:47:19 +00002708 PyObject *tuple, *result;
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002709
Georg Brandlef1701f2006-03-07 14:57:48 +00002710 CHECK_DB_NOT_CLOSED(self);
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002711
Georg Brandlef1701f2006-03-07 14:57:48 +00002712 if (!PyCallable_Check(comparator)) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002713 makeTypeError("Callable", comparator);
2714 return NULL;
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002715 }
2716
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002717 /*
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002718 * Perform a test call of the comparator function with two empty
2719 * string objects here. verify that it returns an int (0).
2720 * err if not.
2721 */
Thomas Woutersb3153832006-03-08 01:47:19 +00002722 tuple = Py_BuildValue("(ss)", "", "");
Georg Brandlef1701f2006-03-07 14:57:48 +00002723 result = PyEval_CallObject(comparator, tuple);
2724 Py_DECREF(tuple);
Thomas Woutersb3153832006-03-08 01:47:19 +00002725 if (result == NULL)
2726 return NULL;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002727 if (!NUMBER_Check(result)) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002728 Py_DECREF(result);
2729 PyErr_SetString(PyExc_TypeError,
2730 "callback MUST return an int");
2731 return NULL;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002732 } else if (NUMBER_AsLong(result) != 0) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002733 Py_DECREF(result);
2734 PyErr_SetString(PyExc_TypeError,
2735 "callback failed to return 0 on two empty strings");
2736 return NULL;
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002737 }
Thomas Woutersb3153832006-03-08 01:47:19 +00002738 Py_DECREF(result);
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002739
2740 /* We don't accept multiple set_bt_compare operations, in order to
2741 * simplify the code. This would have no real use, as one cannot
2742 * change the function once the db is opened anyway */
2743 if (self->btCompareCallback != NULL) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002744 PyErr_SetString(PyExc_RuntimeError, "set_bt_compare() cannot be called more than once");
2745 return NULL;
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002746 }
2747
Georg Brandlef1701f2006-03-07 14:57:48 +00002748 Py_INCREF(comparator);
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002749 self->btCompareCallback = comparator;
2750
2751 /* This is to workaround a problem with un-initialized threads (see
2752 comment in DB_associate) */
2753#ifdef WITH_THREAD
2754 PyEval_InitThreads();
2755#endif
2756
Thomas Woutersb3153832006-03-08 01:47:19 +00002757 err = self->db->set_bt_compare(self->db, _db_compareCallback);
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002758
2759 if (err) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002760 /* restore the old state in case of error */
2761 Py_DECREF(comparator);
2762 self->btCompareCallback = NULL;
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002763 }
2764
Georg Brandlef1701f2006-03-07 14:57:48 +00002765 RETURN_IF_ERR();
2766 RETURN_NONE();
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002767}
2768
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07002769static int
2770_db_dupCompareCallback(DB* db,
2771 const DBT *leftKey,
2772 const DBT *rightKey)
2773{
2774 int res = 0;
2775 PyObject *args;
2776 PyObject *result = NULL;
2777 DBObject *self = (DBObject *)db->app_private;
2778
2779 if (self == NULL || self->dupCompareCallback == NULL) {
2780 MYDB_BEGIN_BLOCK_THREADS;
2781 PyErr_SetString(PyExc_TypeError,
2782 (self == 0
2783 ? "DB_dup_compare db is NULL."
2784 : "DB_dup_compare callback is NULL."));
2785 /* we're in a callback within the DB code, we can't raise */
2786 PyErr_Print();
2787 res = _default_cmp(leftKey, rightKey);
2788 MYDB_END_BLOCK_THREADS;
2789 } else {
2790 MYDB_BEGIN_BLOCK_THREADS;
2791
2792 args = BuildValue_SS(leftKey->data, leftKey->size, rightKey->data, rightKey->size);
2793 if (args != NULL) {
2794 result = PyEval_CallObject(self->dupCompareCallback, args);
2795 }
2796 if (args == NULL || result == NULL) {
2797 /* we're in a callback within the DB code, we can't raise */
2798 PyErr_Print();
2799 res = _default_cmp(leftKey, rightKey);
2800 } else if (NUMBER_Check(result)) {
2801 res = NUMBER_AsLong(result);
2802 } else {
2803 PyErr_SetString(PyExc_TypeError,
2804 "DB_dup_compare callback MUST return an int.");
2805 /* we're in a callback within the DB code, we can't raise */
2806 PyErr_Print();
2807 res = _default_cmp(leftKey, rightKey);
2808 }
2809
2810 Py_XDECREF(args);
2811 Py_XDECREF(result);
2812
2813 MYDB_END_BLOCK_THREADS;
2814 }
2815 return res;
2816}
2817
2818static PyObject*
2819DB_set_dup_compare(DBObject* self, PyObject* comparator)
2820{
2821 int err;
2822 PyObject *tuple, *result;
2823
2824 CHECK_DB_NOT_CLOSED(self);
2825
2826 if (!PyCallable_Check(comparator)) {
2827 makeTypeError("Callable", comparator);
2828 return NULL;
2829 }
2830
2831 /*
2832 * Perform a test call of the comparator function with two empty
2833 * string objects here. verify that it returns an int (0).
2834 * err if not.
2835 */
2836 tuple = Py_BuildValue("(ss)", "", "");
2837 result = PyEval_CallObject(comparator, tuple);
2838 Py_DECREF(tuple);
2839 if (result == NULL)
2840 return NULL;
2841 if (!NUMBER_Check(result)) {
2842 Py_DECREF(result);
2843 PyErr_SetString(PyExc_TypeError,
2844 "callback MUST return an int");
2845 return NULL;
2846 } else if (NUMBER_AsLong(result) != 0) {
2847 Py_DECREF(result);
2848 PyErr_SetString(PyExc_TypeError,
2849 "callback failed to return 0 on two empty strings");
2850 return NULL;
2851 }
2852 Py_DECREF(result);
2853
2854 /* We don't accept multiple set_dup_compare operations, in order to
2855 * simplify the code. This would have no real use, as one cannot
2856 * change the function once the db is opened anyway */
2857 if (self->dupCompareCallback != NULL) {
2858 PyErr_SetString(PyExc_RuntimeError, "set_dup_compare() cannot be called more than once");
2859 return NULL;
2860 }
2861
2862 Py_INCREF(comparator);
2863 self->dupCompareCallback = comparator;
2864
2865 /* This is to workaround a problem with un-initialized threads (see
2866 comment in DB_associate) */
2867#ifdef WITH_THREAD
2868 PyEval_InitThreads();
2869#endif
2870
2871 err = self->db->set_dup_compare(self->db, _db_dupCompareCallback);
2872
2873 if (err) {
2874 /* restore the old state in case of error */
2875 Py_DECREF(comparator);
2876 self->dupCompareCallback = NULL;
2877 }
2878
2879 RETURN_IF_ERR();
2880 RETURN_NONE();
2881}
2882
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002883
2884static PyObject*
2885DB_set_cachesize(DBObject* self, PyObject* args)
2886{
2887 int err;
2888 int gbytes = 0, bytes = 0, ncache = 0;
2889
2890 if (!PyArg_ParseTuple(args,"ii|i:set_cachesize",
2891 &gbytes,&bytes,&ncache))
2892 return NULL;
2893 CHECK_DB_NOT_CLOSED(self);
2894
2895 MYDB_BEGIN_ALLOW_THREADS;
2896 err = self->db->set_cachesize(self->db, gbytes, bytes, ncache);
2897 MYDB_END_ALLOW_THREADS;
2898 RETURN_IF_ERR();
2899 RETURN_NONE();
2900}
2901
Jesus Cea6557aac2010-03-22 14:22:26 +00002902static PyObject*
2903DB_get_cachesize(DBObject* self)
2904{
2905 int err;
2906 u_int32_t gbytes, bytes;
2907 int ncache;
2908
2909 CHECK_DB_NOT_CLOSED(self);
2910
2911 MYDB_BEGIN_ALLOW_THREADS;
2912 err = self->db->get_cachesize(self->db, &gbytes, &bytes, &ncache);
2913 MYDB_END_ALLOW_THREADS;
2914
2915 RETURN_IF_ERR();
2916
2917 return Py_BuildValue("(iii)", gbytes, bytes, ncache);
2918}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002919
2920static PyObject*
2921DB_set_flags(DBObject* self, PyObject* args)
2922{
2923 int err, flags;
2924
2925 if (!PyArg_ParseTuple(args,"i:set_flags", &flags))
2926 return NULL;
2927 CHECK_DB_NOT_CLOSED(self);
2928
2929 MYDB_BEGIN_ALLOW_THREADS;
2930 err = self->db->set_flags(self->db, flags);
2931 MYDB_END_ALLOW_THREADS;
2932 RETURN_IF_ERR();
2933
2934 self->setflags |= flags;
2935 RETURN_NONE();
2936}
2937
Jesus Cea6557aac2010-03-22 14:22:26 +00002938static PyObject*
2939DB_get_flags(DBObject* self)
2940{
2941 int err;
2942 u_int32_t flags;
2943
2944 CHECK_DB_NOT_CLOSED(self);
2945
2946 MYDB_BEGIN_ALLOW_THREADS;
2947 err = self->db->get_flags(self->db, &flags);
2948 MYDB_END_ALLOW_THREADS;
2949 RETURN_IF_ERR();
2950 return NUMBER_FromLong(flags);
2951}
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07002952
2953static PyObject*
2954DB_get_transactional(DBObject* self)
2955{
2956 int err;
2957
2958 CHECK_DB_NOT_CLOSED(self);
2959
2960 MYDB_BEGIN_ALLOW_THREADS;
2961 err = self->db->get_transactional(self->db);
2962 MYDB_END_ALLOW_THREADS;
2963
2964 if(err == 0) {
2965 Py_INCREF(Py_False);
2966 return Py_False;
2967 } else if(err == 1) {
2968 Py_INCREF(Py_True);
2969 return Py_True;
2970 }
2971
2972 /*
2973 ** If we reach there, there was an error. The
2974 ** "return" should be unreachable.
2975 */
2976 RETURN_IF_ERR();
2977 assert(0); /* This code SHOULD be unreachable */
2978 return NULL;
2979}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002980
2981static PyObject*
2982DB_set_h_ffactor(DBObject* self, PyObject* args)
2983{
2984 int err, ffactor;
2985
2986 if (!PyArg_ParseTuple(args,"i:set_h_ffactor", &ffactor))
2987 return NULL;
2988 CHECK_DB_NOT_CLOSED(self);
2989
2990 MYDB_BEGIN_ALLOW_THREADS;
2991 err = self->db->set_h_ffactor(self->db, ffactor);
2992 MYDB_END_ALLOW_THREADS;
2993 RETURN_IF_ERR();
2994 RETURN_NONE();
2995}
2996
Jesus Cea6557aac2010-03-22 14:22:26 +00002997static PyObject*
2998DB_get_h_ffactor(DBObject* self)
2999{
3000 int err;
3001 u_int32_t ffactor;
3002
3003 CHECK_DB_NOT_CLOSED(self);
3004
3005 MYDB_BEGIN_ALLOW_THREADS;
3006 err = self->db->get_h_ffactor(self->db, &ffactor);
3007 MYDB_END_ALLOW_THREADS;
3008 RETURN_IF_ERR();
3009 return NUMBER_FromLong(ffactor);
3010}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003011
3012static PyObject*
3013DB_set_h_nelem(DBObject* self, PyObject* args)
3014{
3015 int err, nelem;
3016
3017 if (!PyArg_ParseTuple(args,"i:set_h_nelem", &nelem))
3018 return NULL;
3019 CHECK_DB_NOT_CLOSED(self);
3020
3021 MYDB_BEGIN_ALLOW_THREADS;
3022 err = self->db->set_h_nelem(self->db, nelem);
3023 MYDB_END_ALLOW_THREADS;
3024 RETURN_IF_ERR();
3025 RETURN_NONE();
3026}
3027
Jesus Cea6557aac2010-03-22 14:22:26 +00003028static PyObject*
3029DB_get_h_nelem(DBObject* self)
3030{
3031 int err;
3032 u_int32_t nelem;
3033
3034 CHECK_DB_NOT_CLOSED(self);
3035
3036 MYDB_BEGIN_ALLOW_THREADS;
3037 err = self->db->get_h_nelem(self->db, &nelem);
3038 MYDB_END_ALLOW_THREADS;
3039 RETURN_IF_ERR();
3040 return NUMBER_FromLong(nelem);
3041}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003042
3043static PyObject*
3044DB_set_lorder(DBObject* self, PyObject* args)
3045{
3046 int err, lorder;
3047
3048 if (!PyArg_ParseTuple(args,"i:set_lorder", &lorder))
3049 return NULL;
3050 CHECK_DB_NOT_CLOSED(self);
3051
3052 MYDB_BEGIN_ALLOW_THREADS;
3053 err = self->db->set_lorder(self->db, lorder);
3054 MYDB_END_ALLOW_THREADS;
3055 RETURN_IF_ERR();
3056 RETURN_NONE();
3057}
3058
Jesus Cea6557aac2010-03-22 14:22:26 +00003059static PyObject*
3060DB_get_lorder(DBObject* self)
3061{
3062 int err;
3063 int lorder;
3064
3065 CHECK_DB_NOT_CLOSED(self);
3066
3067 MYDB_BEGIN_ALLOW_THREADS;
3068 err = self->db->get_lorder(self->db, &lorder);
3069 MYDB_END_ALLOW_THREADS;
3070 RETURN_IF_ERR();
3071 return NUMBER_FromLong(lorder);
3072}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003073
3074static PyObject*
3075DB_set_pagesize(DBObject* self, PyObject* args)
3076{
3077 int err, pagesize;
3078
3079 if (!PyArg_ParseTuple(args,"i:set_pagesize", &pagesize))
3080 return NULL;
3081 CHECK_DB_NOT_CLOSED(self);
3082
3083 MYDB_BEGIN_ALLOW_THREADS;
3084 err = self->db->set_pagesize(self->db, pagesize);
3085 MYDB_END_ALLOW_THREADS;
3086 RETURN_IF_ERR();
3087 RETURN_NONE();
3088}
3089
Jesus Cea6557aac2010-03-22 14:22:26 +00003090static PyObject*
3091DB_get_pagesize(DBObject* self)
3092{
3093 int err;
3094 u_int32_t pagesize;
3095
3096 CHECK_DB_NOT_CLOSED(self);
3097
3098 MYDB_BEGIN_ALLOW_THREADS;
3099 err = self->db->get_pagesize(self->db, &pagesize);
3100 MYDB_END_ALLOW_THREADS;
3101 RETURN_IF_ERR();
3102 return NUMBER_FromLong(pagesize);
3103}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003104
3105static PyObject*
3106DB_set_re_delim(DBObject* self, PyObject* args)
3107{
3108 int err;
3109 char delim;
3110
3111 if (!PyArg_ParseTuple(args,"b:set_re_delim", &delim)) {
3112 PyErr_Clear();
3113 if (!PyArg_ParseTuple(args,"c:set_re_delim", &delim))
3114 return NULL;
3115 }
3116
3117 CHECK_DB_NOT_CLOSED(self);
3118
3119 MYDB_BEGIN_ALLOW_THREADS;
3120 err = self->db->set_re_delim(self->db, delim);
3121 MYDB_END_ALLOW_THREADS;
3122 RETURN_IF_ERR();
3123 RETURN_NONE();
3124}
3125
Jesus Cea6557aac2010-03-22 14:22:26 +00003126static PyObject*
3127DB_get_re_delim(DBObject* self)
3128{
3129 int err, re_delim;
3130
3131 CHECK_DB_NOT_CLOSED(self);
3132
3133 MYDB_BEGIN_ALLOW_THREADS;
3134 err = self->db->get_re_delim(self->db, &re_delim);
3135 MYDB_END_ALLOW_THREADS;
3136 RETURN_IF_ERR();
3137 return NUMBER_FromLong(re_delim);
3138}
Jesus Cea6557aac2010-03-22 14:22:26 +00003139
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003140static PyObject*
3141DB_set_re_len(DBObject* self, PyObject* args)
3142{
3143 int err, len;
3144
3145 if (!PyArg_ParseTuple(args,"i:set_re_len", &len))
3146 return NULL;
3147 CHECK_DB_NOT_CLOSED(self);
3148
3149 MYDB_BEGIN_ALLOW_THREADS;
3150 err = self->db->set_re_len(self->db, len);
3151 MYDB_END_ALLOW_THREADS;
3152 RETURN_IF_ERR();
3153 RETURN_NONE();
3154}
3155
Jesus Cea6557aac2010-03-22 14:22:26 +00003156static PyObject*
3157DB_get_re_len(DBObject* self)
3158{
3159 int err;
3160 u_int32_t re_len;
3161
3162 CHECK_DB_NOT_CLOSED(self);
3163
3164 MYDB_BEGIN_ALLOW_THREADS;
3165 err = self->db->get_re_len(self->db, &re_len);
3166 MYDB_END_ALLOW_THREADS;
3167 RETURN_IF_ERR();
3168 return NUMBER_FromLong(re_len);
3169}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003170
3171static PyObject*
3172DB_set_re_pad(DBObject* self, PyObject* args)
3173{
3174 int err;
3175 char pad;
3176
3177 if (!PyArg_ParseTuple(args,"b:set_re_pad", &pad)) {
3178 PyErr_Clear();
3179 if (!PyArg_ParseTuple(args,"c:set_re_pad", &pad))
3180 return NULL;
3181 }
3182 CHECK_DB_NOT_CLOSED(self);
3183
3184 MYDB_BEGIN_ALLOW_THREADS;
3185 err = self->db->set_re_pad(self->db, pad);
3186 MYDB_END_ALLOW_THREADS;
3187 RETURN_IF_ERR();
3188 RETURN_NONE();
3189}
3190
Jesus Cea6557aac2010-03-22 14:22:26 +00003191static PyObject*
3192DB_get_re_pad(DBObject* self)
3193{
3194 int err, re_pad;
3195
3196 CHECK_DB_NOT_CLOSED(self);
3197
3198 MYDB_BEGIN_ALLOW_THREADS;
3199 err = self->db->get_re_pad(self->db, &re_pad);
3200 MYDB_END_ALLOW_THREADS;
3201 RETURN_IF_ERR();
3202 return NUMBER_FromLong(re_pad);
3203}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003204
3205static PyObject*
3206DB_set_re_source(DBObject* self, PyObject* args)
3207{
3208 int err;
Jesus Cea6557aac2010-03-22 14:22:26 +00003209 char *source;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003210
Jesus Cea6557aac2010-03-22 14:22:26 +00003211 if (!PyArg_ParseTuple(args,"s:set_re_source", &source))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003212 return NULL;
3213 CHECK_DB_NOT_CLOSED(self);
3214
3215 MYDB_BEGIN_ALLOW_THREADS;
Jesus Cea6557aac2010-03-22 14:22:26 +00003216 err = self->db->set_re_source(self->db, source);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003217 MYDB_END_ALLOW_THREADS;
3218 RETURN_IF_ERR();
3219 RETURN_NONE();
3220}
3221
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003222static PyObject*
Jesus Cea6557aac2010-03-22 14:22:26 +00003223DB_get_re_source(DBObject* self)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003224{
3225 int err;
Jesus Cea6557aac2010-03-22 14:22:26 +00003226 const char *source;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003227
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003228 CHECK_DB_NOT_CLOSED(self);
3229
3230 MYDB_BEGIN_ALLOW_THREADS;
Jesus Cea6557aac2010-03-22 14:22:26 +00003231 err = self->db->get_re_source(self->db, &source);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003232 MYDB_END_ALLOW_THREADS;
3233 RETURN_IF_ERR();
Jesus Cea6557aac2010-03-22 14:22:26 +00003234 return PyBytes_FromString(source);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003235}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003236
3237static PyObject*
Gregory P. Smith8b7e9172004-12-13 09:51:23 +00003238DB_stat(DBObject* self, PyObject* args, PyObject* kwargs)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003239{
3240 int err, flags = 0, type;
3241 void* sp;
3242 PyObject* d;
Gregory P. Smith8b7e9172004-12-13 09:51:23 +00003243 PyObject* txnobj = NULL;
3244 DB_TXN *txn = NULL;
Gregory P. Smith2fa06792006-09-19 17:35:04 +00003245 static char* kwnames[] = { "flags", "txn", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003246
Gregory P. Smith8b7e9172004-12-13 09:51:23 +00003247 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|iO:stat", kwnames,
3248 &flags, &txnobj))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003249 return NULL;
Gregory P. Smith8b7e9172004-12-13 09:51:23 +00003250 if (!checkTxnObj(txnobj, &txn))
3251 return NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003252 CHECK_DB_NOT_CLOSED(self);
3253
3254 MYDB_BEGIN_ALLOW_THREADS;
Gregory P. Smith8b7e9172004-12-13 09:51:23 +00003255 err = self->db->stat(self->db, txn, &sp, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003256 MYDB_END_ALLOW_THREADS;
3257 RETURN_IF_ERR();
3258
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003259 /* Turn the stat structure into a dictionary */
3260 type = _DB_get_type(self);
3261 if ((type == -1) || ((d = PyDict_New()) == NULL)) {
3262 free(sp);
3263 return NULL;
3264 }
3265
3266#define MAKE_HASH_ENTRY(name) _addIntToDict(d, #name, ((DB_HASH_STAT*)sp)->hash_##name)
3267#define MAKE_BT_ENTRY(name) _addIntToDict(d, #name, ((DB_BTREE_STAT*)sp)->bt_##name)
3268#define MAKE_QUEUE_ENTRY(name) _addIntToDict(d, #name, ((DB_QUEUE_STAT*)sp)->qs_##name)
3269
3270 switch (type) {
3271 case DB_HASH:
3272 MAKE_HASH_ENTRY(magic);
3273 MAKE_HASH_ENTRY(version);
3274 MAKE_HASH_ENTRY(nkeys);
3275 MAKE_HASH_ENTRY(ndata);
Jesus Ceaef9764f2008-05-13 18:45:46 +00003276#if (DBVER >= 46)
3277 MAKE_HASH_ENTRY(pagecnt);
3278#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003279 MAKE_HASH_ENTRY(pagesize);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003280 MAKE_HASH_ENTRY(ffactor);
3281 MAKE_HASH_ENTRY(buckets);
3282 MAKE_HASH_ENTRY(free);
3283 MAKE_HASH_ENTRY(bfree);
3284 MAKE_HASH_ENTRY(bigpages);
3285 MAKE_HASH_ENTRY(big_bfree);
3286 MAKE_HASH_ENTRY(overflows);
3287 MAKE_HASH_ENTRY(ovfl_free);
3288 MAKE_HASH_ENTRY(dup);
3289 MAKE_HASH_ENTRY(dup_free);
3290 break;
3291
3292 case DB_BTREE:
3293 case DB_RECNO:
3294 MAKE_BT_ENTRY(magic);
3295 MAKE_BT_ENTRY(version);
3296 MAKE_BT_ENTRY(nkeys);
3297 MAKE_BT_ENTRY(ndata);
Jesus Ceaef9764f2008-05-13 18:45:46 +00003298#if (DBVER >= 46)
3299 MAKE_BT_ENTRY(pagecnt);
3300#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003301 MAKE_BT_ENTRY(pagesize);
3302 MAKE_BT_ENTRY(minkey);
3303 MAKE_BT_ENTRY(re_len);
3304 MAKE_BT_ENTRY(re_pad);
3305 MAKE_BT_ENTRY(levels);
3306 MAKE_BT_ENTRY(int_pg);
3307 MAKE_BT_ENTRY(leaf_pg);
3308 MAKE_BT_ENTRY(dup_pg);
3309 MAKE_BT_ENTRY(over_pg);
Jesus Ceaef9764f2008-05-13 18:45:46 +00003310 MAKE_BT_ENTRY(empty_pg);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003311 MAKE_BT_ENTRY(free);
3312 MAKE_BT_ENTRY(int_pgfree);
3313 MAKE_BT_ENTRY(leaf_pgfree);
3314 MAKE_BT_ENTRY(dup_pgfree);
3315 MAKE_BT_ENTRY(over_pgfree);
3316 break;
3317
3318 case DB_QUEUE:
3319 MAKE_QUEUE_ENTRY(magic);
3320 MAKE_QUEUE_ENTRY(version);
3321 MAKE_QUEUE_ENTRY(nkeys);
3322 MAKE_QUEUE_ENTRY(ndata);
3323 MAKE_QUEUE_ENTRY(pagesize);
Jesus Ceaef9764f2008-05-13 18:45:46 +00003324 MAKE_QUEUE_ENTRY(extentsize);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003325 MAKE_QUEUE_ENTRY(pages);
3326 MAKE_QUEUE_ENTRY(re_len);
3327 MAKE_QUEUE_ENTRY(re_pad);
3328 MAKE_QUEUE_ENTRY(pgfree);
3329#if (DBVER == 31)
3330 MAKE_QUEUE_ENTRY(start);
3331#endif
3332 MAKE_QUEUE_ENTRY(first_recno);
3333 MAKE_QUEUE_ENTRY(cur_recno);
3334 break;
3335
3336 default:
3337 PyErr_SetString(PyExc_TypeError, "Unknown DB type, unable to stat");
3338 Py_DECREF(d);
3339 d = NULL;
3340 }
3341
3342#undef MAKE_HASH_ENTRY
3343#undef MAKE_BT_ENTRY
3344#undef MAKE_QUEUE_ENTRY
3345
3346 free(sp);
3347 return d;
3348}
3349
Jesus Cea6557aac2010-03-22 14:22:26 +00003350static PyObject*
3351DB_stat_print(DBObject* self, PyObject* args, PyObject *kwargs)
3352{
3353 int err;
3354 int flags=0;
3355 static char* kwnames[] = { "flags", NULL };
3356
3357 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:stat_print",
3358 kwnames, &flags))
3359 {
3360 return NULL;
3361 }
3362 CHECK_DB_NOT_CLOSED(self);
3363 MYDB_BEGIN_ALLOW_THREADS;
3364 err = self->db->stat_print(self->db, flags);
3365 MYDB_END_ALLOW_THREADS;
3366 RETURN_IF_ERR();
3367 RETURN_NONE();
3368}
Jesus Cea6557aac2010-03-22 14:22:26 +00003369
3370
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003371static PyObject*
3372DB_sync(DBObject* self, PyObject* args)
3373{
3374 int err;
3375 int flags = 0;
3376
3377 if (!PyArg_ParseTuple(args,"|i:sync", &flags ))
3378 return NULL;
3379 CHECK_DB_NOT_CLOSED(self);
3380
3381 MYDB_BEGIN_ALLOW_THREADS;
3382 err = self->db->sync(self->db, flags);
3383 MYDB_END_ALLOW_THREADS;
3384 RETURN_IF_ERR();
3385 RETURN_NONE();
3386}
3387
3388
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003389static PyObject*
3390DB_truncate(DBObject* self, PyObject* args, PyObject* kwargs)
3391{
3392 int err, flags=0;
3393 u_int32_t count=0;
3394 PyObject* txnobj = NULL;
3395 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003396 static char* kwnames[] = { "txn", "flags", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003397
3398 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Oi:cursor", kwnames,
3399 &txnobj, &flags))
3400 return NULL;
3401 CHECK_DB_NOT_CLOSED(self);
3402 if (!checkTxnObj(txnobj, &txn))
3403 return NULL;
3404
3405 MYDB_BEGIN_ALLOW_THREADS;
3406 err = self->db->truncate(self->db, txn, &count, flags);
3407 MYDB_END_ALLOW_THREADS;
3408 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00003409 return NUMBER_FromLong(count);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003410}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003411
3412
3413static PyObject*
3414DB_upgrade(DBObject* self, PyObject* args)
3415{
3416 int err, flags=0;
3417 char *filename;
3418
3419 if (!PyArg_ParseTuple(args,"s|i:upgrade", &filename, &flags))
3420 return NULL;
3421 CHECK_DB_NOT_CLOSED(self);
3422
3423 MYDB_BEGIN_ALLOW_THREADS;
3424 err = self->db->upgrade(self->db, filename, flags);
3425 MYDB_END_ALLOW_THREADS;
3426 RETURN_IF_ERR();
3427 RETURN_NONE();
3428}
3429
3430
3431static PyObject*
3432DB_verify(DBObject* self, PyObject* args, PyObject* kwargs)
3433{
3434 int err, flags=0;
3435 char* fileName;
3436 char* dbName=NULL;
3437 char* outFileName=NULL;
3438 FILE* outFile=NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003439 static char* kwnames[] = { "filename", "dbname", "outfile", "flags",
Jeremy Hyltonaf68c872005-12-10 18:50:16 +00003440 NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003441
3442 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|zzi:verify", kwnames,
3443 &fileName, &dbName, &outFileName, &flags))
3444 return NULL;
3445
3446 CHECK_DB_NOT_CLOSED(self);
3447 if (outFileName)
3448 outFile = fopen(outFileName, "w");
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003449 /* XXX(nnorwitz): it should probably be an exception if outFile
3450 can't be opened. */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003451
Jesus Ceaef9764f2008-05-13 18:45:46 +00003452 { /* DB.verify acts as a DB handle destructor (like close) */
3453 PyObject *error;
3454
Jesus Cea5cd5f122008-09-23 18:54:08 +00003455 error=DB_close_internal(self, 0, 1);
Jesus Cea6557aac2010-03-22 14:22:26 +00003456 if (error) {
Serhiy Storchakaaffac002015-07-24 08:05:45 +03003457 if (outFile)
3458 fclose(outFile);
3459 return error;
Jesus Ceaef9764f2008-05-13 18:45:46 +00003460 }
Serhiy Storchakaaffac002015-07-24 08:05:45 +03003461 }
Gregory P. Smith41631e82003-09-21 00:08:14 +00003462
Jesus Cea5cd5f122008-09-23 18:54:08 +00003463 MYDB_BEGIN_ALLOW_THREADS;
3464 err = self->db->verify(self->db, fileName, dbName, outFile, flags);
3465 MYDB_END_ALLOW_THREADS;
3466
3467 self->db = NULL; /* Implicit close; related objects already released */
3468
3469 if (outFile)
3470 fclose(outFile);
3471
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003472 RETURN_IF_ERR();
3473 RETURN_NONE();
3474}
3475
3476
3477static PyObject*
3478DB_set_get_returns_none(DBObject* self, PyObject* args)
3479{
3480 int flags=0;
Gregory P. Smith455d46f2003-07-09 04:45:59 +00003481 int oldValue=0;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003482
3483 if (!PyArg_ParseTuple(args,"i:set_get_returns_none", &flags))
3484 return NULL;
3485 CHECK_DB_NOT_CLOSED(self);
3486
Gregory P. Smith455d46f2003-07-09 04:45:59 +00003487 if (self->moduleFlags.getReturnsNone)
3488 ++oldValue;
3489 if (self->moduleFlags.cursorSetReturnsNone)
3490 ++oldValue;
3491 self->moduleFlags.getReturnsNone = (flags >= 1);
3492 self->moduleFlags.cursorSetReturnsNone = (flags >= 2);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00003493 return NUMBER_FromLong(oldValue);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003494}
3495
Barry Warsaw9a0d7792002-12-30 20:53:52 +00003496static PyObject*
3497DB_set_encrypt(DBObject* self, PyObject* args, PyObject* kwargs)
3498{
3499 int err;
3500 u_int32_t flags=0;
3501 char *passwd = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003502 static char* kwnames[] = { "passwd", "flags", NULL };
Barry Warsaw9a0d7792002-12-30 20:53:52 +00003503
3504 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|i:set_encrypt", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003505 &passwd, &flags)) {
3506 return NULL;
Barry Warsaw9a0d7792002-12-30 20:53:52 +00003507 }
3508
3509 MYDB_BEGIN_ALLOW_THREADS;
3510 err = self->db->set_encrypt(self->db, passwd, flags);
3511 MYDB_END_ALLOW_THREADS;
3512
3513 RETURN_IF_ERR();
3514 RETURN_NONE();
3515}
Jesus Cea6557aac2010-03-22 14:22:26 +00003516
Jesus Cea6557aac2010-03-22 14:22:26 +00003517static PyObject*
3518DB_get_encrypt_flags(DBObject* self)
3519{
3520 int err;
3521 u_int32_t flags;
3522
3523 MYDB_BEGIN_ALLOW_THREADS;
3524 err = self->db->get_encrypt_flags(self->db, &flags);
3525 MYDB_END_ALLOW_THREADS;
3526
3527 RETURN_IF_ERR();
3528
3529 return NUMBER_FromLong(flags);
3530}
Jesus Cea6557aac2010-03-22 14:22:26 +00003531
Barry Warsaw9a0d7792002-12-30 20:53:52 +00003532
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003533
3534/*-------------------------------------------------------------- */
3535/* Mapping and Dictionary-like access routines */
3536
Martin v. Löwis70ee3cc2006-06-12 04:26:31 +00003537Py_ssize_t DB_length(PyObject* _self)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003538{
3539 int err;
Gregory P. Smith3c228b12006-06-05 23:59:37 +00003540 Py_ssize_t size = 0;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003541 void* sp;
Martin v. Löwis70ee3cc2006-06-12 04:26:31 +00003542 DBObject* self = (DBObject*)_self;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003543
3544 if (self->db == NULL) {
Thomas Woutersb3153832006-03-08 01:47:19 +00003545 PyObject *t = Py_BuildValue("(is)", 0, "DB object has been closed");
Jesus Ceac5a11fa2008-07-23 11:38:42 +00003546 if (t) {
3547 PyErr_SetObject(DBError, t);
3548 Py_DECREF(t);
3549 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003550 return -1;
3551 }
3552
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003553 MYDB_BEGIN_ALLOW_THREADS;
Jesus Cea6557aac2010-03-22 14:22:26 +00003554 err = self->db->stat(self->db, /*txnid*/ NULL, &sp, 0);
Jesus Cea6557aac2010-03-22 14:22:26 +00003555 MYDB_END_ALLOW_THREADS;
Gregory P. Smith3c228b12006-06-05 23:59:37 +00003556
3557 /* All the stat structures have matching fields upto the ndata field,
3558 so we can use any of them for the type cast */
3559 size = ((DB_BTREE_STAT*)sp)->bt_ndata;
3560
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003561 if (err)
3562 return -1;
3563
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003564 free(sp);
3565 return size;
3566}
3567
3568
3569PyObject* DB_subscript(DBObject* self, PyObject* keyobj)
3570{
3571 int err;
3572 PyObject* retval;
3573 DBT key;
3574 DBT data;
3575
3576 CHECK_DB_NOT_CLOSED(self);
3577 if (!make_key_dbt(self, keyobj, &key, NULL))
3578 return NULL;
3579
3580 CLEAR_DBT(data);
3581 if (CHECK_DBFLAG(self, DB_THREAD)) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00003582 /* Tell Berkeley DB to malloc the return value (thread safe) */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003583 data.flags = DB_DBT_MALLOC;
3584 }
3585 MYDB_BEGIN_ALLOW_THREADS;
3586 err = self->db->get(self->db, NULL, &key, &data, 0);
3587 MYDB_END_ALLOW_THREADS;
3588 if (err == DB_NOTFOUND || err == DB_KEYEMPTY) {
3589 PyErr_SetObject(PyExc_KeyError, keyobj);
3590 retval = NULL;
3591 }
3592 else if (makeDBError(err)) {
3593 retval = NULL;
3594 }
3595 else {
Jesus Ceaef9764f2008-05-13 18:45:46 +00003596 retval = Build_PyString(data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003597 FREE_DBT(data);
3598 }
3599
3600 FREE_DBT(key);
3601 return retval;
3602}
3603
3604
3605static int
3606DB_ass_sub(DBObject* self, PyObject* keyobj, PyObject* dataobj)
3607{
3608 DBT key, data;
3609 int retval;
3610 int flags = 0;
3611
3612 if (self->db == NULL) {
Thomas Woutersb3153832006-03-08 01:47:19 +00003613 PyObject *t = Py_BuildValue("(is)", 0, "DB object has been closed");
Jesus Ceac5a11fa2008-07-23 11:38:42 +00003614 if (t) {
3615 PyErr_SetObject(DBError, t);
3616 Py_DECREF(t);
3617 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003618 return -1;
3619 }
3620
3621 if (!make_key_dbt(self, keyobj, &key, NULL))
3622 return -1;
3623
3624 if (dataobj != NULL) {
3625 if (!make_dbt(dataobj, &data))
3626 retval = -1;
3627 else {
3628 if (self->setflags & (DB_DUP|DB_DUPSORT))
Barry Warsaw9a0d7792002-12-30 20:53:52 +00003629 /* dictionaries shouldn't have duplicate keys */
3630 flags = DB_NOOVERWRITE;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003631 retval = _DB_put(self, NULL, &key, &data, flags);
3632
3633 if ((retval == -1) && (self->setflags & (DB_DUP|DB_DUPSORT))) {
Barry Warsaw9a0d7792002-12-30 20:53:52 +00003634 /* try deleting any old record that matches and then PUT it
3635 * again... */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003636 _DB_delete(self, NULL, &key, 0);
3637 PyErr_Clear();
3638 retval = _DB_put(self, NULL, &key, &data, flags);
3639 }
3640 }
3641 }
3642 else {
3643 /* dataobj == NULL, so delete the key */
3644 retval = _DB_delete(self, NULL, &key, 0);
3645 }
3646 FREE_DBT(key);
3647 return retval;
3648}
3649
3650
3651static PyObject*
Jesus Cea6557aac2010-03-22 14:22:26 +00003652_DB_has_key(DBObject* self, PyObject* keyobj, PyObject* txnobj)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003653{
3654 int err;
Jesus Cea6557aac2010-03-22 14:22:26 +00003655 DBT key;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003656 DB_TXN *txn = NULL;
Jesus Cea4907d272008-08-31 14:00:51 +00003657
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003658 CHECK_DB_NOT_CLOSED(self);
3659 if (!make_key_dbt(self, keyobj, &key, NULL))
3660 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00003661 if (!checkTxnObj(txnobj, &txn)) {
3662 FREE_DBT(key);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003663 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00003664 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003665
Jesus Cea6557aac2010-03-22 14:22:26 +00003666#if (DBVER < 46)
Gregory P. Smith8b7e9172004-12-13 09:51:23 +00003667 /* This causes DB_BUFFER_SMALL to be returned when the db has the key because
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003668 it has a record but can't allocate a buffer for the data. This saves
3669 having to deal with data we won't be using.
3670 */
Jesus Cea6557aac2010-03-22 14:22:26 +00003671 {
3672 DBT data ;
3673 CLEAR_DBT(data);
3674 data.flags = DB_DBT_USERMEM;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003675
Jesus Cea6557aac2010-03-22 14:22:26 +00003676 MYDB_BEGIN_ALLOW_THREADS;
3677 err = self->db->get(self->db, txn, &key, &data, 0);
3678 MYDB_END_ALLOW_THREADS;
3679 }
3680#else
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003681 MYDB_BEGIN_ALLOW_THREADS;
Jesus Cea6557aac2010-03-22 14:22:26 +00003682 err = self->db->exists(self->db, txn, &key, 0);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003683 MYDB_END_ALLOW_THREADS;
Jesus Cea6557aac2010-03-22 14:22:26 +00003684#endif
3685
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003686 FREE_DBT(key);
Gregory P. Smithe9477062005-06-04 06:46:59 +00003687
Jesus Cea6557aac2010-03-22 14:22:26 +00003688 /*
3689 ** DB_BUFFER_SMALL is only used if we use "get".
3690 ** We can drop it when we only use "exists",
3691 ** when we drop suport for Berkeley DB < 4.6.
3692 */
Gregory P. Smithe9477062005-06-04 06:46:59 +00003693 if (err == DB_BUFFER_SMALL || err == 0) {
Jesus Cea6557aac2010-03-22 14:22:26 +00003694 Py_INCREF(Py_True);
3695 return Py_True;
Gregory P. Smithe9477062005-06-04 06:46:59 +00003696 } else if (err == DB_NOTFOUND || err == DB_KEYEMPTY) {
Jesus Cea6557aac2010-03-22 14:22:26 +00003697 Py_INCREF(Py_False);
3698 return Py_False;
Gregory P. Smithe9477062005-06-04 06:46:59 +00003699 }
3700
3701 makeDBError(err);
3702 return NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003703}
3704
Jesus Cea6557aac2010-03-22 14:22:26 +00003705static PyObject*
3706DB_has_key(DBObject* self, PyObject* args, PyObject* kwargs)
3707{
3708 PyObject* keyobj;
3709 PyObject* txnobj = NULL;
3710 static char* kwnames[] = {"key","txn", NULL};
3711
3712 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O:has_key", kwnames,
3713 &keyobj, &txnobj))
3714 return NULL;
3715
3716 return _DB_has_key(self, keyobj, txnobj);
3717}
3718
3719
3720static int DB_contains(DBObject* self, PyObject* keyobj)
3721{
3722 PyObject* result;
3723 int result2 = 0;
3724
3725 result = _DB_has_key(self, keyobj, NULL) ;
3726 if (result == NULL) {
3727 return -1; /* Propague exception */
3728 }
3729 if (result != Py_False) {
3730 result2 = 1;
3731 }
3732
3733 Py_DECREF(result);
3734 return result2;
3735}
3736
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003737
3738#define _KEYS_LIST 1
3739#define _VALUES_LIST 2
3740#define _ITEMS_LIST 3
3741
3742static PyObject*
3743_DB_make_list(DBObject* self, DB_TXN* txn, int type)
3744{
3745 int err, dbtype;
3746 DBT key;
3747 DBT data;
3748 DBC *cursor;
3749 PyObject* list;
3750 PyObject* item = NULL;
3751
3752 CHECK_DB_NOT_CLOSED(self);
3753 CLEAR_DBT(key);
3754 CLEAR_DBT(data);
3755
3756 dbtype = _DB_get_type(self);
3757 if (dbtype == -1)
3758 return NULL;
3759
3760 list = PyList_New(0);
Thomas Woutersb3153832006-03-08 01:47:19 +00003761 if (list == NULL)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003762 return NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003763
3764 /* get a cursor */
3765 MYDB_BEGIN_ALLOW_THREADS;
Gregory P. Smith442c9fc2004-09-04 01:36:59 +00003766 err = self->db->cursor(self->db, txn, &cursor, 0);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003767 MYDB_END_ALLOW_THREADS;
Thomas Woutersb3153832006-03-08 01:47:19 +00003768 if (makeDBError(err)) {
3769 Py_DECREF(list);
3770 return NULL;
3771 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003772
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003773 while (1) { /* use the cursor to traverse the DB, collecting items */
3774 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00003775 err = _DBC_get(cursor, &key, &data, DB_NEXT);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003776 MYDB_END_ALLOW_THREADS;
3777
3778 if (err) {
3779 /* for any error, break out of the loop */
3780 break;
3781 }
3782
3783 switch (type) {
3784 case _KEYS_LIST:
3785 switch(dbtype) {
3786 case DB_BTREE:
3787 case DB_HASH:
3788 default:
Jesus Ceaef9764f2008-05-13 18:45:46 +00003789 item = Build_PyString(key.data, key.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003790 break;
3791 case DB_RECNO:
3792 case DB_QUEUE:
Jesus Ceac5a11fa2008-07-23 11:38:42 +00003793 item = NUMBER_FromLong(*((db_recno_t*)key.data));
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003794 break;
3795 }
3796 break;
3797
3798 case _VALUES_LIST:
Jesus Ceaef9764f2008-05-13 18:45:46 +00003799 item = Build_PyString(data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003800 break;
3801
3802 case _ITEMS_LIST:
3803 switch(dbtype) {
3804 case DB_BTREE:
3805 case DB_HASH:
3806 default:
Jesus Ceaef9764f2008-05-13 18:45:46 +00003807 item = BuildValue_SS(key.data, key.size, data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003808 break;
3809 case DB_RECNO:
3810 case DB_QUEUE:
Jesus Ceaef9764f2008-05-13 18:45:46 +00003811 item = BuildValue_IS(*((db_recno_t*)key.data), data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003812 break;
3813 }
3814 break;
Thomas Woutersb3153832006-03-08 01:47:19 +00003815 default:
3816 PyErr_Format(PyExc_ValueError, "Unknown key type 0x%x", type);
3817 item = NULL;
3818 break;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003819 }
3820 if (item == NULL) {
3821 Py_DECREF(list);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003822 list = NULL;
3823 goto done;
3824 }
Jesus Ceac5a11fa2008-07-23 11:38:42 +00003825 if (PyList_Append(list, item)) {
3826 Py_DECREF(list);
3827 Py_DECREF(item);
3828 list = NULL;
3829 goto done;
3830 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003831 Py_DECREF(item);
3832 }
3833
Gregory P. Smithe9477062005-06-04 06:46:59 +00003834 /* DB_NOTFOUND || DB_KEYEMPTY is okay, it means we got to the end */
3835 if (err != DB_NOTFOUND && err != DB_KEYEMPTY && makeDBError(err)) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003836 Py_DECREF(list);
3837 list = NULL;
3838 }
3839
3840 done:
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003841 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00003842 _DBC_close(cursor);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003843 MYDB_END_ALLOW_THREADS;
3844 return list;
3845}
3846
3847
3848static PyObject*
3849DB_keys(DBObject* self, PyObject* args)
3850{
3851 PyObject* txnobj = NULL;
3852 DB_TXN *txn = NULL;
3853
Georg Brandl96a8c392006-05-29 21:04:52 +00003854 if (!PyArg_UnpackTuple(args, "keys", 0, 1, &txnobj))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003855 return NULL;
3856 if (!checkTxnObj(txnobj, &txn))
3857 return NULL;
3858 return _DB_make_list(self, txn, _KEYS_LIST);
3859}
3860
3861
3862static PyObject*
3863DB_items(DBObject* self, PyObject* args)
3864{
3865 PyObject* txnobj = NULL;
3866 DB_TXN *txn = NULL;
3867
Georg Brandl96a8c392006-05-29 21:04:52 +00003868 if (!PyArg_UnpackTuple(args, "items", 0, 1, &txnobj))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003869 return NULL;
3870 if (!checkTxnObj(txnobj, &txn))
3871 return NULL;
3872 return _DB_make_list(self, txn, _ITEMS_LIST);
3873}
3874
3875
3876static PyObject*
3877DB_values(DBObject* self, PyObject* args)
3878{
3879 PyObject* txnobj = NULL;
3880 DB_TXN *txn = NULL;
3881
Georg Brandl96a8c392006-05-29 21:04:52 +00003882 if (!PyArg_UnpackTuple(args, "values", 0, 1, &txnobj))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003883 return NULL;
3884 if (!checkTxnObj(txnobj, &txn))
3885 return NULL;
3886 return _DB_make_list(self, txn, _VALUES_LIST);
3887}
3888
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003889/* --------------------------------------------------------------------- */
Jesus Cea6557aac2010-03-22 14:22:26 +00003890/* DBLogCursor methods */
3891
3892
3893static PyObject*
3894DBLogCursor_close_internal(DBLogCursorObject* self)
3895{
3896 int err = 0;
3897
3898 if (self->logc != NULL) {
3899 EXTRACT_FROM_DOUBLE_LINKED_LIST(self);
3900
3901 MYDB_BEGIN_ALLOW_THREADS;
3902 err = self->logc->close(self->logc, 0);
3903 MYDB_END_ALLOW_THREADS;
3904 self->logc = NULL;
3905 }
3906 RETURN_IF_ERR();
3907 RETURN_NONE();
3908}
3909
3910static PyObject*
3911DBLogCursor_close(DBLogCursorObject* self)
3912{
3913 return DBLogCursor_close_internal(self);
3914}
3915
3916
3917static PyObject*
3918_DBLogCursor_get(DBLogCursorObject* self, int flag, DB_LSN *lsn2)
3919{
3920 int err;
3921 DBT data;
3922 DB_LSN lsn = {0, 0};
3923 PyObject *dummy, *retval;
3924
3925 CLEAR_DBT(data);
3926 data.flags = DB_DBT_MALLOC; /* Berkeley DB must do the malloc */
3927
3928 CHECK_LOGCURSOR_NOT_CLOSED(self);
3929
3930 if (lsn2)
3931 lsn = *lsn2;
3932
3933 MYDB_BEGIN_ALLOW_THREADS;
3934 err = self->logc->get(self->logc, &lsn, &data, flag);
3935 MYDB_END_ALLOW_THREADS;
3936
3937 if (err == DB_NOTFOUND) {
3938 Py_INCREF(Py_None);
3939 retval = Py_None;
3940 }
3941 else if (makeDBError(err)) {
3942 retval = NULL;
3943 }
3944 else {
3945 retval = dummy = BuildValue_S(data.data, data.size);
3946 if (dummy) {
3947 retval = Py_BuildValue("(ii)O", lsn.file, lsn.offset, dummy);
3948 Py_DECREF(dummy);
3949 }
3950 }
3951
3952 FREE_DBT(data);
3953 return retval;
3954}
3955
3956static PyObject*
3957DBLogCursor_current(DBLogCursorObject* self)
3958{
3959 return _DBLogCursor_get(self, DB_CURRENT, NULL);
3960}
3961
3962static PyObject*
3963DBLogCursor_first(DBLogCursorObject* self)
3964{
3965 return _DBLogCursor_get(self, DB_FIRST, NULL);
3966}
3967
3968static PyObject*
3969DBLogCursor_last(DBLogCursorObject* self)
3970{
3971 return _DBLogCursor_get(self, DB_LAST, NULL);
3972}
3973
3974static PyObject*
3975DBLogCursor_next(DBLogCursorObject* self)
3976{
3977 return _DBLogCursor_get(self, DB_NEXT, NULL);
3978}
3979
3980static PyObject*
3981DBLogCursor_prev(DBLogCursorObject* self)
3982{
3983 return _DBLogCursor_get(self, DB_PREV, NULL);
3984}
3985
3986static PyObject*
3987DBLogCursor_set(DBLogCursorObject* self, PyObject* args)
3988{
3989 DB_LSN lsn;
3990
3991 if (!PyArg_ParseTuple(args, "(ii):set", &lsn.file, &lsn.offset))
3992 return NULL;
3993
3994 return _DBLogCursor_get(self, DB_SET, &lsn);
3995}
3996
3997
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07003998/* --------------------------------------------------------------------- */
3999/* DBSite methods */
4000
4001
4002#if (DBVER >= 52)
4003static PyObject*
4004DBSite_close_internal(DBSiteObject* self)
4005{
4006 int err = 0;
4007
4008 if (self->site != NULL) {
4009 EXTRACT_FROM_DOUBLE_LINKED_LIST(self);
4010
4011 MYDB_BEGIN_ALLOW_THREADS;
4012 err = self->site->close(self->site);
4013 MYDB_END_ALLOW_THREADS;
4014 self->site = NULL;
4015 }
4016 RETURN_IF_ERR();
4017 RETURN_NONE();
4018}
4019
4020static PyObject*
4021DBSite_close(DBSiteObject* self)
4022{
4023 return DBSite_close_internal(self);
4024}
4025
4026static PyObject*
4027DBSite_remove(DBSiteObject* self)
4028{
4029 int err = 0;
4030
4031 CHECK_SITE_NOT_CLOSED(self);
4032
4033 MYDB_BEGIN_ALLOW_THREADS;
4034 err = self->site->remove(self->site);
4035 MYDB_END_ALLOW_THREADS;
4036
4037 RETURN_IF_ERR();
4038 RETURN_NONE();
4039}
4040
4041static PyObject*
4042DBSite_get_eid(DBSiteObject* self)
4043{
4044 int err = 0;
4045 int eid;
4046
4047 CHECK_SITE_NOT_CLOSED(self);
4048
4049 MYDB_BEGIN_ALLOW_THREADS;
4050 err = self->site->get_eid(self->site, &eid);
4051 MYDB_END_ALLOW_THREADS;
4052
4053 RETURN_IF_ERR();
4054 return NUMBER_FromLong(eid);
4055}
4056
4057static PyObject*
4058DBSite_get_address(DBSiteObject* self)
4059{
4060 int err = 0;
4061 const char *host;
4062 u_int port;
4063
4064 CHECK_SITE_NOT_CLOSED(self);
4065
4066 MYDB_BEGIN_ALLOW_THREADS;
4067 err = self->site->get_address(self->site, &host, &port);
4068 MYDB_END_ALLOW_THREADS;
4069
4070 RETURN_IF_ERR();
4071
4072 return Py_BuildValue("(sI)", host, port);
4073}
4074
4075static PyObject*
4076DBSite_get_config(DBSiteObject* self, PyObject* args, PyObject* kwargs)
4077{
4078 int err = 0;
4079 u_int32_t which, value;
4080 static char* kwnames[] = { "which", NULL };
4081
4082 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i:get_config", kwnames,
4083 &which))
4084 return NULL;
4085
4086 CHECK_SITE_NOT_CLOSED(self);
4087
4088 MYDB_BEGIN_ALLOW_THREADS;
4089 err = self->site->get_config(self->site, which, &value);
4090 MYDB_END_ALLOW_THREADS;
4091
4092 RETURN_IF_ERR();
4093
4094 if (value) {
4095 Py_INCREF(Py_True);
4096 return Py_True;
4097 } else {
4098 Py_INCREF(Py_False);
4099 return Py_False;
4100 }
4101}
4102
4103static PyObject*
4104DBSite_set_config(DBSiteObject* self, PyObject* args, PyObject* kwargs)
4105{
4106 int err = 0;
4107 u_int32_t which, value;
4108 PyObject *valueO;
4109 static char* kwnames[] = { "which", "value", NULL };
4110
4111 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "iO:set_config", kwnames,
4112 &which, &valueO))
4113 return NULL;
4114
4115 CHECK_SITE_NOT_CLOSED(self);
4116
4117 value = PyObject_IsTrue(valueO);
4118
4119 MYDB_BEGIN_ALLOW_THREADS;
4120 err = self->site->set_config(self->site, which, value);
4121 MYDB_END_ALLOW_THREADS;
4122
4123 RETURN_IF_ERR();
4124 RETURN_NONE();
4125}
4126#endif
4127
Jesus Cea6557aac2010-03-22 14:22:26 +00004128
4129/* --------------------------------------------------------------------- */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004130/* DBCursor methods */
4131
4132
4133static PyObject*
Jesus Ceaef9764f2008-05-13 18:45:46 +00004134DBC_close_internal(DBCursorObject* self)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004135{
4136 int err = 0;
4137
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004138 if (self->dbc != NULL) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00004139 EXTRACT_FROM_DOUBLE_LINKED_LIST(self);
4140 if (self->txn) {
4141 EXTRACT_FROM_DOUBLE_LINKED_LIST_TXN(self);
4142 self->txn=NULL;
4143 }
4144
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004145 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004146 err = _DBC_close(self->dbc);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004147 MYDB_END_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004148 self->dbc = NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004149 }
4150 RETURN_IF_ERR();
4151 RETURN_NONE();
4152}
4153
Jesus Ceaef9764f2008-05-13 18:45:46 +00004154static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00004155DBC_close(DBCursorObject* self)
Jesus Ceaef9764f2008-05-13 18:45:46 +00004156{
Jesus Ceaef9764f2008-05-13 18:45:46 +00004157 return DBC_close_internal(self);
4158}
4159
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004160
4161static PyObject*
4162DBC_count(DBCursorObject* self, PyObject* args)
4163{
4164 int err = 0;
4165 db_recno_t count;
4166 int flags = 0;
4167
4168 if (!PyArg_ParseTuple(args, "|i:count", &flags))
4169 return NULL;
4170
4171 CHECK_CURSOR_NOT_CLOSED(self);
4172
4173 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004174 err = _DBC_count(self->dbc, &count, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004175 MYDB_END_ALLOW_THREADS;
4176 RETURN_IF_ERR();
4177
Jesus Ceac5a11fa2008-07-23 11:38:42 +00004178 return NUMBER_FromLong(count);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004179}
4180
4181
4182static PyObject*
4183DBC_current(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4184{
4185 return _DBCursor_get(self,DB_CURRENT,args,kwargs,"|iii:current");
4186}
4187
4188
4189static PyObject*
4190DBC_delete(DBCursorObject* self, PyObject* args)
4191{
4192 int err, flags=0;
4193
4194 if (!PyArg_ParseTuple(args, "|i:delete", &flags))
4195 return NULL;
4196
4197 CHECK_CURSOR_NOT_CLOSED(self);
4198
4199 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004200 err = _DBC_del(self->dbc, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004201 MYDB_END_ALLOW_THREADS;
4202 RETURN_IF_ERR();
4203
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004204 RETURN_NONE();
4205}
4206
4207
4208static PyObject*
4209DBC_dup(DBCursorObject* self, PyObject* args)
4210{
4211 int err, flags =0;
4212 DBC* dbc = NULL;
4213
4214 if (!PyArg_ParseTuple(args, "|i:dup", &flags))
4215 return NULL;
4216
4217 CHECK_CURSOR_NOT_CLOSED(self);
4218
4219 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004220 err = _DBC_dup(self->dbc, &dbc, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004221 MYDB_END_ALLOW_THREADS;
4222 RETURN_IF_ERR();
4223
Jesus Ceaef9764f2008-05-13 18:45:46 +00004224 return (PyObject*) newDBCursorObject(dbc, self->txn, self->mydb);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004225}
4226
4227static PyObject*
4228DBC_first(DBCursorObject* self, PyObject* args, PyObject* kwargs)
4229{
4230 return _DBCursor_get(self,DB_FIRST,args,kwargs,"|iii:first");
4231}
4232
4233
4234static PyObject*
4235DBC_get(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4236{
Martin v. Löwisb2c7aff2002-11-23 11:26:07 +00004237 int err, flags=0;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004238 PyObject* keyobj = NULL;
4239 PyObject* dataobj = NULL;
4240 PyObject* retval = NULL;
4241 int dlen = -1;
4242 int doff = -1;
4243 DBT key, data;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00004244 static char* kwnames[] = { "key","data", "flags", "dlen", "doff",
Jeremy Hyltonaf68c872005-12-10 18:50:16 +00004245 NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004246
4247 CLEAR_DBT(key);
4248 CLEAR_DBT(data);
4249 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|ii:get", &kwnames[2],
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004250 &flags, &dlen, &doff))
Barry Warsaw9a0d7792002-12-30 20:53:52 +00004251 {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004252 PyErr_Clear();
Barry Warsaw9a0d7792002-12-30 20:53:52 +00004253 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Oi|ii:get",
Jesus Cea4907d272008-08-31 14:00:51 +00004254 &kwnames[1],
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004255 &keyobj, &flags, &dlen, &doff))
Barry Warsaw9a0d7792002-12-30 20:53:52 +00004256 {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004257 PyErr_Clear();
Barry Warsaw9a0d7792002-12-30 20:53:52 +00004258 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OOi|ii:get",
4259 kwnames, &keyobj, &dataobj,
4260 &flags, &dlen, &doff))
4261 {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004262 return NULL;
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004263 }
4264 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004265 }
4266
4267 CHECK_CURSOR_NOT_CLOSED(self);
4268
4269 if (keyobj && !make_key_dbt(self->mydb, keyobj, &key, NULL))
4270 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004271 if ( (dataobj && !make_dbt(dataobj, &data)) ||
4272 (!add_partial_dbt(&data, dlen, doff)) )
4273 {
Jesus Ceaef9764f2008-05-13 18:45:46 +00004274 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004275 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004276 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004277
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004278 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004279 err = _DBC_get(self->dbc, &key, &data, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004280 MYDB_END_ALLOW_THREADS;
4281
Gregory P. Smithe9477062005-06-04 06:46:59 +00004282 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004283 && self->mydb->moduleFlags.getReturnsNone) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004284 Py_INCREF(Py_None);
4285 retval = Py_None;
4286 }
4287 else if (makeDBError(err)) {
4288 retval = NULL;
4289 }
4290 else {
4291 switch (_DB_get_type(self->mydb)) {
4292 case -1:
4293 retval = NULL;
4294 break;
4295 case DB_BTREE:
4296 case DB_HASH:
4297 default:
Jesus Ceaef9764f2008-05-13 18:45:46 +00004298 retval = BuildValue_SS(key.data, key.size, data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004299 break;
4300 case DB_RECNO:
4301 case DB_QUEUE:
Jesus Ceaef9764f2008-05-13 18:45:46 +00004302 retval = BuildValue_IS(*((db_recno_t*)key.data), data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004303 break;
4304 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004305 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00004306 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004307 return retval;
4308}
4309
Gregory P. Smith19699a92004-06-28 04:06:49 +00004310static PyObject*
4311DBC_pget(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4312{
4313 int err, flags=0;
4314 PyObject* keyobj = NULL;
4315 PyObject* dataobj = NULL;
4316 PyObject* retval = NULL;
4317 int dlen = -1;
4318 int doff = -1;
4319 DBT key, pkey, data;
Gregory P. Smith372b5832006-06-05 18:48:21 +00004320 static char* kwnames_keyOnly[] = { "key", "flags", "dlen", "doff", NULL };
4321 static char* kwnames[] = { "key", "data", "flags", "dlen", "doff", NULL };
Gregory P. Smith19699a92004-06-28 04:06:49 +00004322
4323 CLEAR_DBT(key);
4324 CLEAR_DBT(data);
4325 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|ii:pget", &kwnames[2],
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004326 &flags, &dlen, &doff))
Gregory P. Smith19699a92004-06-28 04:06:49 +00004327 {
4328 PyErr_Clear();
4329 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Oi|ii:pget",
Jesus Cea6557aac2010-03-22 14:22:26 +00004330 kwnames_keyOnly,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004331 &keyobj, &flags, &dlen, &doff))
Gregory P. Smith19699a92004-06-28 04:06:49 +00004332 {
4333 PyErr_Clear();
4334 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OOi|ii:pget",
4335 kwnames, &keyobj, &dataobj,
4336 &flags, &dlen, &doff))
4337 {
4338 return NULL;
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004339 }
4340 }
Gregory P. Smith19699a92004-06-28 04:06:49 +00004341 }
4342
4343 CHECK_CURSOR_NOT_CLOSED(self);
4344
4345 if (keyobj && !make_key_dbt(self->mydb, keyobj, &key, NULL))
4346 return NULL;
4347 if ( (dataobj && !make_dbt(dataobj, &data)) ||
4348 (!add_partial_dbt(&data, dlen, doff)) ) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00004349 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Gregory P. Smith19699a92004-06-28 04:06:49 +00004350 return NULL;
4351 }
4352
Gregory P. Smith19699a92004-06-28 04:06:49 +00004353 CLEAR_DBT(pkey);
4354 pkey.flags = DB_DBT_MALLOC;
4355
4356 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004357 err = _DBC_pget(self->dbc, &key, &pkey, &data, flags);
Gregory P. Smith19699a92004-06-28 04:06:49 +00004358 MYDB_END_ALLOW_THREADS;
4359
Gregory P. Smithe9477062005-06-04 06:46:59 +00004360 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004361 && self->mydb->moduleFlags.getReturnsNone) {
Gregory P. Smith19699a92004-06-28 04:06:49 +00004362 Py_INCREF(Py_None);
4363 retval = Py_None;
4364 }
4365 else if (makeDBError(err)) {
4366 retval = NULL;
4367 }
4368 else {
4369 PyObject *pkeyObj;
4370 PyObject *dataObj;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004371 dataObj = Build_PyString(data.data, data.size);
Gregory P. Smith19699a92004-06-28 04:06:49 +00004372
4373 if (self->mydb->primaryDBType == DB_RECNO ||
4374 self->mydb->primaryDBType == DB_QUEUE)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00004375 pkeyObj = NUMBER_FromLong(*(int *)pkey.data);
Gregory P. Smith19699a92004-06-28 04:06:49 +00004376 else
Jesus Ceaef9764f2008-05-13 18:45:46 +00004377 pkeyObj = Build_PyString(pkey.data, pkey.size);
Gregory P. Smith19699a92004-06-28 04:06:49 +00004378
Gregory P. Smith4e414d82006-01-24 19:55:02 +00004379 if (key.data && key.size) /* return key, pkey and data */
Gregory P. Smith19699a92004-06-28 04:06:49 +00004380 {
4381 PyObject *keyObj;
4382 int type = _DB_get_type(self->mydb);
4383 if (type == DB_RECNO || type == DB_QUEUE)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00004384 keyObj = NUMBER_FromLong(*(int *)key.data);
Gregory P. Smith19699a92004-06-28 04:06:49 +00004385 else
Jesus Ceaef9764f2008-05-13 18:45:46 +00004386 keyObj = Build_PyString(key.data, key.size);
Gregory P. Smith4e414d82006-01-24 19:55:02 +00004387 retval = PyTuple_Pack(3, keyObj, pkeyObj, dataObj);
Thomas Woutersb3153832006-03-08 01:47:19 +00004388 Py_DECREF(keyObj);
Jesus Ceaef9764f2008-05-13 18:45:46 +00004389 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Gregory P. Smith19699a92004-06-28 04:06:49 +00004390 }
4391 else /* return just the pkey and data */
4392 {
Gregory P. Smith4e414d82006-01-24 19:55:02 +00004393 retval = PyTuple_Pack(2, pkeyObj, dataObj);
Gregory P. Smith19699a92004-06-28 04:06:49 +00004394 }
Thomas Woutersb3153832006-03-08 01:47:19 +00004395 Py_DECREF(dataObj);
4396 Py_DECREF(pkeyObj);
Gregory P. Smith19699a92004-06-28 04:06:49 +00004397 FREE_DBT(pkey);
Gregory P. Smith19699a92004-06-28 04:06:49 +00004398 }
4399 /* the only time REALLOC should be set is if we used an integer
4400 * key that make_key_dbt malloc'd for us. always free these. */
Jesus Ceaef9764f2008-05-13 18:45:46 +00004401 if (key.flags & DB_DBT_REALLOC) { /* 'make_key_dbt' could do a 'malloc' */
Gregory P. Smith19699a92004-06-28 04:06:49 +00004402 FREE_DBT(key);
4403 }
4404 return retval;
4405}
4406
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004407
4408static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00004409DBC_get_recno(DBCursorObject* self)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004410{
4411 int err;
4412 db_recno_t recno;
4413 DBT key;
4414 DBT data;
4415
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004416 CHECK_CURSOR_NOT_CLOSED(self);
4417
4418 CLEAR_DBT(key);
4419 CLEAR_DBT(data);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004420
4421 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004422 err = _DBC_get(self->dbc, &key, &data, DB_GET_RECNO);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004423 MYDB_END_ALLOW_THREADS;
4424 RETURN_IF_ERR();
4425
4426 recno = *((db_recno_t*)data.data);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00004427 return NUMBER_FromLong(recno);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004428}
4429
4430
4431static PyObject*
4432DBC_last(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4433{
4434 return _DBCursor_get(self,DB_LAST,args,kwargs,"|iii:last");
4435}
4436
4437
4438static PyObject*
4439DBC_next(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4440{
4441 return _DBCursor_get(self,DB_NEXT,args,kwargs,"|iii:next");
4442}
4443
4444
4445static PyObject*
4446DBC_prev(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4447{
4448 return _DBCursor_get(self,DB_PREV,args,kwargs,"|iii:prev");
4449}
4450
4451
4452static PyObject*
4453DBC_put(DBCursorObject* self, PyObject* args, PyObject* kwargs)
4454{
4455 int err, flags = 0;
4456 PyObject* keyobj, *dataobj;
4457 DBT key, data;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00004458 static char* kwnames[] = { "key", "data", "flags", "dlen", "doff",
Jeremy Hyltonaf68c872005-12-10 18:50:16 +00004459 NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004460 int dlen = -1;
4461 int doff = -1;
4462
4463 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|iii:put", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004464 &keyobj, &dataobj, &flags, &dlen, &doff))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004465 return NULL;
4466
4467 CHECK_CURSOR_NOT_CLOSED(self);
4468
4469 if (!make_key_dbt(self->mydb, keyobj, &key, NULL))
4470 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004471 if (!make_dbt(dataobj, &data) ||
4472 !add_partial_dbt(&data, dlen, doff) )
4473 {
Jesus Ceaef9764f2008-05-13 18:45:46 +00004474 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004475 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004476 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004477
4478 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004479 err = _DBC_put(self->dbc, &key, &data, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004480 MYDB_END_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004481 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004482 RETURN_IF_ERR();
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004483 RETURN_NONE();
4484}
4485
4486
4487static PyObject*
4488DBC_set(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4489{
4490 int err, flags = 0;
4491 DBT key, data;
4492 PyObject* retval, *keyobj;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00004493 static char* kwnames[] = { "key", "flags", "dlen", "doff", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004494 int dlen = -1;
4495 int doff = -1;
4496
4497 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|iii:set", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004498 &keyobj, &flags, &dlen, &doff))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004499 return NULL;
4500
4501 CHECK_CURSOR_NOT_CLOSED(self);
4502
4503 if (!make_key_dbt(self->mydb, keyobj, &key, NULL))
4504 return NULL;
4505
4506 CLEAR_DBT(data);
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004507 if (!add_partial_dbt(&data, dlen, doff)) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00004508 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004509 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004510 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004511
4512 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004513 err = _DBC_get(self->dbc, &key, &data, flags|DB_SET);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004514 MYDB_END_ALLOW_THREADS;
Gregory P. Smithe9477062005-06-04 06:46:59 +00004515 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004516 && self->mydb->moduleFlags.cursorSetReturnsNone) {
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004517 Py_INCREF(Py_None);
4518 retval = Py_None;
4519 }
4520 else if (makeDBError(err)) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004521 retval = NULL;
4522 }
4523 else {
4524 switch (_DB_get_type(self->mydb)) {
4525 case -1:
4526 retval = NULL;
4527 break;
4528 case DB_BTREE:
4529 case DB_HASH:
4530 default:
Jesus Ceaef9764f2008-05-13 18:45:46 +00004531 retval = BuildValue_SS(key.data, key.size, data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004532 break;
4533 case DB_RECNO:
4534 case DB_QUEUE:
Jesus Ceaef9764f2008-05-13 18:45:46 +00004535 retval = BuildValue_IS(*((db_recno_t*)key.data), data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004536 break;
4537 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00004538 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004539 }
Gregory P. Smith19699a92004-06-28 04:06:49 +00004540 /* the only time REALLOC should be set is if we used an integer
4541 * key that make_key_dbt malloc'd for us. always free these. */
4542 if (key.flags & DB_DBT_REALLOC) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00004543 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Gregory P. Smith19699a92004-06-28 04:06:49 +00004544 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004545
4546 return retval;
4547}
4548
4549
4550static PyObject*
4551DBC_set_range(DBCursorObject* self, PyObject* args, PyObject* kwargs)
4552{
4553 int err, flags = 0;
4554 DBT key, data;
4555 PyObject* retval, *keyobj;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00004556 static char* kwnames[] = { "key", "flags", "dlen", "doff", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004557 int dlen = -1;
4558 int doff = -1;
4559
4560 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|iii:set_range", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004561 &keyobj, &flags, &dlen, &doff))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004562 return NULL;
4563
4564 CHECK_CURSOR_NOT_CLOSED(self);
4565
4566 if (!make_key_dbt(self->mydb, keyobj, &key, NULL))
4567 return NULL;
4568
4569 CLEAR_DBT(data);
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004570 if (!add_partial_dbt(&data, dlen, doff)) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00004571 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004572 return NULL;
4573 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004574 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004575 err = _DBC_get(self->dbc, &key, &data, flags|DB_SET_RANGE);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004576 MYDB_END_ALLOW_THREADS;
Gregory P. Smithe9477062005-06-04 06:46:59 +00004577 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004578 && self->mydb->moduleFlags.cursorSetReturnsNone) {
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004579 Py_INCREF(Py_None);
4580 retval = Py_None;
4581 }
4582 else if (makeDBError(err)) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004583 retval = NULL;
4584 }
4585 else {
4586 switch (_DB_get_type(self->mydb)) {
4587 case -1:
4588 retval = NULL;
4589 break;
4590 case DB_BTREE:
4591 case DB_HASH:
4592 default:
Jesus Ceaef9764f2008-05-13 18:45:46 +00004593 retval = BuildValue_SS(key.data, key.size, data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004594 break;
4595 case DB_RECNO:
4596 case DB_QUEUE:
Jesus Ceaef9764f2008-05-13 18:45:46 +00004597 retval = BuildValue_IS(*((db_recno_t*)key.data), data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004598 break;
4599 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00004600 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004601 }
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004602 /* the only time REALLOC should be set is if we used an integer
Gregory P. Smith19699a92004-06-28 04:06:49 +00004603 * key that make_key_dbt malloc'd for us. always free these. */
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004604 if (key.flags & DB_DBT_REALLOC) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00004605 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004606 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004607
4608 return retval;
4609}
4610
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004611static PyObject*
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004612_DBC_get_set_both(DBCursorObject* self, PyObject* keyobj, PyObject* dataobj,
4613 int flags, unsigned int returnsNone)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004614{
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004615 int err;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004616 DBT key, data;
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004617 PyObject* retval;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004618
Gregory P. Smith7441e652003-11-03 21:35:31 +00004619 /* the caller did this: CHECK_CURSOR_NOT_CLOSED(self); */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004620 if (!make_key_dbt(self->mydb, keyobj, &key, NULL))
4621 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004622 if (!make_dbt(dataobj, &data)) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00004623 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004624 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004625 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004626
4627 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004628 err = _DBC_get(self->dbc, &key, &data, flags|DB_GET_BOTH);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004629 MYDB_END_ALLOW_THREADS;
Gregory P. Smithe9477062005-06-04 06:46:59 +00004630 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY) && returnsNone) {
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004631 Py_INCREF(Py_None);
4632 retval = Py_None;
4633 }
4634 else if (makeDBError(err)) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004635 retval = NULL;
4636 }
4637 else {
4638 switch (_DB_get_type(self->mydb)) {
4639 case -1:
4640 retval = NULL;
4641 break;
4642 case DB_BTREE:
4643 case DB_HASH:
4644 default:
Jesus Ceaef9764f2008-05-13 18:45:46 +00004645 retval = BuildValue_SS(key.data, key.size, data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004646 break;
4647 case DB_RECNO:
4648 case DB_QUEUE:
Jesus Ceaef9764f2008-05-13 18:45:46 +00004649 retval = BuildValue_IS(*((db_recno_t*)key.data), data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004650 break;
4651 }
4652 }
4653
Jesus Ceaef9764f2008-05-13 18:45:46 +00004654 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004655 return retval;
4656}
4657
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004658static PyObject*
4659DBC_get_both(DBCursorObject* self, PyObject* args)
4660{
4661 int flags=0;
4662 PyObject *keyobj, *dataobj;
4663
4664 if (!PyArg_ParseTuple(args, "OO|i:get_both", &keyobj, &dataobj, &flags))
4665 return NULL;
4666
Gregory P. Smith7441e652003-11-03 21:35:31 +00004667 /* if the cursor is closed, self->mydb may be invalid */
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004668 CHECK_CURSOR_NOT_CLOSED(self);
4669
4670 return _DBC_get_set_both(self, keyobj, dataobj, flags,
4671 self->mydb->moduleFlags.getReturnsNone);
4672}
4673
Gregory P. Smithbe0db8b2003-10-01 06:48:51 +00004674/* Return size of entry */
4675static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00004676DBC_get_current_size(DBCursorObject* self)
Gregory P. Smithbe0db8b2003-10-01 06:48:51 +00004677{
4678 int err, flags=DB_CURRENT;
4679 PyObject* retval = NULL;
4680 DBT key, data;
4681
Gregory P. Smithbe0db8b2003-10-01 06:48:51 +00004682 CHECK_CURSOR_NOT_CLOSED(self);
4683 CLEAR_DBT(key);
4684 CLEAR_DBT(data);
4685
Gregory P. Smith8b7e9172004-12-13 09:51:23 +00004686 /* We don't allocate any memory, forcing a DB_BUFFER_SMALL error and thus
Gregory P. Smithbe0db8b2003-10-01 06:48:51 +00004687 getting the record size. */
4688 data.flags = DB_DBT_USERMEM;
4689 data.ulen = 0;
4690 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004691 err = _DBC_get(self->dbc, &key, &data, flags);
Gregory P. Smithbe0db8b2003-10-01 06:48:51 +00004692 MYDB_END_ALLOW_THREADS;
Gregory P. Smith8b7e9172004-12-13 09:51:23 +00004693 if (err == DB_BUFFER_SMALL || !err) {
4694 /* DB_BUFFER_SMALL means positive size, !err means zero length value */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00004695 retval = NUMBER_FromLong((long)data.size);
Gregory P. Smithbe0db8b2003-10-01 06:48:51 +00004696 err = 0;
4697 }
4698
Gregory P. Smithbe0db8b2003-10-01 06:48:51 +00004699 RETURN_IF_ERR();
4700 return retval;
4701}
4702
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004703static PyObject*
4704DBC_set_both(DBCursorObject* self, PyObject* args)
4705{
4706 int flags=0;
4707 PyObject *keyobj, *dataobj;
4708
4709 if (!PyArg_ParseTuple(args, "OO|i:set_both", &keyobj, &dataobj, &flags))
4710 return NULL;
4711
Gregory P. Smith7441e652003-11-03 21:35:31 +00004712 /* if the cursor is closed, self->mydb may be invalid */
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004713 CHECK_CURSOR_NOT_CLOSED(self);
4714
4715 return _DBC_get_set_both(self, keyobj, dataobj, flags,
4716 self->mydb->moduleFlags.cursorSetReturnsNone);
4717}
4718
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004719
4720static PyObject*
4721DBC_set_recno(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4722{
4723 int err, irecno, flags=0;
4724 db_recno_t recno;
4725 DBT key, data;
4726 PyObject* retval;
4727 int dlen = -1;
4728 int doff = -1;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00004729 static char* kwnames[] = { "recno","flags", "dlen", "doff", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004730
4731 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|iii:set_recno", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004732 &irecno, &flags, &dlen, &doff))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004733 return NULL;
4734
4735 CHECK_CURSOR_NOT_CLOSED(self);
4736
4737 CLEAR_DBT(key);
4738 recno = (db_recno_t) irecno;
Barry Warsaw9a0d7792002-12-30 20:53:52 +00004739 /* use allocated space so DB will be able to realloc room for the real
4740 * key */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004741 key.data = malloc(sizeof(db_recno_t));
4742 if (key.data == NULL) {
4743 PyErr_SetString(PyExc_MemoryError, "Key memory allocation failed");
4744 return NULL;
4745 }
4746 key.size = sizeof(db_recno_t);
4747 key.ulen = key.size;
4748 memcpy(key.data, &recno, sizeof(db_recno_t));
4749 key.flags = DB_DBT_REALLOC;
4750
4751 CLEAR_DBT(data);
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004752 if (!add_partial_dbt(&data, dlen, doff)) {
4753 FREE_DBT(key);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004754 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004755 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004756
4757 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004758 err = _DBC_get(self->dbc, &key, &data, flags|DB_SET_RECNO);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004759 MYDB_END_ALLOW_THREADS;
Gregory P. Smithe9477062005-06-04 06:46:59 +00004760 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004761 && self->mydb->moduleFlags.cursorSetReturnsNone) {
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004762 Py_INCREF(Py_None);
4763 retval = Py_None;
4764 }
4765 else if (makeDBError(err)) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004766 retval = NULL;
4767 }
4768 else { /* Can only be used for BTrees, so no need to return int key */
Jesus Ceaef9764f2008-05-13 18:45:46 +00004769 retval = BuildValue_SS(key.data, key.size, data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004770 }
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004771 FREE_DBT(key);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004772
4773 return retval;
4774}
4775
4776
4777static PyObject*
4778DBC_consume(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4779{
4780 return _DBCursor_get(self,DB_CONSUME,args,kwargs,"|iii:consume");
4781}
4782
4783
4784static PyObject*
4785DBC_next_dup(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4786{
4787 return _DBCursor_get(self,DB_NEXT_DUP,args,kwargs,"|iii:next_dup");
4788}
4789
4790
4791static PyObject*
4792DBC_next_nodup(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4793{
4794 return _DBCursor_get(self,DB_NEXT_NODUP,args,kwargs,"|iii:next_nodup");
4795}
4796
Jesus Cea6557aac2010-03-22 14:22:26 +00004797#if (DBVER >= 46)
4798static PyObject*
4799DBC_prev_dup(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4800{
4801 return _DBCursor_get(self,DB_PREV_DUP,args,kwargs,"|iii:prev_dup");
4802}
4803#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004804
4805static PyObject*
4806DBC_prev_nodup(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4807{
4808 return _DBCursor_get(self,DB_PREV_NODUP,args,kwargs,"|iii:prev_nodup");
4809}
4810
4811
4812static PyObject*
4813DBC_join_item(DBCursorObject* self, PyObject* args)
4814{
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004815 int err, flags=0;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004816 DBT key, data;
4817 PyObject* retval;
4818
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004819 if (!PyArg_ParseTuple(args, "|i:join_item", &flags))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004820 return NULL;
4821
4822 CHECK_CURSOR_NOT_CLOSED(self);
4823
4824 CLEAR_DBT(key);
4825 CLEAR_DBT(data);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004826
4827 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004828 err = _DBC_get(self->dbc, &key, &data, flags | DB_JOIN_ITEM);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004829 MYDB_END_ALLOW_THREADS;
Gregory P. Smithe9477062005-06-04 06:46:59 +00004830 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004831 && self->mydb->moduleFlags.getReturnsNone) {
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004832 Py_INCREF(Py_None);
4833 retval = Py_None;
4834 }
4835 else if (makeDBError(err)) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004836 retval = NULL;
4837 }
4838 else {
Jesus Ceaef9764f2008-05-13 18:45:46 +00004839 retval = BuildValue_S(key.data, key.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004840 }
4841
4842 return retval;
4843}
4844
4845
Jesus Cea6557aac2010-03-22 14:22:26 +00004846#if (DBVER >= 46)
4847static PyObject*
4848DBC_set_priority(DBCursorObject* self, PyObject* args, PyObject* kwargs)
4849{
4850 int err, priority;
4851 static char* kwnames[] = { "priority", NULL };
4852
4853 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i:set_priority", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004854 &priority))
Jesus Cea6557aac2010-03-22 14:22:26 +00004855 return NULL;
4856
4857 CHECK_CURSOR_NOT_CLOSED(self);
4858
4859 MYDB_BEGIN_ALLOW_THREADS;
4860 err = self->dbc->set_priority(self->dbc, priority);
4861 MYDB_END_ALLOW_THREADS;
4862 RETURN_IF_ERR();
4863 RETURN_NONE();
4864}
4865
4866
4867static PyObject*
4868DBC_get_priority(DBCursorObject* self)
4869{
4870 int err;
4871 DB_CACHE_PRIORITY priority;
4872
4873 CHECK_CURSOR_NOT_CLOSED(self);
4874
4875 MYDB_BEGIN_ALLOW_THREADS;
4876 err = self->dbc->get_priority(self->dbc, &priority);
4877 MYDB_END_ALLOW_THREADS;
4878 RETURN_IF_ERR();
4879 return NUMBER_FromLong(priority);
4880}
4881#endif
4882
4883
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004884
4885/* --------------------------------------------------------------------- */
4886/* DBEnv methods */
4887
4888
4889static PyObject*
Jesus Ceaef9764f2008-05-13 18:45:46 +00004890DBEnv_close_internal(DBEnvObject* self, int flags)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004891{
Jesus Ceaef9764f2008-05-13 18:45:46 +00004892 PyObject *dummy;
4893 int err;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004894
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004895 if (!self->closed) { /* Don't close more than once */
Jesus Ceaef9764f2008-05-13 18:45:46 +00004896 while(self->children_txns) {
Jesus Cea6557aac2010-03-22 14:22:26 +00004897 dummy = DBTxn_abort_discard_internal(self->children_txns, 0);
4898 Py_XDECREF(dummy);
Jesus Ceaef9764f2008-05-13 18:45:46 +00004899 }
4900 while(self->children_dbs) {
Jesus Cea6557aac2010-03-22 14:22:26 +00004901 dummy = DB_close_internal(self->children_dbs, 0, 0);
4902 Py_XDECREF(dummy);
4903 }
4904 while(self->children_logcursors) {
4905 dummy = DBLogCursor_close_internal(self->children_logcursors);
4906 Py_XDECREF(dummy);
Jesus Ceaef9764f2008-05-13 18:45:46 +00004907 }
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07004908#if (DBVER >= 52)
4909 while(self->children_sites) {
4910 dummy = DBSite_close_internal(self->children_sites);
4911 Py_XDECREF(dummy);
4912 }
4913#endif
Jesus Ceaac25fab2008-09-03 17:50:32 +00004914 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00004915
Jesus Ceaac25fab2008-09-03 17:50:32 +00004916 self->closed = 1;
4917 if (self->db_env) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004918 MYDB_BEGIN_ALLOW_THREADS;
4919 err = self->db_env->close(self->db_env, flags);
4920 MYDB_END_ALLOW_THREADS;
4921 /* after calling DBEnv->close, regardless of error, this DBEnv
Jesus Ceaef9764f2008-05-13 18:45:46 +00004922 * may not be accessed again (Berkeley DB docs). */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004923 self->db_env = NULL;
4924 RETURN_IF_ERR();
4925 }
4926 RETURN_NONE();
4927}
4928
Jesus Ceaef9764f2008-05-13 18:45:46 +00004929static PyObject*
4930DBEnv_close(DBEnvObject* self, PyObject* args)
4931{
4932 int flags = 0;
4933
4934 if (!PyArg_ParseTuple(args, "|i:close", &flags))
4935 return NULL;
Jesus Cea5cd5f122008-09-23 18:54:08 +00004936 return DBEnv_close_internal(self, flags);
Jesus Ceaef9764f2008-05-13 18:45:46 +00004937}
4938
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004939
4940static PyObject*
4941DBEnv_open(DBEnvObject* self, PyObject* args)
4942{
4943 int err, flags=0, mode=0660;
4944 char *db_home;
4945
4946 if (!PyArg_ParseTuple(args, "z|ii:open", &db_home, &flags, &mode))
4947 return NULL;
4948
4949 CHECK_ENV_NOT_CLOSED(self);
4950
4951 MYDB_BEGIN_ALLOW_THREADS;
4952 err = self->db_env->open(self->db_env, db_home, flags, mode);
4953 MYDB_END_ALLOW_THREADS;
4954 RETURN_IF_ERR();
4955 self->closed = 0;
4956 self->flags = flags;
4957 RETURN_NONE();
4958}
4959
4960
4961static PyObject*
Jesus Cea6557aac2010-03-22 14:22:26 +00004962DBEnv_memp_stat(DBEnvObject* self, PyObject* args, PyObject *kwargs)
4963{
4964 int err;
4965 DB_MPOOL_STAT *gsp;
4966 DB_MPOOL_FSTAT **fsp, **fsp2;
4967 PyObject* d = NULL, *d2, *d3, *r;
4968 u_int32_t flags = 0;
4969 static char* kwnames[] = { "flags", NULL };
4970
4971 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:memp_stat",
4972 kwnames, &flags))
4973 return NULL;
4974
4975 CHECK_ENV_NOT_CLOSED(self);
4976
4977 MYDB_BEGIN_ALLOW_THREADS;
4978 err = self->db_env->memp_stat(self->db_env, &gsp, &fsp, flags);
4979 MYDB_END_ALLOW_THREADS;
4980 RETURN_IF_ERR();
4981
4982 /* Turn the stat structure into a dictionary */
4983 d = PyDict_New();
4984 if (d == NULL) {
4985 if (gsp)
4986 free(gsp);
4987 return NULL;
4988 }
4989
4990#define MAKE_ENTRY(name) _addIntToDict(d, #name, gsp->st_##name)
4991
4992 MAKE_ENTRY(gbytes);
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07004993 MAKE_ENTRY(bytes);
Jesus Cea6557aac2010-03-22 14:22:26 +00004994 MAKE_ENTRY(ncache);
4995#if (DBVER >= 46)
4996 MAKE_ENTRY(max_ncache);
4997#endif
4998 MAKE_ENTRY(regsize);
Jesus Cea6557aac2010-03-22 14:22:26 +00004999 MAKE_ENTRY(mmapsize);
5000 MAKE_ENTRY(maxopenfd);
5001 MAKE_ENTRY(maxwrite);
5002 MAKE_ENTRY(maxwrite_sleep);
Jesus Cea6557aac2010-03-22 14:22:26 +00005003 MAKE_ENTRY(map);
5004 MAKE_ENTRY(cache_hit);
5005 MAKE_ENTRY(cache_miss);
5006 MAKE_ENTRY(page_create);
5007 MAKE_ENTRY(page_in);
5008 MAKE_ENTRY(page_out);
5009 MAKE_ENTRY(ro_evict);
5010 MAKE_ENTRY(rw_evict);
5011 MAKE_ENTRY(page_trickle);
5012 MAKE_ENTRY(pages);
5013 MAKE_ENTRY(page_clean);
5014 MAKE_ENTRY(page_dirty);
5015 MAKE_ENTRY(hash_buckets);
5016 MAKE_ENTRY(hash_searches);
5017 MAKE_ENTRY(hash_longest);
5018 MAKE_ENTRY(hash_examined);
5019 MAKE_ENTRY(hash_nowait);
5020 MAKE_ENTRY(hash_wait);
5021#if (DBVER >= 45)
5022 MAKE_ENTRY(hash_max_nowait);
5023#endif
5024 MAKE_ENTRY(hash_max_wait);
5025 MAKE_ENTRY(region_wait);
5026 MAKE_ENTRY(region_nowait);
5027#if (DBVER >= 45)
5028 MAKE_ENTRY(mvcc_frozen);
5029 MAKE_ENTRY(mvcc_thawed);
5030 MAKE_ENTRY(mvcc_freed);
5031#endif
5032 MAKE_ENTRY(alloc);
5033 MAKE_ENTRY(alloc_buckets);
5034 MAKE_ENTRY(alloc_max_buckets);
5035 MAKE_ENTRY(alloc_pages);
5036 MAKE_ENTRY(alloc_max_pages);
5037#if (DBVER >= 45)
5038 MAKE_ENTRY(io_wait);
5039#endif
5040#if (DBVER >= 48)
5041 MAKE_ENTRY(sync_interrupted);
5042#endif
5043
5044#undef MAKE_ENTRY
5045 free(gsp);
5046
5047 d2 = PyDict_New();
5048 if (d2 == NULL) {
5049 Py_DECREF(d);
5050 if (fsp)
5051 free(fsp);
5052 return NULL;
5053 }
5054#define MAKE_ENTRY(name) _addIntToDict(d3, #name, (*fsp2)->st_##name)
5055 for(fsp2=fsp;*fsp2; fsp2++) {
5056 d3 = PyDict_New();
5057 if (d3 == NULL) {
5058 Py_DECREF(d);
5059 Py_DECREF(d2);
5060 if (fsp)
5061 free(fsp);
5062 return NULL;
5063 }
5064 MAKE_ENTRY(pagesize);
5065 MAKE_ENTRY(cache_hit);
5066 MAKE_ENTRY(cache_miss);
5067 MAKE_ENTRY(map);
5068 MAKE_ENTRY(page_create);
5069 MAKE_ENTRY(page_in);
5070 MAKE_ENTRY(page_out);
5071 if(PyDict_SetItemString(d2, (*fsp2)->file_name, d3)) {
5072 Py_DECREF(d);
5073 Py_DECREF(d2);
5074 Py_DECREF(d3);
5075 if (fsp)
5076 free(fsp);
5077 return NULL;
5078 }
5079 Py_DECREF(d3);
5080 }
5081
5082#undef MAKE_ENTRY
5083 free(fsp);
5084
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07005085 r = PyTuple_Pack(2, d, d2);
Jesus Cea6557aac2010-03-22 14:22:26 +00005086 Py_DECREF(d);
5087 Py_DECREF(d2);
5088 return r;
5089}
5090
Jesus Cea6557aac2010-03-22 14:22:26 +00005091static PyObject*
5092DBEnv_memp_stat_print(DBEnvObject* self, PyObject* args, PyObject *kwargs)
5093{
5094 int err;
5095 int flags=0;
5096 static char* kwnames[] = { "flags", NULL };
5097
5098 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:memp_stat_print",
5099 kwnames, &flags))
5100 {
5101 return NULL;
5102 }
5103 CHECK_ENV_NOT_CLOSED(self);
5104 MYDB_BEGIN_ALLOW_THREADS;
5105 err = self->db_env->memp_stat_print(self->db_env, flags);
5106 MYDB_END_ALLOW_THREADS;
5107 RETURN_IF_ERR();
5108 RETURN_NONE();
5109}
Jesus Cea6557aac2010-03-22 14:22:26 +00005110
5111
5112static PyObject*
5113DBEnv_memp_trickle(DBEnvObject* self, PyObject* args)
5114{
5115 int err, percent, nwrotep;
5116
5117 if (!PyArg_ParseTuple(args, "i:memp_trickle", &percent))
5118 return NULL;
5119 CHECK_ENV_NOT_CLOSED(self);
5120 MYDB_BEGIN_ALLOW_THREADS;
5121 err = self->db_env->memp_trickle(self->db_env, percent, &nwrotep);
5122 MYDB_END_ALLOW_THREADS;
5123 RETURN_IF_ERR();
5124 return NUMBER_FromLong(nwrotep);
5125}
5126
5127static PyObject*
5128DBEnv_memp_sync(DBEnvObject* self, PyObject* args)
5129{
5130 int err;
5131 DB_LSN lsn = {0, 0};
5132 DB_LSN *lsn_p = NULL;
5133
5134 if (!PyArg_ParseTuple(args, "|(ii):memp_sync", &lsn.file, &lsn.offset))
5135 return NULL;
5136 if ((lsn.file!=0) || (lsn.offset!=0)) {
5137 lsn_p = &lsn;
5138 }
5139 CHECK_ENV_NOT_CLOSED(self);
5140 MYDB_BEGIN_ALLOW_THREADS;
5141 err = self->db_env->memp_sync(self->db_env, lsn_p);
5142 MYDB_END_ALLOW_THREADS;
5143 RETURN_IF_ERR();
5144 RETURN_NONE();
5145}
5146
5147static PyObject*
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005148DBEnv_remove(DBEnvObject* self, PyObject* args)
5149{
5150 int err, flags=0;
5151 char *db_home;
5152
5153 if (!PyArg_ParseTuple(args, "s|i:remove", &db_home, &flags))
5154 return NULL;
5155 CHECK_ENV_NOT_CLOSED(self);
5156 MYDB_BEGIN_ALLOW_THREADS;
5157 err = self->db_env->remove(self->db_env, db_home, flags);
5158 MYDB_END_ALLOW_THREADS;
5159 RETURN_IF_ERR();
5160 RETURN_NONE();
5161}
5162
Barry Warsaw9a0d7792002-12-30 20:53:52 +00005163static PyObject*
5164DBEnv_dbremove(DBEnvObject* self, PyObject* args, PyObject* kwargs)
5165{
5166 int err;
5167 u_int32_t flags=0;
5168 char *file = NULL;
5169 char *database = NULL;
5170 PyObject *txnobj = NULL;
5171 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00005172 static char* kwnames[] = { "file", "database", "txn", "flags",
Jeremy Hyltonaf68c872005-12-10 18:50:16 +00005173 NULL };
Barry Warsaw9a0d7792002-12-30 20:53:52 +00005174
Gregory P. Smith641cddf2006-07-28 01:35:25 +00005175 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|zOi:dbremove", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00005176 &file, &database, &txnobj, &flags)) {
5177 return NULL;
Barry Warsaw9a0d7792002-12-30 20:53:52 +00005178 }
5179 if (!checkTxnObj(txnobj, &txn)) {
5180 return NULL;
5181 }
5182 CHECK_ENV_NOT_CLOSED(self);
5183 MYDB_BEGIN_ALLOW_THREADS;
5184 err = self->db_env->dbremove(self->db_env, txn, file, database, flags);
5185 MYDB_END_ALLOW_THREADS;
5186 RETURN_IF_ERR();
5187 RETURN_NONE();
5188}
5189
5190static PyObject*
5191DBEnv_dbrename(DBEnvObject* self, PyObject* args, PyObject* kwargs)
5192{
5193 int err;
5194 u_int32_t flags=0;
5195 char *file = NULL;
5196 char *database = NULL;
5197 char *newname = NULL;
5198 PyObject *txnobj = NULL;
5199 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00005200 static char* kwnames[] = { "file", "database", "newname", "txn",
Jeremy Hyltonaf68c872005-12-10 18:50:16 +00005201 "flags", NULL };
Barry Warsaw9a0d7792002-12-30 20:53:52 +00005202
Gregory P. Smith641cddf2006-07-28 01:35:25 +00005203 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "szs|Oi:dbrename", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00005204 &file, &database, &newname, &txnobj, &flags)) {
5205 return NULL;
Barry Warsaw9a0d7792002-12-30 20:53:52 +00005206 }
5207 if (!checkTxnObj(txnobj, &txn)) {
5208 return NULL;
5209 }
5210 CHECK_ENV_NOT_CLOSED(self);
5211 MYDB_BEGIN_ALLOW_THREADS;
5212 err = self->db_env->dbrename(self->db_env, txn, file, database, newname,
5213 flags);
5214 MYDB_END_ALLOW_THREADS;
5215 RETURN_IF_ERR();
5216 RETURN_NONE();
5217}
5218
Jesus Cea6557aac2010-03-22 14:22:26 +00005219
5220
Barry Warsaw9a0d7792002-12-30 20:53:52 +00005221static PyObject*
5222DBEnv_set_encrypt(DBEnvObject* self, PyObject* args, PyObject* kwargs)
5223{
5224 int err;
5225 u_int32_t flags=0;
5226 char *passwd = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00005227 static char* kwnames[] = { "passwd", "flags", NULL };
Barry Warsaw9a0d7792002-12-30 20:53:52 +00005228
5229 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|i:set_encrypt", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00005230 &passwd, &flags)) {
5231 return NULL;
Barry Warsaw9a0d7792002-12-30 20:53:52 +00005232 }
5233
5234 MYDB_BEGIN_ALLOW_THREADS;
5235 err = self->db_env->set_encrypt(self->db_env, passwd, flags);
5236 MYDB_END_ALLOW_THREADS;
5237
5238 RETURN_IF_ERR();
5239 RETURN_NONE();
5240}
Jesus Cea6557aac2010-03-22 14:22:26 +00005241
Jesus Cea6557aac2010-03-22 14:22:26 +00005242static PyObject*
5243DBEnv_get_encrypt_flags(DBEnvObject* self)
5244{
5245 int err;
5246 u_int32_t flags;
5247
5248 CHECK_ENV_NOT_CLOSED(self);
5249
5250 MYDB_BEGIN_ALLOW_THREADS;
5251 err = self->db_env->get_encrypt_flags(self->db_env, &flags);
5252 MYDB_END_ALLOW_THREADS;
5253
5254 RETURN_IF_ERR();
5255
5256 return NUMBER_FromLong(flags);
5257}
5258
5259static PyObject*
5260DBEnv_get_timeout(DBEnvObject* self, PyObject* args, PyObject* kwargs)
5261{
5262 int err;
5263 int flag;
5264 u_int32_t timeout;
5265 static char* kwnames[] = {"flag", NULL };
5266
5267 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i:get_timeout", kwnames,
5268 &flag)) {
5269 return NULL;
5270 }
5271 CHECK_ENV_NOT_CLOSED(self);
5272
5273 MYDB_BEGIN_ALLOW_THREADS;
5274 err = self->db_env->get_timeout(self->db_env, &timeout, flag);
5275 MYDB_END_ALLOW_THREADS;
5276 RETURN_IF_ERR();
5277 return NUMBER_FromLong(timeout);
5278}
Jesus Cea6557aac2010-03-22 14:22:26 +00005279
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005280
Gregory P. Smithfe11d3e2003-03-27 17:23:29 +00005281static PyObject*
5282DBEnv_set_timeout(DBEnvObject* self, PyObject* args, PyObject* kwargs)
5283{
5284 int err;
5285 u_int32_t flags=0;
5286 u_int32_t timeout = 0;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00005287 static char* kwnames[] = { "timeout", "flags", NULL };
Gregory P. Smithfe11d3e2003-03-27 17:23:29 +00005288
5289 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ii:set_timeout", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00005290 &timeout, &flags)) {
5291 return NULL;
Gregory P. Smithfe11d3e2003-03-27 17:23:29 +00005292 }
5293
5294 MYDB_BEGIN_ALLOW_THREADS;
5295 err = self->db_env->set_timeout(self->db_env, (db_timeout_t)timeout, flags);
5296 MYDB_END_ALLOW_THREADS;
5297
5298 RETURN_IF_ERR();
5299 RETURN_NONE();
5300}
Gregory P. Smithfe11d3e2003-03-27 17:23:29 +00005301
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005302static PyObject*
Gregory P. Smith6676f6e2003-08-28 21:50:30 +00005303DBEnv_set_shm_key(DBEnvObject* self, PyObject* args)
5304{
5305 int err;
5306 long shm_key = 0;
5307
5308 if (!PyArg_ParseTuple(args, "l:set_shm_key", &shm_key))
5309 return NULL;
5310 CHECK_ENV_NOT_CLOSED(self);
5311
5312 err = self->db_env->set_shm_key(self->db_env, shm_key);
5313 RETURN_IF_ERR();
5314 RETURN_NONE();
5315}
5316
Jesus Cea6557aac2010-03-22 14:22:26 +00005317static PyObject*
5318DBEnv_get_shm_key(DBEnvObject* self)
5319{
5320 int err;
5321 long shm_key;
5322
5323 CHECK_ENV_NOT_CLOSED(self);
5324
5325 MYDB_BEGIN_ALLOW_THREADS;
5326 err = self->db_env->get_shm_key(self->db_env, &shm_key);
5327 MYDB_END_ALLOW_THREADS;
5328
5329 RETURN_IF_ERR();
5330
5331 return NUMBER_FromLong(shm_key);
5332}
Jesus Cea6557aac2010-03-22 14:22:26 +00005333
5334#if (DBVER >= 46)
5335static PyObject*
5336DBEnv_set_cache_max(DBEnvObject* self, PyObject* args)
5337{
5338 int err, gbytes, bytes;
5339
5340 if (!PyArg_ParseTuple(args, "ii:set_cache_max",
5341 &gbytes, &bytes))
5342 return NULL;
5343 CHECK_ENV_NOT_CLOSED(self);
5344
5345 MYDB_BEGIN_ALLOW_THREADS;
5346 err = self->db_env->set_cache_max(self->db_env, gbytes, bytes);
5347 MYDB_END_ALLOW_THREADS;
5348 RETURN_IF_ERR();
5349 RETURN_NONE();
5350}
5351
5352static PyObject*
5353DBEnv_get_cache_max(DBEnvObject* self)
5354{
5355 int err;
5356 u_int32_t gbytes, bytes;
5357
5358 CHECK_ENV_NOT_CLOSED(self);
5359
5360 MYDB_BEGIN_ALLOW_THREADS;
5361 err = self->db_env->get_cache_max(self->db_env, &gbytes, &bytes);
5362 MYDB_END_ALLOW_THREADS;
5363
5364 RETURN_IF_ERR();
5365
5366 return Py_BuildValue("(ii)", gbytes, bytes);
5367}
5368#endif
5369
5370#if (DBVER >= 46)
5371static PyObject*
5372DBEnv_set_thread_count(DBEnvObject* self, PyObject* args)
5373{
5374 int err;
5375 u_int32_t count;
5376
5377 if (!PyArg_ParseTuple(args, "i:set_thread_count", &count))
5378 return NULL;
5379 CHECK_ENV_NOT_CLOSED(self);
5380
5381 MYDB_BEGIN_ALLOW_THREADS;
5382 err = self->db_env->set_thread_count(self->db_env, count);
5383 MYDB_END_ALLOW_THREADS;
5384 RETURN_IF_ERR();
5385 RETURN_NONE();
5386}
5387
5388static PyObject*
5389DBEnv_get_thread_count(DBEnvObject* self)
5390{
5391 int err;
5392 u_int32_t count;
5393
5394 CHECK_ENV_NOT_CLOSED(self);
5395
5396 MYDB_BEGIN_ALLOW_THREADS;
5397 err = self->db_env->get_thread_count(self->db_env, &count);
5398 MYDB_END_ALLOW_THREADS;
5399 RETURN_IF_ERR();
5400 return NUMBER_FromLong(count);
5401}
5402#endif
5403
Gregory P. Smith6676f6e2003-08-28 21:50:30 +00005404static PyObject*
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005405DBEnv_set_cachesize(DBEnvObject* self, PyObject* args)
5406{
5407 int err, gbytes=0, bytes=0, ncache=0;
5408
5409 if (!PyArg_ParseTuple(args, "ii|i:set_cachesize",
5410 &gbytes, &bytes, &ncache))
5411 return NULL;
5412 CHECK_ENV_NOT_CLOSED(self);
5413
5414 MYDB_BEGIN_ALLOW_THREADS;
5415 err = self->db_env->set_cachesize(self->db_env, gbytes, bytes, ncache);
5416 MYDB_END_ALLOW_THREADS;
5417 RETURN_IF_ERR();
5418 RETURN_NONE();
5419}
5420
Jesus Cea6557aac2010-03-22 14:22:26 +00005421static PyObject*
5422DBEnv_get_cachesize(DBEnvObject* self)
5423{
5424 int err;
5425 u_int32_t gbytes, bytes;
5426 int ncache;
5427
5428 CHECK_ENV_NOT_CLOSED(self);
5429
5430 MYDB_BEGIN_ALLOW_THREADS;
5431 err = self->db_env->get_cachesize(self->db_env, &gbytes, &bytes, &ncache);
5432 MYDB_END_ALLOW_THREADS;
5433
5434 RETURN_IF_ERR();
5435
5436 return Py_BuildValue("(iii)", gbytes, bytes, ncache);
5437}
Jesus Cea6557aac2010-03-22 14:22:26 +00005438
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005439
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005440static PyObject*
5441DBEnv_set_flags(DBEnvObject* self, PyObject* args)
5442{
5443 int err, flags=0, onoff=0;
5444
5445 if (!PyArg_ParseTuple(args, "ii:set_flags",
5446 &flags, &onoff))
5447 return NULL;
5448 CHECK_ENV_NOT_CLOSED(self);
5449
5450 MYDB_BEGIN_ALLOW_THREADS;
5451 err = self->db_env->set_flags(self->db_env, flags, onoff);
5452 MYDB_END_ALLOW_THREADS;
5453 RETURN_IF_ERR();
5454 RETURN_NONE();
5455}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005456
Jesus Cea6557aac2010-03-22 14:22:26 +00005457static PyObject*
5458DBEnv_get_flags(DBEnvObject* self)
5459{
5460 int err;
5461 u_int32_t flags;
5462
5463 CHECK_ENV_NOT_CLOSED(self);
5464
5465 MYDB_BEGIN_ALLOW_THREADS;
5466 err = self->db_env->get_flags(self->db_env, &flags);
5467 MYDB_END_ALLOW_THREADS;
5468 RETURN_IF_ERR();
5469 return NUMBER_FromLong(flags);
5470}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005471
Jesus Ceaca3939c2008-05-22 15:27:38 +00005472#if (DBVER >= 47)
5473static PyObject*
5474DBEnv_log_set_config(DBEnvObject* self, PyObject* args)
5475{
5476 int err, flags, onoff;
5477
5478 if (!PyArg_ParseTuple(args, "ii:log_set_config",
5479 &flags, &onoff))
5480 return NULL;
5481 CHECK_ENV_NOT_CLOSED(self);
5482
5483 MYDB_BEGIN_ALLOW_THREADS;
5484 err = self->db_env->log_set_config(self->db_env, flags, onoff);
5485 MYDB_END_ALLOW_THREADS;
5486 RETURN_IF_ERR();
5487 RETURN_NONE();
5488}
Jesus Cea6557aac2010-03-22 14:22:26 +00005489
5490static PyObject*
5491DBEnv_log_get_config(DBEnvObject* self, PyObject* args)
5492{
5493 int err, flag, onoff;
5494
5495 if (!PyArg_ParseTuple(args, "i:log_get_config", &flag))
5496 return NULL;
5497 CHECK_ENV_NOT_CLOSED(self);
5498
5499 MYDB_BEGIN_ALLOW_THREADS;
5500 err = self->db_env->log_get_config(self->db_env, flag, &onoff);
5501 MYDB_END_ALLOW_THREADS;
5502 RETURN_IF_ERR();
5503 return PyBool_FromLong(onoff);
5504}
Jesus Ceaca3939c2008-05-22 15:27:38 +00005505#endif /* DBVER >= 47 */
5506
Jesus Cea6557aac2010-03-22 14:22:26 +00005507#if (DBVER >= 44)
5508static PyObject*
5509DBEnv_mutex_set_max(DBEnvObject* self, PyObject* args)
5510{
5511 int err;
5512 int value;
5513
5514 if (!PyArg_ParseTuple(args, "i:mutex_set_max", &value))
5515 return NULL;
5516
5517 CHECK_ENV_NOT_CLOSED(self);
5518
5519 MYDB_BEGIN_ALLOW_THREADS;
5520 err = self->db_env->mutex_set_max(self->db_env, value);
5521 MYDB_END_ALLOW_THREADS;
5522
5523 RETURN_IF_ERR();
5524 RETURN_NONE();
5525}
5526
5527static PyObject*
5528DBEnv_mutex_get_max(DBEnvObject* self)
5529{
5530 int err;
5531 u_int32_t value;
5532
5533 CHECK_ENV_NOT_CLOSED(self);
5534
5535 MYDB_BEGIN_ALLOW_THREADS;
5536 err = self->db_env->mutex_get_max(self->db_env, &value);
5537 MYDB_END_ALLOW_THREADS;
5538
5539 RETURN_IF_ERR();
5540
5541 return NUMBER_FromLong(value);
5542}
5543
5544static PyObject*
5545DBEnv_mutex_set_align(DBEnvObject* self, PyObject* args)
5546{
5547 int err;
5548 int align;
5549
5550 if (!PyArg_ParseTuple(args, "i:mutex_set_align", &align))
5551 return NULL;
5552
5553 CHECK_ENV_NOT_CLOSED(self);
5554
5555 MYDB_BEGIN_ALLOW_THREADS;
5556 err = self->db_env->mutex_set_align(self->db_env, align);
5557 MYDB_END_ALLOW_THREADS;
5558
5559 RETURN_IF_ERR();
5560 RETURN_NONE();
5561}
5562
5563static PyObject*
5564DBEnv_mutex_get_align(DBEnvObject* self)
5565{
5566 int err;
5567 u_int32_t align;
5568
5569 CHECK_ENV_NOT_CLOSED(self);
5570
5571 MYDB_BEGIN_ALLOW_THREADS;
5572 err = self->db_env->mutex_get_align(self->db_env, &align);
5573 MYDB_END_ALLOW_THREADS;
5574
5575 RETURN_IF_ERR();
5576
5577 return NUMBER_FromLong(align);
5578}
5579
5580static PyObject*
5581DBEnv_mutex_set_increment(DBEnvObject* self, PyObject* args)
5582{
5583 int err;
5584 int increment;
5585
5586 if (!PyArg_ParseTuple(args, "i:mutex_set_increment", &increment))
5587 return NULL;
5588
5589 CHECK_ENV_NOT_CLOSED(self);
5590
5591 MYDB_BEGIN_ALLOW_THREADS;
5592 err = self->db_env->mutex_set_increment(self->db_env, increment);
5593 MYDB_END_ALLOW_THREADS;
5594
5595 RETURN_IF_ERR();
5596 RETURN_NONE();
5597}
5598
5599static PyObject*
5600DBEnv_mutex_get_increment(DBEnvObject* self)
5601{
5602 int err;
5603 u_int32_t increment;
5604
5605 CHECK_ENV_NOT_CLOSED(self);
5606
5607 MYDB_BEGIN_ALLOW_THREADS;
5608 err = self->db_env->mutex_get_increment(self->db_env, &increment);
5609 MYDB_END_ALLOW_THREADS;
5610
5611 RETURN_IF_ERR();
5612
5613 return NUMBER_FromLong(increment);
5614}
5615
5616static PyObject*
5617DBEnv_mutex_set_tas_spins(DBEnvObject* self, PyObject* args)
5618{
5619 int err;
5620 int tas_spins;
5621
5622 if (!PyArg_ParseTuple(args, "i:mutex_set_tas_spins", &tas_spins))
5623 return NULL;
5624
5625 CHECK_ENV_NOT_CLOSED(self);
5626
5627 MYDB_BEGIN_ALLOW_THREADS;
5628 err = self->db_env->mutex_set_tas_spins(self->db_env, tas_spins);
5629 MYDB_END_ALLOW_THREADS;
5630
5631 RETURN_IF_ERR();
5632 RETURN_NONE();
5633}
5634
5635static PyObject*
5636DBEnv_mutex_get_tas_spins(DBEnvObject* self)
5637{
5638 int err;
5639 u_int32_t tas_spins;
5640
5641 CHECK_ENV_NOT_CLOSED(self);
5642
5643 MYDB_BEGIN_ALLOW_THREADS;
5644 err = self->db_env->mutex_get_tas_spins(self->db_env, &tas_spins);
5645 MYDB_END_ALLOW_THREADS;
5646
5647 RETURN_IF_ERR();
5648
5649 return NUMBER_FromLong(tas_spins);
5650}
5651#endif
Jesus Ceaca3939c2008-05-22 15:27:38 +00005652
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005653static PyObject*
5654DBEnv_set_data_dir(DBEnvObject* self, PyObject* args)
5655{
5656 int err;
5657 char *dir;
5658
5659 if (!PyArg_ParseTuple(args, "s:set_data_dir", &dir))
5660 return NULL;
5661 CHECK_ENV_NOT_CLOSED(self);
5662
5663 MYDB_BEGIN_ALLOW_THREADS;
5664 err = self->db_env->set_data_dir(self->db_env, dir);
5665 MYDB_END_ALLOW_THREADS;
5666 RETURN_IF_ERR();
5667 RETURN_NONE();
5668}
5669
Jesus Cea6557aac2010-03-22 14:22:26 +00005670static PyObject*
5671DBEnv_get_data_dirs(DBEnvObject* self)
5672{
5673 int err;
5674 PyObject *tuple;
5675 PyObject *item;
5676 const char **dirpp;
5677 int size, i;
5678
5679 CHECK_ENV_NOT_CLOSED(self);
5680
5681 MYDB_BEGIN_ALLOW_THREADS;
5682 err = self->db_env->get_data_dirs(self->db_env, &dirpp);
5683 MYDB_END_ALLOW_THREADS;
5684
5685 RETURN_IF_ERR();
5686
5687 /*
5688 ** Calculate size. Python C API
5689 ** actually allows for tuple resizing,
5690 ** but this is simple enough.
5691 */
5692 for (size=0; *(dirpp+size) ; size++);
5693
5694 tuple = PyTuple_New(size);
5695 if (!tuple)
5696 return NULL;
5697
5698 for (i=0; i<size; i++) {
5699 item = PyBytes_FromString (*(dirpp+i));
5700 if (item == NULL) {
5701 Py_DECREF(tuple);
5702 tuple = NULL;
5703 break;
5704 }
5705 PyTuple_SET_ITEM(tuple, i, item);
5706 }
5707 return tuple;
5708}
Jesus Cea6557aac2010-03-22 14:22:26 +00005709
5710#if (DBVER >= 44)
5711static PyObject*
5712DBEnv_set_lg_filemode(DBEnvObject* self, PyObject* args)
5713{
5714 int err, filemode;
5715
5716 if (!PyArg_ParseTuple(args, "i:set_lg_filemode", &filemode))
5717 return NULL;
5718 CHECK_ENV_NOT_CLOSED(self);
5719
5720 MYDB_BEGIN_ALLOW_THREADS;
5721 err = self->db_env->set_lg_filemode(self->db_env, filemode);
5722 MYDB_END_ALLOW_THREADS;
5723 RETURN_IF_ERR();
5724 RETURN_NONE();
5725}
5726
5727static PyObject*
5728DBEnv_get_lg_filemode(DBEnvObject* self)
5729{
5730 int err, filemode;
5731
5732 CHECK_ENV_NOT_CLOSED(self);
5733
5734 MYDB_BEGIN_ALLOW_THREADS;
5735 err = self->db_env->get_lg_filemode(self->db_env, &filemode);
5736 MYDB_END_ALLOW_THREADS;
5737 RETURN_IF_ERR();
5738 return NUMBER_FromLong(filemode);
5739}
5740#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005741
5742static PyObject*
5743DBEnv_set_lg_bsize(DBEnvObject* self, PyObject* args)
5744{
5745 int err, lg_bsize;
5746
5747 if (!PyArg_ParseTuple(args, "i:set_lg_bsize", &lg_bsize))
5748 return NULL;
5749 CHECK_ENV_NOT_CLOSED(self);
5750
5751 MYDB_BEGIN_ALLOW_THREADS;
5752 err = self->db_env->set_lg_bsize(self->db_env, lg_bsize);
5753 MYDB_END_ALLOW_THREADS;
5754 RETURN_IF_ERR();
5755 RETURN_NONE();
5756}
5757
Jesus Cea6557aac2010-03-22 14:22:26 +00005758static PyObject*
5759DBEnv_get_lg_bsize(DBEnvObject* self)
5760{
5761 int err;
5762 u_int32_t lg_bsize;
5763
5764 CHECK_ENV_NOT_CLOSED(self);
5765
5766 MYDB_BEGIN_ALLOW_THREADS;
5767 err = self->db_env->get_lg_bsize(self->db_env, &lg_bsize);
5768 MYDB_END_ALLOW_THREADS;
5769 RETURN_IF_ERR();
5770 return NUMBER_FromLong(lg_bsize);
5771}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005772
5773static PyObject*
5774DBEnv_set_lg_dir(DBEnvObject* self, PyObject* args)
5775{
5776 int err;
5777 char *dir;
5778
5779 if (!PyArg_ParseTuple(args, "s:set_lg_dir", &dir))
5780 return NULL;
5781 CHECK_ENV_NOT_CLOSED(self);
5782
5783 MYDB_BEGIN_ALLOW_THREADS;
5784 err = self->db_env->set_lg_dir(self->db_env, dir);
5785 MYDB_END_ALLOW_THREADS;
5786 RETURN_IF_ERR();
5787 RETURN_NONE();
5788}
5789
Jesus Cea6557aac2010-03-22 14:22:26 +00005790static PyObject*
5791DBEnv_get_lg_dir(DBEnvObject* self)
5792{
5793 int err;
5794 const char *dirp;
5795
5796 CHECK_ENV_NOT_CLOSED(self);
5797
5798 MYDB_BEGIN_ALLOW_THREADS;
5799 err = self->db_env->get_lg_dir(self->db_env, &dirp);
5800 MYDB_END_ALLOW_THREADS;
5801 RETURN_IF_ERR();
5802 return PyBytes_FromString(dirp);
5803}
Jesus Cea6557aac2010-03-22 14:22:26 +00005804
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005805static PyObject*
5806DBEnv_set_lg_max(DBEnvObject* self, PyObject* args)
5807{
5808 int err, lg_max;
5809
5810 if (!PyArg_ParseTuple(args, "i:set_lg_max", &lg_max))
5811 return NULL;
5812 CHECK_ENV_NOT_CLOSED(self);
5813
5814 MYDB_BEGIN_ALLOW_THREADS;
5815 err = self->db_env->set_lg_max(self->db_env, lg_max);
5816 MYDB_END_ALLOW_THREADS;
5817 RETURN_IF_ERR();
5818 RETURN_NONE();
5819}
5820
Jesus Ceaef9764f2008-05-13 18:45:46 +00005821static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00005822DBEnv_get_lg_max(DBEnvObject* self)
Jesus Ceaef9764f2008-05-13 18:45:46 +00005823{
5824 int err;
5825 u_int32_t lg_max;
5826
Jesus Ceaef9764f2008-05-13 18:45:46 +00005827 CHECK_ENV_NOT_CLOSED(self);
5828
5829 MYDB_BEGIN_ALLOW_THREADS;
5830 err = self->db_env->get_lg_max(self->db_env, &lg_max);
5831 MYDB_END_ALLOW_THREADS;
5832 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00005833 return NUMBER_FromLong(lg_max);
Jesus Ceaef9764f2008-05-13 18:45:46 +00005834}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005835
5836static PyObject*
Gregory P. Smithe9477062005-06-04 06:46:59 +00005837DBEnv_set_lg_regionmax(DBEnvObject* self, PyObject* args)
5838{
5839 int err, lg_max;
5840
5841 if (!PyArg_ParseTuple(args, "i:set_lg_regionmax", &lg_max))
5842 return NULL;
5843 CHECK_ENV_NOT_CLOSED(self);
5844
5845 MYDB_BEGIN_ALLOW_THREADS;
5846 err = self->db_env->set_lg_regionmax(self->db_env, lg_max);
5847 MYDB_END_ALLOW_THREADS;
5848 RETURN_IF_ERR();
5849 RETURN_NONE();
5850}
5851
Jesus Cea6557aac2010-03-22 14:22:26 +00005852static PyObject*
5853DBEnv_get_lg_regionmax(DBEnvObject* self)
5854{
5855 int err;
5856 u_int32_t lg_regionmax;
5857
5858 CHECK_ENV_NOT_CLOSED(self);
5859
5860 MYDB_BEGIN_ALLOW_THREADS;
5861 err = self->db_env->get_lg_regionmax(self->db_env, &lg_regionmax);
5862 MYDB_END_ALLOW_THREADS;
5863 RETURN_IF_ERR();
5864 return NUMBER_FromLong(lg_regionmax);
5865}
Jesus Cea6557aac2010-03-22 14:22:26 +00005866
5867#if (DBVER >= 47)
5868static PyObject*
5869DBEnv_set_lk_partitions(DBEnvObject* self, PyObject* args)
5870{
5871 int err, lk_partitions;
5872
5873 if (!PyArg_ParseTuple(args, "i:set_lk_partitions", &lk_partitions))
5874 return NULL;
5875 CHECK_ENV_NOT_CLOSED(self);
5876
5877 MYDB_BEGIN_ALLOW_THREADS;
5878 err = self->db_env->set_lk_partitions(self->db_env, lk_partitions);
5879 MYDB_END_ALLOW_THREADS;
5880 RETURN_IF_ERR();
5881 RETURN_NONE();
5882}
5883
5884static PyObject*
5885DBEnv_get_lk_partitions(DBEnvObject* self)
5886{
5887 int err;
5888 u_int32_t lk_partitions;
5889
5890 CHECK_ENV_NOT_CLOSED(self);
5891
5892 MYDB_BEGIN_ALLOW_THREADS;
5893 err = self->db_env->get_lk_partitions(self->db_env, &lk_partitions);
5894 MYDB_END_ALLOW_THREADS;
5895 RETURN_IF_ERR();
5896 return NUMBER_FromLong(lk_partitions);
5897}
5898#endif
Gregory P. Smithe9477062005-06-04 06:46:59 +00005899
5900static PyObject*
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005901DBEnv_set_lk_detect(DBEnvObject* self, PyObject* args)
5902{
5903 int err, lk_detect;
5904
5905 if (!PyArg_ParseTuple(args, "i:set_lk_detect", &lk_detect))
5906 return NULL;
5907 CHECK_ENV_NOT_CLOSED(self);
5908
5909 MYDB_BEGIN_ALLOW_THREADS;
5910 err = self->db_env->set_lk_detect(self->db_env, lk_detect);
5911 MYDB_END_ALLOW_THREADS;
5912 RETURN_IF_ERR();
5913 RETURN_NONE();
5914}
5915
Jesus Cea6557aac2010-03-22 14:22:26 +00005916static PyObject*
5917DBEnv_get_lk_detect(DBEnvObject* self)
5918{
5919 int err;
5920 u_int32_t lk_detect;
5921
5922 CHECK_ENV_NOT_CLOSED(self);
5923
5924 MYDB_BEGIN_ALLOW_THREADS;
5925 err = self->db_env->get_lk_detect(self->db_env, &lk_detect);
5926 MYDB_END_ALLOW_THREADS;
5927 RETURN_IF_ERR();
5928 return NUMBER_FromLong(lk_detect);
5929}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005930
Gregory P. Smith8b96a352007-01-05 01:59:42 +00005931#if (DBVER < 45)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005932static PyObject*
5933DBEnv_set_lk_max(DBEnvObject* self, PyObject* args)
5934{
5935 int err, max;
5936
5937 if (!PyArg_ParseTuple(args, "i:set_lk_max", &max))
5938 return NULL;
5939 CHECK_ENV_NOT_CLOSED(self);
5940
5941 MYDB_BEGIN_ALLOW_THREADS;
5942 err = self->db_env->set_lk_max(self->db_env, max);
5943 MYDB_END_ALLOW_THREADS;
5944 RETURN_IF_ERR();
5945 RETURN_NONE();
5946}
Gregory P. Smith8b96a352007-01-05 01:59:42 +00005947#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005948
5949
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005950
5951static PyObject*
5952DBEnv_set_lk_max_locks(DBEnvObject* self, PyObject* args)
5953{
5954 int err, max;
5955
5956 if (!PyArg_ParseTuple(args, "i:set_lk_max_locks", &max))
5957 return NULL;
5958 CHECK_ENV_NOT_CLOSED(self);
5959
5960 MYDB_BEGIN_ALLOW_THREADS;
5961 err = self->db_env->set_lk_max_locks(self->db_env, max);
5962 MYDB_END_ALLOW_THREADS;
5963 RETURN_IF_ERR();
5964 RETURN_NONE();
5965}
5966
Jesus Cea6557aac2010-03-22 14:22:26 +00005967static PyObject*
5968DBEnv_get_lk_max_locks(DBEnvObject* self)
5969{
5970 int err;
5971 u_int32_t lk_max;
5972
5973 CHECK_ENV_NOT_CLOSED(self);
5974
5975 MYDB_BEGIN_ALLOW_THREADS;
5976 err = self->db_env->get_lk_max_locks(self->db_env, &lk_max);
5977 MYDB_END_ALLOW_THREADS;
5978 RETURN_IF_ERR();
5979 return NUMBER_FromLong(lk_max);
5980}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005981
5982static PyObject*
5983DBEnv_set_lk_max_lockers(DBEnvObject* self, PyObject* args)
5984{
5985 int err, max;
5986
5987 if (!PyArg_ParseTuple(args, "i:set_lk_max_lockers", &max))
5988 return NULL;
5989 CHECK_ENV_NOT_CLOSED(self);
5990
5991 MYDB_BEGIN_ALLOW_THREADS;
5992 err = self->db_env->set_lk_max_lockers(self->db_env, max);
5993 MYDB_END_ALLOW_THREADS;
5994 RETURN_IF_ERR();
5995 RETURN_NONE();
5996}
5997
Jesus Cea6557aac2010-03-22 14:22:26 +00005998static PyObject*
5999DBEnv_get_lk_max_lockers(DBEnvObject* self)
6000{
6001 int err;
6002 u_int32_t lk_max;
6003
6004 CHECK_ENV_NOT_CLOSED(self);
6005
6006 MYDB_BEGIN_ALLOW_THREADS;
6007 err = self->db_env->get_lk_max_lockers(self->db_env, &lk_max);
6008 MYDB_END_ALLOW_THREADS;
6009 RETURN_IF_ERR();
6010 return NUMBER_FromLong(lk_max);
6011}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006012
6013static PyObject*
6014DBEnv_set_lk_max_objects(DBEnvObject* self, PyObject* args)
6015{
6016 int err, max;
6017
6018 if (!PyArg_ParseTuple(args, "i:set_lk_max_objects", &max))
6019 return NULL;
6020 CHECK_ENV_NOT_CLOSED(self);
6021
6022 MYDB_BEGIN_ALLOW_THREADS;
6023 err = self->db_env->set_lk_max_objects(self->db_env, max);
6024 MYDB_END_ALLOW_THREADS;
6025 RETURN_IF_ERR();
6026 RETURN_NONE();
6027}
6028
Jesus Cea6557aac2010-03-22 14:22:26 +00006029static PyObject*
6030DBEnv_get_lk_max_objects(DBEnvObject* self)
6031{
6032 int err;
6033 u_int32_t lk_max;
6034
6035 CHECK_ENV_NOT_CLOSED(self);
6036
6037 MYDB_BEGIN_ALLOW_THREADS;
6038 err = self->db_env->get_lk_max_objects(self->db_env, &lk_max);
6039 MYDB_END_ALLOW_THREADS;
6040 RETURN_IF_ERR();
6041 return NUMBER_FromLong(lk_max);
6042}
Jesus Cea6557aac2010-03-22 14:22:26 +00006043
Jesus Cea6557aac2010-03-22 14:22:26 +00006044static PyObject*
6045DBEnv_get_mp_mmapsize(DBEnvObject* self)
6046{
6047 int err;
6048 size_t mmapsize;
6049
6050 CHECK_ENV_NOT_CLOSED(self);
6051
6052 MYDB_BEGIN_ALLOW_THREADS;
6053 err = self->db_env->get_mp_mmapsize(self->db_env, &mmapsize);
6054 MYDB_END_ALLOW_THREADS;
6055 RETURN_IF_ERR();
6056 return NUMBER_FromLong(mmapsize);
6057}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006058
6059static PyObject*
6060DBEnv_set_mp_mmapsize(DBEnvObject* self, PyObject* args)
6061{
6062 int err, mp_mmapsize;
6063
6064 if (!PyArg_ParseTuple(args, "i:set_mp_mmapsize", &mp_mmapsize))
6065 return NULL;
6066 CHECK_ENV_NOT_CLOSED(self);
6067
6068 MYDB_BEGIN_ALLOW_THREADS;
6069 err = self->db_env->set_mp_mmapsize(self->db_env, mp_mmapsize);
6070 MYDB_END_ALLOW_THREADS;
6071 RETURN_IF_ERR();
6072 RETURN_NONE();
6073}
6074
6075
6076static PyObject*
6077DBEnv_set_tmp_dir(DBEnvObject* self, PyObject* args)
6078{
6079 int err;
6080 char *dir;
6081
6082 if (!PyArg_ParseTuple(args, "s:set_tmp_dir", &dir))
6083 return NULL;
6084 CHECK_ENV_NOT_CLOSED(self);
6085
6086 MYDB_BEGIN_ALLOW_THREADS;
6087 err = self->db_env->set_tmp_dir(self->db_env, dir);
6088 MYDB_END_ALLOW_THREADS;
6089 RETURN_IF_ERR();
6090 RETURN_NONE();
6091}
6092
Jesus Cea6557aac2010-03-22 14:22:26 +00006093static PyObject*
6094DBEnv_get_tmp_dir(DBEnvObject* self)
6095{
6096 int err;
6097 const char *dirpp;
6098
6099 CHECK_ENV_NOT_CLOSED(self);
6100
6101 MYDB_BEGIN_ALLOW_THREADS;
6102 err = self->db_env->get_tmp_dir(self->db_env, &dirpp);
6103 MYDB_END_ALLOW_THREADS;
6104
6105 RETURN_IF_ERR();
6106
6107 return PyBytes_FromString(dirpp);
6108}
Jesus Cea6557aac2010-03-22 14:22:26 +00006109
Jesus Ceaef9764f2008-05-13 18:45:46 +00006110static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00006111DBEnv_txn_recover(DBEnvObject* self)
Jesus Ceaef9764f2008-05-13 18:45:46 +00006112{
6113 int flags = DB_FIRST;
6114 int err, i;
6115 PyObject *list, *tuple, *gid;
6116 DBTxnObject *txn;
6117#define PREPLIST_LEN 16
6118 DB_PREPLIST preplist[PREPLIST_LEN];
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07006119#if (DBVER < 48) || (DBVER >= 52)
Jesus Ceaef9764f2008-05-13 18:45:46 +00006120 long retp;
Matthias Klose54cc5392010-03-15 12:46:18 +00006121#else
6122 u_int32_t retp;
6123#endif
Jesus Ceaef9764f2008-05-13 18:45:46 +00006124
Jesus Ceaef9764f2008-05-13 18:45:46 +00006125 CHECK_ENV_NOT_CLOSED(self);
6126
6127 list=PyList_New(0);
6128 if (!list)
6129 return NULL;
6130 while (!0) {
6131 MYDB_BEGIN_ALLOW_THREADS
6132 err=self->db_env->txn_recover(self->db_env,
6133 preplist, PREPLIST_LEN, &retp, flags);
6134#undef PREPLIST_LEN
6135 MYDB_END_ALLOW_THREADS
6136 if (err) {
6137 Py_DECREF(list);
6138 RETURN_IF_ERR();
6139 }
6140 if (!retp) break;
6141 flags=DB_NEXT; /* Prepare for next loop pass */
6142 for (i=0; i<retp; i++) {
Christian Heimes593daf52008-05-26 12:51:38 +00006143 gid=PyBytes_FromStringAndSize((char *)(preplist[i].gid),
Matthias Klose54cc5392010-03-15 12:46:18 +00006144 DB_GID_SIZE);
Jesus Ceaef9764f2008-05-13 18:45:46 +00006145 if (!gid) {
6146 Py_DECREF(list);
6147 return NULL;
6148 }
Jesus Cea6557aac2010-03-22 14:22:26 +00006149 txn=newDBTxnObject(self, NULL, preplist[i].txn, 0);
Jesus Ceaef9764f2008-05-13 18:45:46 +00006150 if (!txn) {
6151 Py_DECREF(list);
6152 Py_DECREF(gid);
6153 return NULL;
6154 }
6155 txn->flag_prepare=1; /* Recover state */
6156 tuple=PyTuple_New(2);
6157 if (!tuple) {
6158 Py_DECREF(list);
6159 Py_DECREF(gid);
6160 Py_DECREF(txn);
6161 return NULL;
6162 }
6163 if (PyTuple_SetItem(tuple, 0, gid)) {
6164 Py_DECREF(list);
6165 Py_DECREF(gid);
6166 Py_DECREF(txn);
6167 Py_DECREF(tuple);
6168 return NULL;
6169 }
6170 if (PyTuple_SetItem(tuple, 1, (PyObject *)txn)) {
6171 Py_DECREF(list);
6172 Py_DECREF(txn);
6173 Py_DECREF(tuple); /* This delete the "gid" also */
6174 return NULL;
6175 }
6176 if (PyList_Append(list, tuple)) {
6177 Py_DECREF(list);
6178 Py_DECREF(tuple);/* This delete the "gid" and the "txn" also */
6179 return NULL;
6180 }
6181 Py_DECREF(tuple);
6182 }
6183 }
6184 return list;
6185}
Jesus Ceaef9764f2008-05-13 18:45:46 +00006186
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006187static PyObject*
6188DBEnv_txn_begin(DBEnvObject* self, PyObject* args, PyObject* kwargs)
6189{
6190 int flags = 0;
6191 PyObject* txnobj = NULL;
6192 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00006193 static char* kwnames[] = { "parent", "flags", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006194
6195 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Oi:txn_begin", kwnames,
6196 &txnobj, &flags))
6197 return NULL;
6198
6199 if (!checkTxnObj(txnobj, &txn))
6200 return NULL;
6201 CHECK_ENV_NOT_CLOSED(self);
6202
Jesus Ceaef9764f2008-05-13 18:45:46 +00006203 return (PyObject*)newDBTxnObject(self, (DBTxnObject *)txnobj, NULL, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006204}
6205
6206
6207static PyObject*
6208DBEnv_txn_checkpoint(DBEnvObject* self, PyObject* args)
6209{
6210 int err, kbyte=0, min=0, flags=0;
6211
6212 if (!PyArg_ParseTuple(args, "|iii:txn_checkpoint", &kbyte, &min, &flags))
6213 return NULL;
6214 CHECK_ENV_NOT_CLOSED(self);
6215
6216 MYDB_BEGIN_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006217 err = self->db_env->txn_checkpoint(self->db_env, kbyte, min, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006218 MYDB_END_ALLOW_THREADS;
6219 RETURN_IF_ERR();
6220 RETURN_NONE();
6221}
6222
Jesus Cea6557aac2010-03-22 14:22:26 +00006223static PyObject*
6224DBEnv_get_tx_max(DBEnvObject* self)
6225{
6226 int err;
6227 u_int32_t max;
6228
6229 CHECK_ENV_NOT_CLOSED(self);
6230
6231 MYDB_BEGIN_ALLOW_THREADS;
6232 err = self->db_env->get_tx_max(self->db_env, &max);
6233 MYDB_END_ALLOW_THREADS;
6234 RETURN_IF_ERR();
6235 return PyLong_FromUnsignedLong(max);
6236}
Jesus Cea6557aac2010-03-22 14:22:26 +00006237
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006238static PyObject*
6239DBEnv_set_tx_max(DBEnvObject* self, PyObject* args)
6240{
6241 int err, max;
6242
6243 if (!PyArg_ParseTuple(args, "i:set_tx_max", &max))
6244 return NULL;
6245 CHECK_ENV_NOT_CLOSED(self);
6246
Jesus Cea6557aac2010-03-22 14:22:26 +00006247 MYDB_BEGIN_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006248 err = self->db_env->set_tx_max(self->db_env, max);
Jesus Cea6557aac2010-03-22 14:22:26 +00006249 MYDB_END_ALLOW_THREADS;
Gregory P. Smith8a474042006-01-27 07:05:40 +00006250 RETURN_IF_ERR();
6251 RETURN_NONE();
6252}
6253
Jesus Cea6557aac2010-03-22 14:22:26 +00006254static PyObject*
6255DBEnv_get_tx_timestamp(DBEnvObject* self)
6256{
6257 int err;
6258 time_t timestamp;
6259
6260 CHECK_ENV_NOT_CLOSED(self);
6261
6262 MYDB_BEGIN_ALLOW_THREADS;
6263 err = self->db_env->get_tx_timestamp(self->db_env, &timestamp);
6264 MYDB_END_ALLOW_THREADS;
6265 RETURN_IF_ERR();
6266 return NUMBER_FromLong(timestamp);
6267}
Jesus Cea6557aac2010-03-22 14:22:26 +00006268
Gregory P. Smith8a474042006-01-27 07:05:40 +00006269static PyObject*
6270DBEnv_set_tx_timestamp(DBEnvObject* self, PyObject* args)
6271{
6272 int err;
Thomas Wouters9d63cca2006-03-01 01:01:55 +00006273 long stamp;
6274 time_t timestamp;
Gregory P. Smith8a474042006-01-27 07:05:40 +00006275
Thomas Wouters9d63cca2006-03-01 01:01:55 +00006276 if (!PyArg_ParseTuple(args, "l:set_tx_timestamp", &stamp))
Gregory P. Smith8a474042006-01-27 07:05:40 +00006277 return NULL;
6278 CHECK_ENV_NOT_CLOSED(self);
Thomas Wouters9d63cca2006-03-01 01:01:55 +00006279 timestamp = (time_t)stamp;
Jesus Cea6557aac2010-03-22 14:22:26 +00006280 MYDB_BEGIN_ALLOW_THREADS;
Thomas Wouters9d63cca2006-03-01 01:01:55 +00006281 err = self->db_env->set_tx_timestamp(self->db_env, &timestamp);
Jesus Cea6557aac2010-03-22 14:22:26 +00006282 MYDB_END_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006283 RETURN_IF_ERR();
6284 RETURN_NONE();
6285}
6286
6287
6288static PyObject*
6289DBEnv_lock_detect(DBEnvObject* self, PyObject* args)
6290{
6291 int err, atype, flags=0;
6292 int aborted = 0;
6293
6294 if (!PyArg_ParseTuple(args, "i|i:lock_detect", &atype, &flags))
6295 return NULL;
6296 CHECK_ENV_NOT_CLOSED(self);
6297
6298 MYDB_BEGIN_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006299 err = self->db_env->lock_detect(self->db_env, flags, atype, &aborted);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006300 MYDB_END_ALLOW_THREADS;
6301 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00006302 return NUMBER_FromLong(aborted);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006303}
6304
6305
6306static PyObject*
6307DBEnv_lock_get(DBEnvObject* self, PyObject* args)
6308{
6309 int flags=0;
6310 int locker, lock_mode;
6311 DBT obj;
6312 PyObject* objobj;
6313
6314 if (!PyArg_ParseTuple(args, "iOi|i:lock_get", &locker, &objobj, &lock_mode, &flags))
6315 return NULL;
6316
6317
6318 if (!make_dbt(objobj, &obj))
6319 return NULL;
6320
6321 return (PyObject*)newDBLockObject(self, locker, &obj, lock_mode, flags);
6322}
6323
6324
6325static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00006326DBEnv_lock_id(DBEnvObject* self)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006327{
6328 int err;
6329 u_int32_t theID;
6330
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006331 CHECK_ENV_NOT_CLOSED(self);
6332 MYDB_BEGIN_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006333 err = self->db_env->lock_id(self->db_env, &theID);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006334 MYDB_END_ALLOW_THREADS;
6335 RETURN_IF_ERR();
6336
Jesus Ceac5a11fa2008-07-23 11:38:42 +00006337 return NUMBER_FromLong((long)theID);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006338}
6339
Gregory P. Smithac11e022007-11-05 02:56:31 +00006340static PyObject*
6341DBEnv_lock_id_free(DBEnvObject* self, PyObject* args)
6342{
6343 int err;
6344 u_int32_t theID;
6345
6346 if (!PyArg_ParseTuple(args, "I:lock_id_free", &theID))
6347 return NULL;
6348
6349 CHECK_ENV_NOT_CLOSED(self);
6350 MYDB_BEGIN_ALLOW_THREADS;
6351 err = self->db_env->lock_id_free(self->db_env, theID);
6352 MYDB_END_ALLOW_THREADS;
6353 RETURN_IF_ERR();
6354 RETURN_NONE();
6355}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006356
6357static PyObject*
6358DBEnv_lock_put(DBEnvObject* self, PyObject* args)
6359{
6360 int err;
6361 DBLockObject* dblockobj;
6362
6363 if (!PyArg_ParseTuple(args, "O!:lock_put", &DBLock_Type, &dblockobj))
6364 return NULL;
6365
6366 CHECK_ENV_NOT_CLOSED(self);
6367 MYDB_BEGIN_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006368 err = self->db_env->lock_put(self->db_env, &dblockobj->lock);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006369 MYDB_END_ALLOW_THREADS;
6370 RETURN_IF_ERR();
6371 RETURN_NONE();
6372}
6373
Gregory P. Smithdb8a8072006-06-05 01:56:15 +00006374#if (DBVER >= 44)
6375static PyObject*
Jesus Cea6557aac2010-03-22 14:22:26 +00006376DBEnv_fileid_reset(DBEnvObject* self, PyObject* args, PyObject* kwargs)
6377{
6378 int err;
6379 char *file;
6380 u_int32_t flags = 0;
6381 static char* kwnames[] = { "file", "flags", NULL};
6382
6383 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "z|i:fileid_reset", kwnames,
6384 &file, &flags))
6385 return NULL;
6386 CHECK_ENV_NOT_CLOSED(self);
6387
6388 MYDB_BEGIN_ALLOW_THREADS;
6389 err = self->db_env->fileid_reset(self->db_env, file, flags);
6390 MYDB_END_ALLOW_THREADS;
6391 RETURN_IF_ERR();
6392 RETURN_NONE();
6393}
6394
6395static PyObject*
Gregory P. Smithdb8a8072006-06-05 01:56:15 +00006396DBEnv_lsn_reset(DBEnvObject* self, PyObject* args, PyObject* kwargs)
6397{
6398 int err;
6399 char *file;
6400 u_int32_t flags = 0;
6401 static char* kwnames[] = { "file", "flags", NULL};
6402
6403 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "z|i:lsn_reset", kwnames,
6404 &file, &flags))
6405 return NULL;
6406 CHECK_ENV_NOT_CLOSED(self);
6407
6408 MYDB_BEGIN_ALLOW_THREADS;
6409 err = self->db_env->lsn_reset(self->db_env, file, flags);
6410 MYDB_END_ALLOW_THREADS;
6411 RETURN_IF_ERR();
6412 RETURN_NONE();
6413}
6414#endif /* DBVER >= 4.4 */
6415
Jesus Cea6557aac2010-03-22 14:22:26 +00006416
Jesus Cea6557aac2010-03-22 14:22:26 +00006417static PyObject*
6418DBEnv_stat_print(DBEnvObject* self, PyObject* args, PyObject *kwargs)
6419{
6420 int err;
6421 int flags=0;
6422 static char* kwnames[] = { "flags", NULL };
6423
6424 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:stat_print",
6425 kwnames, &flags))
6426 {
6427 return NULL;
6428 }
6429 CHECK_ENV_NOT_CLOSED(self);
6430 MYDB_BEGIN_ALLOW_THREADS;
6431 err = self->db_env->stat_print(self->db_env, flags);
6432 MYDB_END_ALLOW_THREADS;
6433 RETURN_IF_ERR();
6434 RETURN_NONE();
6435}
Jesus Cea6557aac2010-03-22 14:22:26 +00006436
6437
Gregory P. Smith76a82e82006-06-05 01:39:52 +00006438static PyObject*
6439DBEnv_log_stat(DBEnvObject* self, PyObject* args)
6440{
6441 int err;
6442 DB_LOG_STAT* statp = NULL;
6443 PyObject* d = NULL;
6444 u_int32_t flags = 0;
6445
6446 if (!PyArg_ParseTuple(args, "|i:log_stat", &flags))
6447 return NULL;
6448 CHECK_ENV_NOT_CLOSED(self);
6449
6450 MYDB_BEGIN_ALLOW_THREADS;
6451 err = self->db_env->log_stat(self->db_env, &statp, flags);
6452 MYDB_END_ALLOW_THREADS;
6453 RETURN_IF_ERR();
6454
6455 /* Turn the stat structure into a dictionary */
6456 d = PyDict_New();
6457 if (d == NULL) {
6458 if (statp)
6459 free(statp);
6460 return NULL;
6461 }
6462
6463#define MAKE_ENTRY(name) _addIntToDict(d, #name, statp->st_##name)
6464
6465 MAKE_ENTRY(magic);
6466 MAKE_ENTRY(version);
6467 MAKE_ENTRY(mode);
6468 MAKE_ENTRY(lg_bsize);
6469#if (DBVER >= 44)
6470 MAKE_ENTRY(lg_size);
6471 MAKE_ENTRY(record);
6472#endif
Gregory P. Smith76a82e82006-06-05 01:39:52 +00006473 MAKE_ENTRY(w_mbytes);
6474 MAKE_ENTRY(w_bytes);
6475 MAKE_ENTRY(wc_mbytes);
6476 MAKE_ENTRY(wc_bytes);
6477 MAKE_ENTRY(wcount);
6478 MAKE_ENTRY(wcount_fill);
6479#if (DBVER >= 44)
6480 MAKE_ENTRY(rcount);
6481#endif
6482 MAKE_ENTRY(scount);
6483 MAKE_ENTRY(cur_file);
6484 MAKE_ENTRY(cur_offset);
6485 MAKE_ENTRY(disk_file);
6486 MAKE_ENTRY(disk_offset);
6487 MAKE_ENTRY(maxcommitperflush);
6488 MAKE_ENTRY(mincommitperflush);
6489 MAKE_ENTRY(regsize);
6490 MAKE_ENTRY(region_wait);
6491 MAKE_ENTRY(region_nowait);
6492
6493#undef MAKE_ENTRY
6494 free(statp);
6495 return d;
6496} /* DBEnv_log_stat */
Gregory P. Smith76a82e82006-06-05 01:39:52 +00006497
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006498
Jesus Cea6557aac2010-03-22 14:22:26 +00006499static PyObject*
6500DBEnv_log_stat_print(DBEnvObject* self, PyObject* args, PyObject *kwargs)
6501{
6502 int err;
6503 int flags=0;
6504 static char* kwnames[] = { "flags", NULL };
6505
6506 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:log_stat_print",
6507 kwnames, &flags))
6508 {
6509 return NULL;
6510 }
6511 CHECK_ENV_NOT_CLOSED(self);
6512 MYDB_BEGIN_ALLOW_THREADS;
6513 err = self->db_env->log_stat_print(self->db_env, flags);
6514 MYDB_END_ALLOW_THREADS;
6515 RETURN_IF_ERR();
6516 RETURN_NONE();
6517}
Jesus Cea6557aac2010-03-22 14:22:26 +00006518
6519
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006520static PyObject*
6521DBEnv_lock_stat(DBEnvObject* self, PyObject* args)
6522{
6523 int err;
6524 DB_LOCK_STAT* sp;
6525 PyObject* d = NULL;
Martin v. Löwisb2c7aff2002-11-23 11:26:07 +00006526 u_int32_t flags = 0;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006527
6528 if (!PyArg_ParseTuple(args, "|i:lock_stat", &flags))
6529 return NULL;
6530 CHECK_ENV_NOT_CLOSED(self);
6531
6532 MYDB_BEGIN_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006533 err = self->db_env->lock_stat(self->db_env, &sp, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006534 MYDB_END_ALLOW_THREADS;
6535 RETURN_IF_ERR();
6536
6537 /* Turn the stat structure into a dictionary */
6538 d = PyDict_New();
6539 if (d == NULL) {
6540 free(sp);
6541 return NULL;
6542 }
6543
6544#define MAKE_ENTRY(name) _addIntToDict(d, #name, sp->st_##name)
6545
Jesus Ceaef9764f2008-05-13 18:45:46 +00006546 MAKE_ENTRY(id);
6547 MAKE_ENTRY(cur_maxid);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006548 MAKE_ENTRY(nmodes);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006549 MAKE_ENTRY(maxlocks);
6550 MAKE_ENTRY(maxlockers);
6551 MAKE_ENTRY(maxobjects);
6552 MAKE_ENTRY(nlocks);
6553 MAKE_ENTRY(maxnlocks);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006554 MAKE_ENTRY(nlockers);
6555 MAKE_ENTRY(maxnlockers);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006556 MAKE_ENTRY(nobjects);
6557 MAKE_ENTRY(maxnobjects);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006558 MAKE_ENTRY(nrequests);
6559 MAKE_ENTRY(nreleases);
Jesus Ceaef9764f2008-05-13 18:45:46 +00006560#if (DBVER >= 44)
6561 MAKE_ENTRY(nupgrade);
6562 MAKE_ENTRY(ndowngrade);
6563#endif
Gregory P. Smith29602d22006-01-24 09:46:48 +00006564#if (DBVER < 44)
6565 MAKE_ENTRY(nnowaits); /* these were renamed in 4.4 */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006566 MAKE_ENTRY(nconflicts);
Gregory P. Smith29602d22006-01-24 09:46:48 +00006567#else
6568 MAKE_ENTRY(lock_nowait);
6569 MAKE_ENTRY(lock_wait);
6570#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006571 MAKE_ENTRY(ndeadlocks);
Jesus Ceaef9764f2008-05-13 18:45:46 +00006572 MAKE_ENTRY(locktimeout);
6573 MAKE_ENTRY(txntimeout);
Jesus Ceaef9764f2008-05-13 18:45:46 +00006574 MAKE_ENTRY(nlocktimeouts);
6575 MAKE_ENTRY(ntxntimeouts);
Jesus Ceaef9764f2008-05-13 18:45:46 +00006576#if (DBVER >= 46)
6577 MAKE_ENTRY(objs_wait);
6578 MAKE_ENTRY(objs_nowait);
6579 MAKE_ENTRY(lockers_wait);
6580 MAKE_ENTRY(lockers_nowait);
Jesus Ceaca3939c2008-05-22 15:27:38 +00006581#if (DBVER >= 47)
6582 MAKE_ENTRY(lock_wait);
6583 MAKE_ENTRY(lock_nowait);
6584#else
Jesus Ceaef9764f2008-05-13 18:45:46 +00006585 MAKE_ENTRY(locks_wait);
6586 MAKE_ENTRY(locks_nowait);
Jesus Ceaca3939c2008-05-22 15:27:38 +00006587#endif
Jesus Ceaef9764f2008-05-13 18:45:46 +00006588 MAKE_ENTRY(hash_len);
6589#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006590 MAKE_ENTRY(regsize);
6591 MAKE_ENTRY(region_wait);
6592 MAKE_ENTRY(region_nowait);
6593
6594#undef MAKE_ENTRY
6595 free(sp);
6596 return d;
6597}
6598
Jesus Cea6557aac2010-03-22 14:22:26 +00006599static PyObject*
6600DBEnv_lock_stat_print(DBEnvObject* self, PyObject* args, PyObject *kwargs)
6601{
6602 int err;
6603 int flags=0;
6604 static char* kwnames[] = { "flags", NULL };
6605
6606 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:lock_stat_print",
6607 kwnames, &flags))
6608 {
6609 return NULL;
6610 }
6611 CHECK_ENV_NOT_CLOSED(self);
6612 MYDB_BEGIN_ALLOW_THREADS;
6613 err = self->db_env->lock_stat_print(self->db_env, flags);
6614 MYDB_END_ALLOW_THREADS;
6615 RETURN_IF_ERR();
6616 RETURN_NONE();
6617}
Jesus Cea6557aac2010-03-22 14:22:26 +00006618
6619
6620static PyObject*
6621DBEnv_log_cursor(DBEnvObject* self)
6622{
6623 int err;
6624 DB_LOGC* dblogc;
6625
6626 CHECK_ENV_NOT_CLOSED(self);
6627
6628 MYDB_BEGIN_ALLOW_THREADS;
6629 err = self->db_env->log_cursor(self->db_env, &dblogc, 0);
6630 MYDB_END_ALLOW_THREADS;
6631 RETURN_IF_ERR();
6632 return (PyObject*) newDBLogCursorObject(dblogc, self);
6633}
6634
6635
Jesus Ceaef9764f2008-05-13 18:45:46 +00006636static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00006637DBEnv_log_flush(DBEnvObject* self)
Jesus Ceaef9764f2008-05-13 18:45:46 +00006638{
6639 int err;
6640
Jesus Ceaef9764f2008-05-13 18:45:46 +00006641 CHECK_ENV_NOT_CLOSED(self);
6642
6643 MYDB_BEGIN_ALLOW_THREADS
6644 err = self->db_env->log_flush(self->db_env, NULL);
6645 MYDB_END_ALLOW_THREADS
6646
6647 RETURN_IF_ERR();
6648 RETURN_NONE();
6649}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006650
6651static PyObject*
Jesus Cea6557aac2010-03-22 14:22:26 +00006652DBEnv_log_file(DBEnvObject* self, PyObject* args)
6653{
6654 int err;
6655 DB_LSN lsn = {0, 0};
6656 int size = 20;
6657 char *name = NULL;
6658 PyObject *retval;
6659
6660 if (!PyArg_ParseTuple(args, "(ii):log_file", &lsn.file, &lsn.offset))
6661 return NULL;
6662
6663 CHECK_ENV_NOT_CLOSED(self);
6664
6665 do {
6666 name = malloc(size);
6667 if (!name) {
6668 PyErr_NoMemory();
6669 return NULL;
6670 }
6671 MYDB_BEGIN_ALLOW_THREADS;
6672 err = self->db_env->log_file(self->db_env, &lsn, name, size);
6673 MYDB_END_ALLOW_THREADS;
6674 if (err == EINVAL) {
6675 free(name);
6676 size *= 2;
6677 } else if (err) {
6678 free(name);
6679 RETURN_IF_ERR();
6680 assert(0); /* Unreachable... supposely */
6681 return NULL;
6682 }
6683/*
6684** If the final buffer we try is too small, we will
6685** get this exception:
6686** DBInvalidArgError:
6687** (22, 'Invalid argument -- DB_ENV->log_file: name buffer is too short')
6688*/
6689 } while ((err == EINVAL) && (size<(1<<17)));
6690
6691 RETURN_IF_ERR(); /* Maybe the size is not the problem */
6692
6693 retval = Py_BuildValue("s", name);
6694 free(name);
6695 return retval;
6696}
6697
6698
6699#if (DBVER >= 44)
6700static PyObject*
6701DBEnv_log_printf(DBEnvObject* self, PyObject* args, PyObject *kwargs)
6702{
6703 int err;
6704 char *string;
6705 PyObject *txnobj = NULL;
6706 DB_TXN *txn = NULL;
6707 static char* kwnames[] = {"string", "txn", NULL };
6708
6709 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|O:log_printf", kwnames,
6710 &string, &txnobj))
6711 return NULL;
6712
6713 CHECK_ENV_NOT_CLOSED(self);
6714
6715 if (!checkTxnObj(txnobj, &txn))
6716 return NULL;
6717
6718 /*
6719 ** Do not use the format string directly, to avoid attacks.
6720 */
6721 MYDB_BEGIN_ALLOW_THREADS;
6722 err = self->db_env->log_printf(self->db_env, txn, "%s", string);
6723 MYDB_END_ALLOW_THREADS;
6724
6725 RETURN_IF_ERR();
6726 RETURN_NONE();
6727}
6728#endif
6729
6730
6731static PyObject*
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006732DBEnv_log_archive(DBEnvObject* self, PyObject* args)
6733{
6734 int flags=0;
6735 int err;
Gregory P. Smith3dd20022006-06-05 00:31:01 +00006736 char **log_list = NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006737 PyObject* list;
6738 PyObject* item = NULL;
6739
6740 if (!PyArg_ParseTuple(args, "|i:log_archive", &flags))
6741 return NULL;
6742
6743 CHECK_ENV_NOT_CLOSED(self);
6744 MYDB_BEGIN_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006745 err = self->db_env->log_archive(self->db_env, &log_list, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006746 MYDB_END_ALLOW_THREADS;
6747 RETURN_IF_ERR();
6748
Gregory P. Smithbad47452006-06-05 00:33:35 +00006749 list = PyList_New(0);
6750 if (list == NULL) {
6751 if (log_list)
6752 free(log_list);
6753 return NULL;
6754 }
6755
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006756 if (log_list) {
Gregory P. Smith3dd20022006-06-05 00:31:01 +00006757 char **log_list_start;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006758 for (log_list_start = log_list; *log_list != NULL; ++log_list) {
Christian Heimes593daf52008-05-26 12:51:38 +00006759 item = PyBytes_FromString (*log_list);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006760 if (item == NULL) {
6761 Py_DECREF(list);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006762 list = NULL;
6763 break;
6764 }
Jesus Ceac5a11fa2008-07-23 11:38:42 +00006765 if (PyList_Append(list, item)) {
6766 Py_DECREF(list);
6767 list = NULL;
6768 Py_DECREF(item);
6769 break;
6770 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006771 Py_DECREF(item);
6772 }
6773 free(log_list_start);
6774 }
6775 return list;
6776}
6777
6778
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07006779#if (DBVER >= 52)
6780static PyObject*
6781DBEnv_repmgr_site(DBEnvObject* self, PyObject* args, PyObject *kwargs)
6782{
6783 int err;
6784 DB_SITE* site;
6785 char *host;
6786 u_int port;
6787 static char* kwnames[] = {"host", "port", NULL};
6788
6789 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "si:repmgr_site", kwnames,
6790 &host, &port))
6791 return NULL;
6792
6793 CHECK_ENV_NOT_CLOSED(self);
6794
6795 MYDB_BEGIN_ALLOW_THREADS;
6796 err = self->db_env->repmgr_site(self->db_env, host, port, &site, 0);
6797 MYDB_END_ALLOW_THREADS;
6798 RETURN_IF_ERR();
6799 return (PyObject*) newDBSiteObject(site, self);
6800}
6801
6802static PyObject*
6803DBEnv_repmgr_site_by_eid(DBEnvObject* self, PyObject* args, PyObject *kwargs)
6804{
6805 int err;
6806 DB_SITE* site;
6807 int eid;
6808 static char* kwnames[] = {"eid", NULL};
6809
6810 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i:repmgr_site_by_eid",
6811 kwnames, &eid))
6812 return NULL;
6813
6814 CHECK_ENV_NOT_CLOSED(self);
6815
6816 MYDB_BEGIN_ALLOW_THREADS;
6817 err = self->db_env->repmgr_site_by_eid(self->db_env, eid, &site);
6818 MYDB_END_ALLOW_THREADS;
6819 RETURN_IF_ERR();
6820 return (PyObject*) newDBSiteObject(site, self);
6821}
6822#endif
6823
6824
Jesus Cea6557aac2010-03-22 14:22:26 +00006825#if (DBVER >= 44)
6826static PyObject*
6827DBEnv_mutex_stat(DBEnvObject* self, PyObject* args)
6828{
6829 int err;
6830 DB_MUTEX_STAT* statp = NULL;
6831 PyObject* d = NULL;
6832 u_int32_t flags = 0;
6833
6834 if (!PyArg_ParseTuple(args, "|i:mutex_stat", &flags))
6835 return NULL;
6836 CHECK_ENV_NOT_CLOSED(self);
6837
6838 MYDB_BEGIN_ALLOW_THREADS;
6839 err = self->db_env->mutex_stat(self->db_env, &statp, flags);
6840 MYDB_END_ALLOW_THREADS;
6841 RETURN_IF_ERR();
6842
6843 /* Turn the stat structure into a dictionary */
6844 d = PyDict_New();
6845 if (d == NULL) {
6846 if (statp)
6847 free(statp);
6848 return NULL;
6849 }
6850
6851#define MAKE_ENTRY(name) _addIntToDict(d, #name, statp->st_##name)
6852
6853 MAKE_ENTRY(mutex_align);
6854 MAKE_ENTRY(mutex_tas_spins);
6855 MAKE_ENTRY(mutex_cnt);
6856 MAKE_ENTRY(mutex_free);
6857 MAKE_ENTRY(mutex_inuse);
6858 MAKE_ENTRY(mutex_inuse_max);
6859 MAKE_ENTRY(regsize);
6860 MAKE_ENTRY(region_wait);
6861 MAKE_ENTRY(region_nowait);
6862
6863#undef MAKE_ENTRY
6864 free(statp);
6865 return d;
6866}
6867#endif
6868
6869
6870#if (DBVER >= 44)
6871static PyObject*
6872DBEnv_mutex_stat_print(DBEnvObject* self, PyObject* args, PyObject *kwargs)
6873{
6874 int err;
6875 int flags=0;
6876 static char* kwnames[] = { "flags", NULL };
6877
6878 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:mutex_stat_print",
6879 kwnames, &flags))
6880 {
6881 return NULL;
6882 }
6883 CHECK_ENV_NOT_CLOSED(self);
6884 MYDB_BEGIN_ALLOW_THREADS;
6885 err = self->db_env->mutex_stat_print(self->db_env, flags);
6886 MYDB_END_ALLOW_THREADS;
6887 RETURN_IF_ERR();
6888 RETURN_NONE();
6889}
6890#endif
6891
6892
Jesus Cea6557aac2010-03-22 14:22:26 +00006893static PyObject*
6894DBEnv_txn_stat_print(DBEnvObject* self, PyObject* args, PyObject *kwargs)
6895{
6896 int err;
6897 int flags=0;
6898 static char* kwnames[] = { "flags", NULL };
6899
6900 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:stat_print",
6901 kwnames, &flags))
6902 {
6903 return NULL;
6904 }
6905
6906 CHECK_ENV_NOT_CLOSED(self);
6907
6908 MYDB_BEGIN_ALLOW_THREADS;
6909 err = self->db_env->txn_stat_print(self->db_env, flags);
6910 MYDB_END_ALLOW_THREADS;
6911 RETURN_IF_ERR();
6912 RETURN_NONE();
6913}
Jesus Cea6557aac2010-03-22 14:22:26 +00006914
6915
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006916static PyObject*
6917DBEnv_txn_stat(DBEnvObject* self, PyObject* args)
6918{
6919 int err;
6920 DB_TXN_STAT* sp;
6921 PyObject* d = NULL;
Martin v. Löwisb2c7aff2002-11-23 11:26:07 +00006922 u_int32_t flags=0;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006923
6924 if (!PyArg_ParseTuple(args, "|i:txn_stat", &flags))
6925 return NULL;
6926 CHECK_ENV_NOT_CLOSED(self);
6927
6928 MYDB_BEGIN_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006929 err = self->db_env->txn_stat(self->db_env, &sp, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006930 MYDB_END_ALLOW_THREADS;
6931 RETURN_IF_ERR();
6932
6933 /* Turn the stat structure into a dictionary */
6934 d = PyDict_New();
6935 if (d == NULL) {
6936 free(sp);
6937 return NULL;
6938 }
6939
Jesus Ceaef9764f2008-05-13 18:45:46 +00006940#define MAKE_ENTRY(name) _addIntToDict(d, #name, sp->st_##name)
6941#define MAKE_TIME_T_ENTRY(name) _addTimeTToDict(d, #name, sp->st_##name)
6942#define MAKE_DB_LSN_ENTRY(name) _addDB_lsnToDict(d, #name, sp->st_##name)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006943
Jesus Ceaef9764f2008-05-13 18:45:46 +00006944 MAKE_DB_LSN_ENTRY(last_ckp);
Kristján Valur Jónssonbd77c032007-04-26 15:24:54 +00006945 MAKE_TIME_T_ENTRY(time_ckp);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006946 MAKE_ENTRY(last_txnid);
6947 MAKE_ENTRY(maxtxns);
6948 MAKE_ENTRY(nactive);
6949 MAKE_ENTRY(maxnactive);
Jesus Ceaef9764f2008-05-13 18:45:46 +00006950#if (DBVER >= 45)
6951 MAKE_ENTRY(nsnapshot);
6952 MAKE_ENTRY(maxnsnapshot);
6953#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006954 MAKE_ENTRY(nbegins);
6955 MAKE_ENTRY(naborts);
6956 MAKE_ENTRY(ncommits);
Jesus Ceaef9764f2008-05-13 18:45:46 +00006957 MAKE_ENTRY(nrestores);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006958 MAKE_ENTRY(regsize);
6959 MAKE_ENTRY(region_wait);
6960 MAKE_ENTRY(region_nowait);
6961
Jesus Ceaef9764f2008-05-13 18:45:46 +00006962#undef MAKE_DB_LSN_ENTRY
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006963#undef MAKE_ENTRY
Kristján Valur Jónssonbd77c032007-04-26 15:24:54 +00006964#undef MAKE_TIME_T_ENTRY
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006965 free(sp);
6966 return d;
6967}
6968
6969
6970static PyObject*
6971DBEnv_set_get_returns_none(DBEnvObject* self, PyObject* args)
6972{
6973 int flags=0;
Gregory P. Smith455d46f2003-07-09 04:45:59 +00006974 int oldValue=0;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006975
6976 if (!PyArg_ParseTuple(args,"i:set_get_returns_none", &flags))
6977 return NULL;
6978 CHECK_ENV_NOT_CLOSED(self);
6979
Gregory P. Smith455d46f2003-07-09 04:45:59 +00006980 if (self->moduleFlags.getReturnsNone)
6981 ++oldValue;
6982 if (self->moduleFlags.cursorSetReturnsNone)
6983 ++oldValue;
6984 self->moduleFlags.getReturnsNone = (flags >= 1);
6985 self->moduleFlags.cursorSetReturnsNone = (flags >= 2);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00006986 return NUMBER_FromLong(oldValue);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006987}
6988
Jesus Ceac5a11fa2008-07-23 11:38:42 +00006989static PyObject*
6990DBEnv_get_private(DBEnvObject* self)
6991{
6992 /* We can give out the private field even if dbenv is closed */
Jesus Cea4907d272008-08-31 14:00:51 +00006993 Py_INCREF(self->private_obj);
6994 return self->private_obj;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00006995}
6996
6997static PyObject*
Jesus Cea4907d272008-08-31 14:00:51 +00006998DBEnv_set_private(DBEnvObject* self, PyObject* private_obj)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00006999{
7000 /* We can set the private field even if dbenv is closed */
Jesus Cea4907d272008-08-31 14:00:51 +00007001 Py_DECREF(self->private_obj);
7002 Py_INCREF(private_obj);
7003 self->private_obj = private_obj;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007004 RETURN_NONE();
7005}
7006
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07007007#if (DBVER >= 47)
7008static PyObject*
7009DBEnv_set_intermediate_dir_mode(DBEnvObject* self, PyObject* args)
7010{
7011 int err;
7012 const char *mode;
7013
7014 if (!PyArg_ParseTuple(args,"s:set_intermediate_dir_mode", &mode))
7015 return NULL;
7016
7017 CHECK_ENV_NOT_CLOSED(self);
7018
7019 MYDB_BEGIN_ALLOW_THREADS;
7020 err = self->db_env->set_intermediate_dir_mode(self->db_env, mode);
7021 MYDB_END_ALLOW_THREADS;
7022 RETURN_IF_ERR();
7023 RETURN_NONE();
7024}
7025
7026static PyObject*
7027DBEnv_get_intermediate_dir_mode(DBEnvObject* self)
7028{
7029 int err;
7030 const char *mode;
7031
7032 CHECK_ENV_NOT_CLOSED(self);
7033
7034 MYDB_BEGIN_ALLOW_THREADS;
7035 err = self->db_env->get_intermediate_dir_mode(self->db_env, &mode);
7036 MYDB_END_ALLOW_THREADS;
7037 RETURN_IF_ERR();
7038 return Py_BuildValue("s", mode);
7039}
7040#endif
7041
7042#if (DBVER < 47)
7043static PyObject*
7044DBEnv_set_intermediate_dir(DBEnvObject* self, PyObject* args)
7045{
7046 int err;
7047 int mode;
7048 u_int32_t flags;
7049
7050 if (!PyArg_ParseTuple(args, "iI:set_intermediate_dir", &mode, &flags))
7051 return NULL;
7052
7053 CHECK_ENV_NOT_CLOSED(self);
7054
7055 MYDB_BEGIN_ALLOW_THREADS;
7056 err = self->db_env->set_intermediate_dir(self->db_env, mode, flags);
7057 MYDB_END_ALLOW_THREADS;
7058 RETURN_IF_ERR();
7059 RETURN_NONE();
7060}
7061#endif
7062
7063static PyObject*
7064DBEnv_get_open_flags(DBEnvObject* self)
7065{
7066 int err;
7067 unsigned int flags;
7068
7069 CHECK_ENV_NOT_CLOSED(self);
7070
7071 MYDB_BEGIN_ALLOW_THREADS;
7072 err = self->db_env->get_open_flags(self->db_env, &flags);
7073 MYDB_END_ALLOW_THREADS;
7074 RETURN_IF_ERR();
7075 return NUMBER_FromLong(flags);
7076}
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007077
Matthias Klose54cc5392010-03-15 12:46:18 +00007078#if (DBVER < 48)
Jesus Ceaef9764f2008-05-13 18:45:46 +00007079static PyObject*
Jesus Ceaca3939c2008-05-22 15:27:38 +00007080DBEnv_set_rpc_server(DBEnvObject* self, PyObject* args, PyObject* kwargs)
7081{
7082 int err;
7083 char *host;
7084 long cl_timeout=0, sv_timeout=0;
7085
7086 static char* kwnames[] = { "host", "cl_timeout", "sv_timeout", NULL};
7087
7088 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|ll:set_rpc_server", kwnames,
7089 &host, &cl_timeout, &sv_timeout))
7090 return NULL;
7091 CHECK_ENV_NOT_CLOSED(self);
7092
7093 MYDB_BEGIN_ALLOW_THREADS;
7094 err = self->db_env->set_rpc_server(self->db_env, NULL, host, cl_timeout,
7095 sv_timeout, 0);
7096 MYDB_END_ALLOW_THREADS;
7097 RETURN_IF_ERR();
7098 RETURN_NONE();
7099}
Matthias Klose54cc5392010-03-15 12:46:18 +00007100#endif
Jesus Ceaca3939c2008-05-22 15:27:38 +00007101
Jesus Cea6557aac2010-03-22 14:22:26 +00007102static PyObject*
7103DBEnv_set_mp_max_openfd(DBEnvObject* self, PyObject* args)
7104{
7105 int err;
7106 int maxopenfd;
7107
7108 if (!PyArg_ParseTuple(args, "i:set_mp_max_openfd", &maxopenfd)) {
7109 return NULL;
7110 }
7111 CHECK_ENV_NOT_CLOSED(self);
7112 MYDB_BEGIN_ALLOW_THREADS;
7113 err = self->db_env->set_mp_max_openfd(self->db_env, maxopenfd);
7114 MYDB_END_ALLOW_THREADS;
7115 RETURN_IF_ERR();
7116 RETURN_NONE();
7117}
7118
7119static PyObject*
7120DBEnv_get_mp_max_openfd(DBEnvObject* self)
7121{
7122 int err;
7123 int maxopenfd;
7124
7125 CHECK_ENV_NOT_CLOSED(self);
7126
7127 MYDB_BEGIN_ALLOW_THREADS;
7128 err = self->db_env->get_mp_max_openfd(self->db_env, &maxopenfd);
7129 MYDB_END_ALLOW_THREADS;
7130 RETURN_IF_ERR();
7131 return NUMBER_FromLong(maxopenfd);
7132}
7133
7134
7135static PyObject*
7136DBEnv_set_mp_max_write(DBEnvObject* self, PyObject* args)
7137{
7138 int err;
7139 int maxwrite, maxwrite_sleep;
7140
7141 if (!PyArg_ParseTuple(args, "ii:set_mp_max_write", &maxwrite,
7142 &maxwrite_sleep)) {
7143 return NULL;
7144 }
7145 CHECK_ENV_NOT_CLOSED(self);
7146 MYDB_BEGIN_ALLOW_THREADS;
7147 err = self->db_env->set_mp_max_write(self->db_env, maxwrite,
7148 maxwrite_sleep);
7149 MYDB_END_ALLOW_THREADS;
7150 RETURN_IF_ERR();
7151 RETURN_NONE();
7152}
7153
7154static PyObject*
7155DBEnv_get_mp_max_write(DBEnvObject* self)
7156{
7157 int err;
7158 int maxwrite;
7159#if (DBVER >= 46)
7160 db_timeout_t maxwrite_sleep;
7161#else
7162 int maxwrite_sleep;
7163#endif
7164
7165 CHECK_ENV_NOT_CLOSED(self);
7166
7167 MYDB_BEGIN_ALLOW_THREADS;
7168 err = self->db_env->get_mp_max_write(self->db_env, &maxwrite,
7169 &maxwrite_sleep);
7170 MYDB_END_ALLOW_THREADS;
7171 RETURN_IF_ERR();
7172
7173 return Py_BuildValue("(ii)", maxwrite, (int)maxwrite_sleep);
7174}
Jesus Cea6557aac2010-03-22 14:22:26 +00007175
7176
Jesus Ceaca3939c2008-05-22 15:27:38 +00007177static PyObject*
Jesus Ceaef9764f2008-05-13 18:45:46 +00007178DBEnv_set_verbose(DBEnvObject* self, PyObject* args)
7179{
7180 int err;
7181 int which, onoff;
7182
7183 if (!PyArg_ParseTuple(args, "ii:set_verbose", &which, &onoff)) {
7184 return NULL;
7185 }
7186 CHECK_ENV_NOT_CLOSED(self);
7187 MYDB_BEGIN_ALLOW_THREADS;
7188 err = self->db_env->set_verbose(self->db_env, which, onoff);
7189 MYDB_END_ALLOW_THREADS;
7190 RETURN_IF_ERR();
7191 RETURN_NONE();
7192}
7193
Jesus Ceaef9764f2008-05-13 18:45:46 +00007194static PyObject*
7195DBEnv_get_verbose(DBEnvObject* self, PyObject* args)
7196{
7197 int err;
7198 int which;
7199 int verbose;
7200
7201 if (!PyArg_ParseTuple(args, "i:get_verbose", &which)) {
7202 return NULL;
7203 }
7204 CHECK_ENV_NOT_CLOSED(self);
7205 MYDB_BEGIN_ALLOW_THREADS;
7206 err = self->db_env->get_verbose(self->db_env, which, &verbose);
7207 MYDB_END_ALLOW_THREADS;
7208 RETURN_IF_ERR();
7209 return PyBool_FromLong(verbose);
7210}
Jesus Ceaef9764f2008-05-13 18:45:46 +00007211
7212#if (DBVER >= 45)
7213static void
7214_dbenv_event_notifyCallback(DB_ENV* db_env, u_int32_t event, void *event_info)
7215{
7216 DBEnvObject *dbenv;
7217 PyObject* callback;
7218 PyObject* args;
7219 PyObject* result = NULL;
7220
7221 MYDB_BEGIN_BLOCK_THREADS;
7222 dbenv = (DBEnvObject *)db_env->app_private;
7223 callback = dbenv->event_notifyCallback;
7224 if (callback) {
7225 if (event == DB_EVENT_REP_NEWMASTER) {
7226 args = Py_BuildValue("(Oii)", dbenv, event, *((int *)event_info));
7227 } else {
7228 args = Py_BuildValue("(OiO)", dbenv, event, Py_None);
7229 }
7230 if (args) {
7231 result = PyEval_CallObject(callback, args);
7232 }
7233 if ((!args) || (!result)) {
7234 PyErr_Print();
7235 }
7236 Py_XDECREF(args);
7237 Py_XDECREF(result);
7238 }
7239 MYDB_END_BLOCK_THREADS;
7240}
7241#endif
7242
7243#if (DBVER >= 45)
7244static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007245DBEnv_set_event_notify(DBEnvObject* self, PyObject* notifyFunc)
Jesus Ceaef9764f2008-05-13 18:45:46 +00007246{
7247 int err;
Jesus Ceaef9764f2008-05-13 18:45:46 +00007248
7249 CHECK_ENV_NOT_CLOSED(self);
7250
7251 if (!PyCallable_Check(notifyFunc)) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00007252 makeTypeError("Callable", notifyFunc);
7253 return NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00007254 }
7255
7256 Py_XDECREF(self->event_notifyCallback);
7257 Py_INCREF(notifyFunc);
7258 self->event_notifyCallback = notifyFunc;
7259
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007260 /* This is to workaround a problem with un-initialized threads (see
7261 comment in DB_associate) */
7262#ifdef WITH_THREAD
7263 PyEval_InitThreads();
7264#endif
7265
Jesus Ceaef9764f2008-05-13 18:45:46 +00007266 MYDB_BEGIN_ALLOW_THREADS;
7267 err = self->db_env->set_event_notify(self->db_env, _dbenv_event_notifyCallback);
7268 MYDB_END_ALLOW_THREADS;
7269
7270 if (err) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00007271 Py_DECREF(notifyFunc);
7272 self->event_notifyCallback = NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00007273 }
7274
7275 RETURN_IF_ERR();
7276 RETURN_NONE();
7277}
7278#endif
7279
7280
7281/* --------------------------------------------------------------------- */
7282/* REPLICATION METHODS: Base Replication */
7283
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007284
7285static PyObject*
7286DBEnv_rep_process_message(DBEnvObject* self, PyObject* args)
7287{
7288 int err;
7289 PyObject *control_py, *rec_py;
7290 DBT control, rec;
7291 int envid;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007292 DB_LSN lsn;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007293
7294 if (!PyArg_ParseTuple(args, "OOi:rep_process_message", &control_py,
7295 &rec_py, &envid))
7296 return NULL;
7297 CHECK_ENV_NOT_CLOSED(self);
7298
7299 if (!make_dbt(control_py, &control))
7300 return NULL;
7301 if (!make_dbt(rec_py, &rec))
7302 return NULL;
7303
7304 MYDB_BEGIN_ALLOW_THREADS;
7305#if (DBVER >= 46)
7306 err = self->db_env->rep_process_message(self->db_env, &control, &rec,
7307 envid, &lsn);
7308#else
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007309 err = self->db_env->rep_process_message(self->db_env, &control, &rec,
7310 &envid, &lsn);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007311#endif
7312 MYDB_END_ALLOW_THREADS;
7313 switch (err) {
7314 case DB_REP_NEWMASTER :
7315 return Py_BuildValue("(iO)", envid, Py_None);
7316 break;
7317
7318 case DB_REP_DUPMASTER :
7319 case DB_REP_HOLDELECTION :
7320#if (DBVER >= 44)
7321 case DB_REP_IGNORE :
7322 case DB_REP_JOIN_FAILURE :
7323#endif
7324 return Py_BuildValue("(iO)", err, Py_None);
7325 break;
7326 case DB_REP_NEWSITE :
Jesus Cea4907d272008-08-31 14:00:51 +00007327 {
7328 PyObject *tmp, *r;
7329
7330 if (!(tmp = PyBytes_FromStringAndSize(rec.data, rec.size))) {
7331 return NULL;
7332 }
7333
7334 r = Py_BuildValue("(iO)", err, tmp);
7335 Py_DECREF(tmp);
7336 return r;
7337 break;
7338 }
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007339 case DB_REP_NOTPERM :
7340 case DB_REP_ISPERM :
7341 return Py_BuildValue("(i(ll))", err, lsn.file, lsn.offset);
7342 break;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007343 }
7344 RETURN_IF_ERR();
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07007345 return PyTuple_Pack(2, Py_None, Py_None);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007346}
7347
7348static int
7349_DBEnv_rep_transportCallback(DB_ENV* db_env, const DBT* control, const DBT* rec,
7350 const DB_LSN *lsn, int envid, u_int32_t flags)
7351{
7352 DBEnvObject *dbenv;
7353 PyObject* rep_transport;
7354 PyObject* args;
Jesus Cea4907d272008-08-31 14:00:51 +00007355 PyObject *a, *b;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007356 PyObject* result = NULL;
7357 int ret=0;
7358
7359 MYDB_BEGIN_BLOCK_THREADS;
7360 dbenv = (DBEnvObject *)db_env->app_private;
7361 rep_transport = dbenv->rep_transport;
7362
Jesus Cea4907d272008-08-31 14:00:51 +00007363 /*
7364 ** The errors in 'a' or 'b' are detected in "Py_BuildValue".
7365 */
7366 a = PyBytes_FromStringAndSize(control->data, control->size);
7367 b = PyBytes_FromStringAndSize(rec->data, rec->size);
7368
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007369 args = Py_BuildValue(
Jesus Cea4907d272008-08-31 14:00:51 +00007370 "(OOO(ll)iI)",
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007371 dbenv,
Jesus Cea4907d272008-08-31 14:00:51 +00007372 a, b,
7373 lsn->file, lsn->offset, envid, flags);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007374 if (args) {
7375 result = PyEval_CallObject(rep_transport, args);
7376 }
7377
7378 if ((!args) || (!result)) {
7379 PyErr_Print();
7380 ret = -1;
7381 }
Jesus Cea4907d272008-08-31 14:00:51 +00007382 Py_XDECREF(a);
7383 Py_XDECREF(b);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007384 Py_XDECREF(args);
7385 Py_XDECREF(result);
7386 MYDB_END_BLOCK_THREADS;
7387 return ret;
7388}
7389
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007390static PyObject*
7391DBEnv_rep_set_transport(DBEnvObject* self, PyObject* args)
7392{
7393 int err;
7394 int envid;
7395 PyObject *rep_transport;
7396
7397 if (!PyArg_ParseTuple(args, "iO:rep_set_transport", &envid, &rep_transport))
7398 return NULL;
7399 CHECK_ENV_NOT_CLOSED(self);
7400 if (!PyCallable_Check(rep_transport)) {
7401 makeTypeError("Callable", rep_transport);
7402 return NULL;
7403 }
7404
7405 MYDB_BEGIN_ALLOW_THREADS;
7406#if (DBVER >=45)
7407 err = self->db_env->rep_set_transport(self->db_env, envid,
7408 &_DBEnv_rep_transportCallback);
7409#else
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007410 err = self->db_env->set_rep_transport(self->db_env, envid,
7411 &_DBEnv_rep_transportCallback);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007412#endif
7413 MYDB_END_ALLOW_THREADS;
7414 RETURN_IF_ERR();
7415
7416 Py_DECREF(self->rep_transport);
7417 Py_INCREF(rep_transport);
7418 self->rep_transport = rep_transport;
7419 RETURN_NONE();
7420}
7421
7422#if (DBVER >= 47)
7423static PyObject*
7424DBEnv_rep_set_request(DBEnvObject* self, PyObject* args)
7425{
7426 int err;
7427 unsigned int minimum, maximum;
7428
7429 if (!PyArg_ParseTuple(args,"II:rep_set_request", &minimum, &maximum))
7430 return NULL;
7431 CHECK_ENV_NOT_CLOSED(self);
7432
7433 MYDB_BEGIN_ALLOW_THREADS;
7434 err = self->db_env->rep_set_request(self->db_env, minimum, maximum);
7435 MYDB_END_ALLOW_THREADS;
7436 RETURN_IF_ERR();
7437 RETURN_NONE();
7438}
7439
7440static PyObject*
7441DBEnv_rep_get_request(DBEnvObject* self)
7442{
7443 int err;
7444 u_int32_t minimum, maximum;
7445
7446 CHECK_ENV_NOT_CLOSED(self);
7447 MYDB_BEGIN_ALLOW_THREADS;
7448 err = self->db_env->rep_get_request(self->db_env, &minimum, &maximum);
7449 MYDB_END_ALLOW_THREADS;
7450 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007451 return Py_BuildValue("II", minimum, maximum);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007452}
7453#endif
7454
7455#if (DBVER >= 45)
7456static PyObject*
7457DBEnv_rep_set_limit(DBEnvObject* self, PyObject* args)
7458{
7459 int err;
7460 int limit;
7461
7462 if (!PyArg_ParseTuple(args,"i:rep_set_limit", &limit))
7463 return NULL;
7464 CHECK_ENV_NOT_CLOSED(self);
7465
7466 MYDB_BEGIN_ALLOW_THREADS;
7467 err = self->db_env->rep_set_limit(self->db_env, 0, limit);
7468 MYDB_END_ALLOW_THREADS;
7469 RETURN_IF_ERR();
7470 RETURN_NONE();
7471}
7472
7473static PyObject*
7474DBEnv_rep_get_limit(DBEnvObject* self)
7475{
7476 int err;
7477 u_int32_t gbytes, bytes;
7478
7479 CHECK_ENV_NOT_CLOSED(self);
7480 MYDB_BEGIN_ALLOW_THREADS;
7481 err = self->db_env->rep_get_limit(self->db_env, &gbytes, &bytes);
7482 MYDB_END_ALLOW_THREADS;
7483 RETURN_IF_ERR();
7484 return NUMBER_FromLong(bytes);
7485}
7486#endif
7487
7488#if (DBVER >= 44)
7489static PyObject*
7490DBEnv_rep_set_config(DBEnvObject* self, PyObject* args)
7491{
7492 int err;
7493 int which;
7494 int onoff;
7495
7496 if (!PyArg_ParseTuple(args,"ii:rep_set_config", &which, &onoff))
7497 return NULL;
7498 CHECK_ENV_NOT_CLOSED(self);
7499
7500 MYDB_BEGIN_ALLOW_THREADS;
7501 err = self->db_env->rep_set_config(self->db_env, which, onoff);
7502 MYDB_END_ALLOW_THREADS;
7503 RETURN_IF_ERR();
7504 RETURN_NONE();
7505}
7506
7507static PyObject*
7508DBEnv_rep_get_config(DBEnvObject* self, PyObject* args)
7509{
7510 int err;
7511 int which;
7512 int onoff;
7513
7514 if (!PyArg_ParseTuple(args, "i:rep_get_config", &which)) {
7515 return NULL;
7516 }
7517 CHECK_ENV_NOT_CLOSED(self);
7518 MYDB_BEGIN_ALLOW_THREADS;
7519 err = self->db_env->rep_get_config(self->db_env, which, &onoff);
7520 MYDB_END_ALLOW_THREADS;
7521 RETURN_IF_ERR();
7522 return PyBool_FromLong(onoff);
7523}
7524#endif
7525
7526#if (DBVER >= 46)
7527static PyObject*
7528DBEnv_rep_elect(DBEnvObject* self, PyObject* args)
7529{
7530 int err;
7531 u_int32_t nsites, nvotes;
7532
7533 if (!PyArg_ParseTuple(args, "II:rep_elect", &nsites, &nvotes)) {
7534 return NULL;
7535 }
7536 CHECK_ENV_NOT_CLOSED(self);
7537 MYDB_BEGIN_ALLOW_THREADS;
Jesus Cea2ab4a912012-01-16 23:57:34 +01007538 err = self->db_env->rep_elect(self->db_env, nsites, nvotes, 0);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007539 MYDB_END_ALLOW_THREADS;
7540 RETURN_IF_ERR();
7541 RETURN_NONE();
7542}
7543#endif
7544
7545static PyObject*
7546DBEnv_rep_start(DBEnvObject* self, PyObject* args, PyObject* kwargs)
7547{
7548 int err;
7549 PyObject *cdata_py = Py_None;
7550 DBT cdata;
7551 int flags;
7552 static char* kwnames[] = {"flags","cdata", NULL};
7553
7554 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
7555 "i|O:rep_start", kwnames, &flags, &cdata_py))
7556 {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00007557 return NULL;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007558 }
7559 CHECK_ENV_NOT_CLOSED(self);
7560
7561 if (!make_dbt(cdata_py, &cdata))
7562 return NULL;
7563
7564 MYDB_BEGIN_ALLOW_THREADS;
7565 err = self->db_env->rep_start(self->db_env, cdata.size ? &cdata : NULL,
7566 flags);
7567 MYDB_END_ALLOW_THREADS;
7568 RETURN_IF_ERR();
7569 RETURN_NONE();
7570}
7571
7572#if (DBVER >= 44)
7573static PyObject*
7574DBEnv_rep_sync(DBEnvObject* self)
7575{
7576 int err;
7577
7578 CHECK_ENV_NOT_CLOSED(self);
7579 MYDB_BEGIN_ALLOW_THREADS;
7580 err = self->db_env->rep_sync(self->db_env, 0);
7581 MYDB_END_ALLOW_THREADS;
7582 RETURN_IF_ERR();
7583 RETURN_NONE();
7584}
7585#endif
7586
7587
Jesus Ceaef9764f2008-05-13 18:45:46 +00007588#if (DBVER >= 45)
7589static PyObject*
7590DBEnv_rep_set_nsites(DBEnvObject* self, PyObject* args)
7591{
7592 int err;
7593 int nsites;
7594
7595 if (!PyArg_ParseTuple(args, "i:rep_set_nsites", &nsites)) {
7596 return NULL;
7597 }
7598 CHECK_ENV_NOT_CLOSED(self);
7599 MYDB_BEGIN_ALLOW_THREADS;
7600 err = self->db_env->rep_set_nsites(self->db_env, nsites);
7601 MYDB_END_ALLOW_THREADS;
7602 RETURN_IF_ERR();
7603 RETURN_NONE();
7604}
7605
7606static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007607DBEnv_rep_get_nsites(DBEnvObject* self)
Jesus Ceaef9764f2008-05-13 18:45:46 +00007608{
7609 int err;
Jesus Ceaca3939c2008-05-22 15:27:38 +00007610#if (DBVER >= 47)
7611 u_int32_t nsites;
7612#else
Jesus Ceaef9764f2008-05-13 18:45:46 +00007613 int nsites;
Jesus Ceaca3939c2008-05-22 15:27:38 +00007614#endif
Jesus Ceaef9764f2008-05-13 18:45:46 +00007615
Jesus Ceaef9764f2008-05-13 18:45:46 +00007616 CHECK_ENV_NOT_CLOSED(self);
7617 MYDB_BEGIN_ALLOW_THREADS;
7618 err = self->db_env->rep_get_nsites(self->db_env, &nsites);
7619 MYDB_END_ALLOW_THREADS;
7620 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007621 return NUMBER_FromLong(nsites);
Jesus Ceaef9764f2008-05-13 18:45:46 +00007622}
7623
7624static PyObject*
7625DBEnv_rep_set_priority(DBEnvObject* self, PyObject* args)
7626{
7627 int err;
7628 int priority;
7629
7630 if (!PyArg_ParseTuple(args, "i:rep_set_priority", &priority)) {
7631 return NULL;
7632 }
7633 CHECK_ENV_NOT_CLOSED(self);
7634 MYDB_BEGIN_ALLOW_THREADS;
7635 err = self->db_env->rep_set_priority(self->db_env, priority);
7636 MYDB_END_ALLOW_THREADS;
7637 RETURN_IF_ERR();
7638 RETURN_NONE();
7639}
7640
7641static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007642DBEnv_rep_get_priority(DBEnvObject* self)
Jesus Ceaef9764f2008-05-13 18:45:46 +00007643{
7644 int err;
Jesus Ceaca3939c2008-05-22 15:27:38 +00007645#if (DBVER >= 47)
7646 u_int32_t priority;
7647#else
Jesus Ceaef9764f2008-05-13 18:45:46 +00007648 int priority;
Jesus Ceaca3939c2008-05-22 15:27:38 +00007649#endif
Jesus Ceaef9764f2008-05-13 18:45:46 +00007650
Jesus Ceaef9764f2008-05-13 18:45:46 +00007651 CHECK_ENV_NOT_CLOSED(self);
7652 MYDB_BEGIN_ALLOW_THREADS;
7653 err = self->db_env->rep_get_priority(self->db_env, &priority);
7654 MYDB_END_ALLOW_THREADS;
7655 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007656 return NUMBER_FromLong(priority);
Jesus Ceaef9764f2008-05-13 18:45:46 +00007657}
7658
7659static PyObject*
7660DBEnv_rep_set_timeout(DBEnvObject* self, PyObject* args)
7661{
7662 int err;
7663 int which, timeout;
7664
7665 if (!PyArg_ParseTuple(args, "ii:rep_set_timeout", &which, &timeout)) {
7666 return NULL;
7667 }
7668 CHECK_ENV_NOT_CLOSED(self);
7669 MYDB_BEGIN_ALLOW_THREADS;
7670 err = self->db_env->rep_set_timeout(self->db_env, which, timeout);
7671 MYDB_END_ALLOW_THREADS;
7672 RETURN_IF_ERR();
7673 RETURN_NONE();
7674}
7675
7676static PyObject*
7677DBEnv_rep_get_timeout(DBEnvObject* self, PyObject* args)
7678{
7679 int err;
7680 int which;
7681 u_int32_t timeout;
7682
7683 if (!PyArg_ParseTuple(args, "i:rep_get_timeout", &which)) {
7684 return NULL;
7685 }
7686 CHECK_ENV_NOT_CLOSED(self);
7687 MYDB_BEGIN_ALLOW_THREADS;
7688 err = self->db_env->rep_get_timeout(self->db_env, which, &timeout);
7689 MYDB_END_ALLOW_THREADS;
7690 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007691 return NUMBER_FromLong(timeout);
Jesus Ceaef9764f2008-05-13 18:45:46 +00007692}
7693#endif
7694
Jesus Cea6557aac2010-03-22 14:22:26 +00007695
7696#if (DBVER >= 47)
7697static PyObject*
7698DBEnv_rep_set_clockskew(DBEnvObject* self, PyObject* args)
7699{
7700 int err;
7701 unsigned int fast, slow;
7702
Jesus Cea6557aac2010-03-22 14:22:26 +00007703 if (!PyArg_ParseTuple(args,"II:rep_set_clockskew", &fast, &slow))
7704 return NULL;
Jesus Cea6557aac2010-03-22 14:22:26 +00007705
7706 CHECK_ENV_NOT_CLOSED(self);
7707
7708 MYDB_BEGIN_ALLOW_THREADS;
7709 err = self->db_env->rep_set_clockskew(self->db_env, fast, slow);
7710 MYDB_END_ALLOW_THREADS;
7711 RETURN_IF_ERR();
7712 RETURN_NONE();
7713}
7714
7715static PyObject*
7716DBEnv_rep_get_clockskew(DBEnvObject* self)
7717{
7718 int err;
7719 unsigned int fast, slow;
7720
7721 CHECK_ENV_NOT_CLOSED(self);
7722 MYDB_BEGIN_ALLOW_THREADS;
7723 err = self->db_env->rep_get_clockskew(self->db_env, &fast, &slow);
7724 MYDB_END_ALLOW_THREADS;
7725 RETURN_IF_ERR();
Jesus Cea6557aac2010-03-22 14:22:26 +00007726 return Py_BuildValue("(II)", fast, slow);
Jesus Cea6557aac2010-03-22 14:22:26 +00007727}
7728#endif
7729
Jesus Cea6557aac2010-03-22 14:22:26 +00007730static PyObject*
7731DBEnv_rep_stat_print(DBEnvObject* self, PyObject* args, PyObject *kwargs)
7732{
7733 int err;
7734 int flags=0;
7735 static char* kwnames[] = { "flags", NULL };
7736
7737 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:rep_stat_print",
7738 kwnames, &flags))
7739 {
7740 return NULL;
7741 }
7742 CHECK_ENV_NOT_CLOSED(self);
7743 MYDB_BEGIN_ALLOW_THREADS;
7744 err = self->db_env->rep_stat_print(self->db_env, flags);
7745 MYDB_END_ALLOW_THREADS;
7746 RETURN_IF_ERR();
7747 RETURN_NONE();
7748}
Jesus Cea6557aac2010-03-22 14:22:26 +00007749
7750static PyObject*
7751DBEnv_rep_stat(DBEnvObject* self, PyObject* args, PyObject *kwargs)
7752{
7753 int err;
7754 int flags=0;
7755 DB_REP_STAT *statp;
7756 PyObject *stats;
7757 static char* kwnames[] = { "flags", NULL };
7758
7759 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:rep_stat",
7760 kwnames, &flags))
7761 {
7762 return NULL;
7763 }
7764 CHECK_ENV_NOT_CLOSED(self);
7765 MYDB_BEGIN_ALLOW_THREADS;
7766 err = self->db_env->rep_stat(self->db_env, &statp, flags);
7767 MYDB_END_ALLOW_THREADS;
7768 RETURN_IF_ERR();
7769
7770 stats=PyDict_New();
7771 if (stats == NULL) {
7772 free(statp);
7773 return NULL;
7774 }
7775
7776#define MAKE_ENTRY(name) _addIntToDict(stats, #name, statp->st_##name)
7777#define MAKE_DB_LSN_ENTRY(name) _addDB_lsnToDict(stats , #name, statp->st_##name)
7778
7779#if (DBVER >= 44)
7780 MAKE_ENTRY(bulk_fills);
7781 MAKE_ENTRY(bulk_overflows);
7782 MAKE_ENTRY(bulk_records);
7783 MAKE_ENTRY(bulk_transfers);
7784 MAKE_ENTRY(client_rerequests);
7785 MAKE_ENTRY(client_svc_miss);
7786 MAKE_ENTRY(client_svc_req);
7787#endif
7788 MAKE_ENTRY(dupmasters);
Jesus Cea6557aac2010-03-22 14:22:26 +00007789 MAKE_ENTRY(egen);
7790 MAKE_ENTRY(election_nvotes);
7791 MAKE_ENTRY(startup_complete);
7792 MAKE_ENTRY(pg_duplicated);
7793 MAKE_ENTRY(pg_records);
7794 MAKE_ENTRY(pg_requested);
7795 MAKE_ENTRY(next_pg);
7796 MAKE_ENTRY(waiting_pg);
Jesus Cea6557aac2010-03-22 14:22:26 +00007797 MAKE_ENTRY(election_cur_winner);
7798 MAKE_ENTRY(election_gen);
7799 MAKE_DB_LSN_ENTRY(election_lsn);
7800 MAKE_ENTRY(election_nsites);
7801 MAKE_ENTRY(election_priority);
7802#if (DBVER >= 44)
7803 MAKE_ENTRY(election_sec);
7804 MAKE_ENTRY(election_usec);
7805#endif
7806 MAKE_ENTRY(election_status);
7807 MAKE_ENTRY(election_tiebreaker);
7808 MAKE_ENTRY(election_votes);
7809 MAKE_ENTRY(elections);
7810 MAKE_ENTRY(elections_won);
7811 MAKE_ENTRY(env_id);
7812 MAKE_ENTRY(env_priority);
7813 MAKE_ENTRY(gen);
7814 MAKE_ENTRY(log_duplicated);
7815 MAKE_ENTRY(log_queued);
7816 MAKE_ENTRY(log_queued_max);
7817 MAKE_ENTRY(log_queued_total);
7818 MAKE_ENTRY(log_records);
7819 MAKE_ENTRY(log_requested);
7820 MAKE_ENTRY(master);
7821 MAKE_ENTRY(master_changes);
7822#if (DBVER >= 47)
7823 MAKE_ENTRY(max_lease_sec);
7824 MAKE_ENTRY(max_lease_usec);
7825 MAKE_DB_LSN_ENTRY(max_perm_lsn);
7826#endif
7827 MAKE_ENTRY(msgs_badgen);
7828 MAKE_ENTRY(msgs_processed);
7829 MAKE_ENTRY(msgs_recover);
7830 MAKE_ENTRY(msgs_send_failures);
7831 MAKE_ENTRY(msgs_sent);
7832 MAKE_ENTRY(newsites);
7833 MAKE_DB_LSN_ENTRY(next_lsn);
7834 MAKE_ENTRY(nsites);
7835 MAKE_ENTRY(nthrottles);
7836 MAKE_ENTRY(outdated);
7837#if (DBVER >= 46)
7838 MAKE_ENTRY(startsync_delayed);
7839#endif
7840 MAKE_ENTRY(status);
7841 MAKE_ENTRY(txns_applied);
7842 MAKE_DB_LSN_ENTRY(waiting_lsn);
7843
7844#undef MAKE_DB_LSN_ENTRY
7845#undef MAKE_ENTRY
7846
7847 free(statp);
7848 return stats;
7849}
7850
Jesus Ceaef9764f2008-05-13 18:45:46 +00007851/* --------------------------------------------------------------------- */
7852/* REPLICATION METHODS: Replication Manager */
7853
7854#if (DBVER >= 45)
7855static PyObject*
7856DBEnv_repmgr_start(DBEnvObject* self, PyObject* args, PyObject*
7857 kwargs)
7858{
7859 int err;
7860 int nthreads, flags;
7861 static char* kwnames[] = {"nthreads","flags", NULL};
7862
7863 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
7864 "ii:repmgr_start", kwnames, &nthreads, &flags))
7865 {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00007866 return NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00007867 }
7868 CHECK_ENV_NOT_CLOSED(self);
7869 MYDB_BEGIN_ALLOW_THREADS;
7870 err = self->db_env->repmgr_start(self->db_env, nthreads, flags);
7871 MYDB_END_ALLOW_THREADS;
7872 RETURN_IF_ERR();
7873 RETURN_NONE();
7874}
7875
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07007876#if (DBVER < 52)
Jesus Ceaef9764f2008-05-13 18:45:46 +00007877static PyObject*
7878DBEnv_repmgr_set_local_site(DBEnvObject* self, PyObject* args, PyObject*
7879 kwargs)
7880{
7881 int err;
7882 char *host;
7883 int port;
7884 int flags = 0;
7885 static char* kwnames[] = {"host", "port", "flags", NULL};
7886
7887 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
7888 "si|i:repmgr_set_local_site", kwnames, &host, &port, &flags))
7889 {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00007890 return NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00007891 }
7892 CHECK_ENV_NOT_CLOSED(self);
7893 MYDB_BEGIN_ALLOW_THREADS;
7894 err = self->db_env->repmgr_set_local_site(self->db_env, host, port, flags);
7895 MYDB_END_ALLOW_THREADS;
7896 RETURN_IF_ERR();
7897 RETURN_NONE();
7898}
7899
7900static PyObject*
7901DBEnv_repmgr_add_remote_site(DBEnvObject* self, PyObject* args, PyObject*
7902 kwargs)
7903{
7904 int err;
7905 char *host;
7906 int port;
7907 int flags = 0;
7908 int eidp;
7909 static char* kwnames[] = {"host", "port", "flags", NULL};
7910
7911 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
7912 "si|i:repmgr_add_remote_site", kwnames, &host, &port, &flags))
7913 {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00007914 return NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00007915 }
7916 CHECK_ENV_NOT_CLOSED(self);
7917 MYDB_BEGIN_ALLOW_THREADS;
7918 err = self->db_env->repmgr_add_remote_site(self->db_env, host, port, &eidp, flags);
7919 MYDB_END_ALLOW_THREADS;
7920 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007921 return NUMBER_FromLong(eidp);
Jesus Ceaef9764f2008-05-13 18:45:46 +00007922}
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07007923#endif
Jesus Ceaef9764f2008-05-13 18:45:46 +00007924
7925static PyObject*
7926DBEnv_repmgr_set_ack_policy(DBEnvObject* self, PyObject* args)
7927{
7928 int err;
7929 int ack_policy;
7930
7931 if (!PyArg_ParseTuple(args, "i:repmgr_set_ack_policy", &ack_policy))
7932 {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00007933 return NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00007934 }
7935 CHECK_ENV_NOT_CLOSED(self);
7936 MYDB_BEGIN_ALLOW_THREADS;
7937 err = self->db_env->repmgr_set_ack_policy(self->db_env, ack_policy);
7938 MYDB_END_ALLOW_THREADS;
7939 RETURN_IF_ERR();
7940 RETURN_NONE();
7941}
7942
7943static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007944DBEnv_repmgr_get_ack_policy(DBEnvObject* self)
Jesus Ceaef9764f2008-05-13 18:45:46 +00007945{
7946 int err;
7947 int ack_policy;
7948
Jesus Ceaef9764f2008-05-13 18:45:46 +00007949 CHECK_ENV_NOT_CLOSED(self);
7950 MYDB_BEGIN_ALLOW_THREADS;
7951 err = self->db_env->repmgr_get_ack_policy(self->db_env, &ack_policy);
7952 MYDB_END_ALLOW_THREADS;
7953 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007954 return NUMBER_FromLong(ack_policy);
Jesus Ceaef9764f2008-05-13 18:45:46 +00007955}
7956
7957static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007958DBEnv_repmgr_site_list(DBEnvObject* self)
Jesus Ceaef9764f2008-05-13 18:45:46 +00007959{
7960 int err;
7961 unsigned int countp;
7962 DB_REPMGR_SITE *listp;
7963 PyObject *stats, *key, *tuple;
7964
Jesus Ceaef9764f2008-05-13 18:45:46 +00007965 CHECK_ENV_NOT_CLOSED(self);
7966 MYDB_BEGIN_ALLOW_THREADS;
7967 err = self->db_env->repmgr_site_list(self->db_env, &countp, &listp);
7968 MYDB_END_ALLOW_THREADS;
7969 RETURN_IF_ERR();
7970
7971 stats=PyDict_New();
7972 if (stats == NULL) {
7973 free(listp);
7974 return NULL;
7975 }
7976
7977 for(;countp--;) {
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007978 key=NUMBER_FromLong(listp[countp].eid);
Jesus Ceaef9764f2008-05-13 18:45:46 +00007979 if(!key) {
7980 Py_DECREF(stats);
7981 free(listp);
7982 return NULL;
7983 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00007984 tuple=Py_BuildValue("(sII)", listp[countp].host,
7985 listp[countp].port, listp[countp].status);
Jesus Ceaef9764f2008-05-13 18:45:46 +00007986 if(!tuple) {
7987 Py_DECREF(key);
7988 Py_DECREF(stats);
7989 free(listp);
7990 return NULL;
7991 }
7992 if(PyDict_SetItem(stats, key, tuple)) {
7993 Py_DECREF(key);
7994 Py_DECREF(tuple);
7995 Py_DECREF(stats);
7996 free(listp);
7997 return NULL;
7998 }
Florent Xiclunae7901c52010-03-01 20:45:01 +00007999 Py_DECREF(key);
8000 Py_DECREF(tuple);
Jesus Ceaef9764f2008-05-13 18:45:46 +00008001 }
8002 free(listp);
8003 return stats;
8004}
8005#endif
8006
8007#if (DBVER >= 46)
8008static PyObject*
8009DBEnv_repmgr_stat_print(DBEnvObject* self, PyObject* args, PyObject *kwargs)
8010{
8011 int err;
8012 int flags=0;
8013 static char* kwnames[] = { "flags", NULL };
8014
8015 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:repmgr_stat_print",
8016 kwnames, &flags))
8017 {
8018 return NULL;
8019 }
8020 CHECK_ENV_NOT_CLOSED(self);
8021 MYDB_BEGIN_ALLOW_THREADS;
8022 err = self->db_env->repmgr_stat_print(self->db_env, flags);
8023 MYDB_END_ALLOW_THREADS;
8024 RETURN_IF_ERR();
8025 RETURN_NONE();
8026}
8027
8028static PyObject*
8029DBEnv_repmgr_stat(DBEnvObject* self, PyObject* args, PyObject *kwargs)
8030{
8031 int err;
8032 int flags=0;
8033 DB_REPMGR_STAT *statp;
8034 PyObject *stats;
8035 static char* kwnames[] = { "flags", NULL };
8036
8037 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:repmgr_stat",
8038 kwnames, &flags))
8039 {
8040 return NULL;
8041 }
8042 CHECK_ENV_NOT_CLOSED(self);
8043 MYDB_BEGIN_ALLOW_THREADS;
8044 err = self->db_env->repmgr_stat(self->db_env, &statp, flags);
8045 MYDB_END_ALLOW_THREADS;
8046 RETURN_IF_ERR();
8047
8048 stats=PyDict_New();
8049 if (stats == NULL) {
8050 free(statp);
8051 return NULL;
8052 }
8053
8054#define MAKE_ENTRY(name) _addIntToDict(stats, #name, statp->st_##name)
8055
8056 MAKE_ENTRY(perm_failed);
8057 MAKE_ENTRY(msgs_queued);
8058 MAKE_ENTRY(msgs_dropped);
8059 MAKE_ENTRY(connection_drop);
8060 MAKE_ENTRY(connect_fail);
8061
8062#undef MAKE_ENTRY
8063
8064 free(statp);
8065 return stats;
8066}
8067#endif
8068
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008069
8070/* --------------------------------------------------------------------- */
8071/* DBTxn methods */
8072
8073
Jesus Ceaef9764f2008-05-13 18:45:46 +00008074static void _close_transaction_cursors(DBTxnObject* txn)
8075{
8076 PyObject *dummy;
8077
8078 while(txn->children_cursors) {
8079 PyErr_Warn(PyExc_RuntimeWarning,
8080 "Must close cursors before resolving a transaction.");
8081 dummy=DBC_close_internal(txn->children_cursors);
8082 Py_XDECREF(dummy);
8083 }
8084}
8085
8086static void _promote_transaction_dbs_and_sequences(DBTxnObject *txn)
8087{
8088 DBObject *db;
Jesus Ceaef9764f2008-05-13 18:45:46 +00008089 DBSequenceObject *dbs;
Jesus Ceaef9764f2008-05-13 18:45:46 +00008090
8091 while (txn->children_dbs) {
8092 db=txn->children_dbs;
8093 EXTRACT_FROM_DOUBLE_LINKED_LIST_TXN(db);
8094 if (txn->parent_txn) {
8095 INSERT_IN_DOUBLE_LINKED_LIST_TXN(txn->parent_txn->children_dbs,db);
8096 db->txn=txn->parent_txn;
8097 } else {
8098 /* The db is already linked to its environment,
8099 ** so nothing to do.
8100 */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00008101 db->txn=NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00008102 }
8103 }
8104
Jesus Ceaef9764f2008-05-13 18:45:46 +00008105 while (txn->children_sequences) {
8106 dbs=txn->children_sequences;
8107 EXTRACT_FROM_DOUBLE_LINKED_LIST_TXN(dbs);
8108 if (txn->parent_txn) {
8109 INSERT_IN_DOUBLE_LINKED_LIST_TXN(txn->parent_txn->children_sequences,dbs);
8110 dbs->txn=txn->parent_txn;
8111 } else {
8112 /* The sequence is already linked to its
8113 ** parent db. Nothing to do.
8114 */
8115 dbs->txn=NULL;
8116 }
8117 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00008118}
8119
8120
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008121static PyObject*
8122DBTxn_commit(DBTxnObject* self, PyObject* args)
8123{
8124 int flags=0, err;
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008125 DB_TXN *txn;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008126
8127 if (!PyArg_ParseTuple(args, "|i:commit", &flags))
8128 return NULL;
8129
Jesus Ceaef9764f2008-05-13 18:45:46 +00008130 _close_transaction_cursors(self);
8131
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008132 if (!self->txn) {
Thomas Woutersb3153832006-03-08 01:47:19 +00008133 PyObject *t = Py_BuildValue("(is)", 0, "DBTxn must not be used "
Jesus Ceaef9764f2008-05-13 18:45:46 +00008134 "after txn_commit, txn_abort "
8135 "or txn_discard");
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008136 if (t) {
8137 PyErr_SetObject(DBError, t);
8138 Py_DECREF(t);
8139 }
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008140 return NULL;
8141 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00008142 self->flag_prepare=0;
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008143 txn = self->txn;
8144 self->txn = NULL; /* this DB_TXN is no longer valid after this call */
Jesus Ceaef9764f2008-05-13 18:45:46 +00008145
8146 EXTRACT_FROM_DOUBLE_LINKED_LIST(self);
8147
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008148 MYDB_BEGIN_ALLOW_THREADS;
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008149 err = txn->commit(txn, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008150 MYDB_END_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00008151
8152 _promote_transaction_dbs_and_sequences(self);
8153
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008154 RETURN_IF_ERR();
8155 RETURN_NONE();
8156}
8157
8158static PyObject*
8159DBTxn_prepare(DBTxnObject* self, PyObject* args)
8160{
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008161 int err;
8162 char* gid=NULL;
8163 int gid_size=0;
8164
8165 if (!PyArg_ParseTuple(args, "s#:prepare", &gid, &gid_size))
8166 return NULL;
8167
Matthias Klose54cc5392010-03-15 12:46:18 +00008168 if (gid_size != DB_GID_SIZE) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008169 PyErr_SetString(PyExc_TypeError,
Matthias Klose54cc5392010-03-15 12:46:18 +00008170 "gid must be DB_GID_SIZE bytes long");
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008171 return NULL;
8172 }
8173
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008174 if (!self->txn) {
Thomas Woutersb3153832006-03-08 01:47:19 +00008175 PyObject *t = Py_BuildValue("(is)", 0,"DBTxn must not be used "
Jesus Ceaef9764f2008-05-13 18:45:46 +00008176 "after txn_commit, txn_abort "
8177 "or txn_discard");
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008178 if (t) {
8179 PyErr_SetObject(DBError, t);
8180 Py_DECREF(t);
8181 }
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008182 return NULL;
8183 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00008184 self->flag_prepare=1; /* Prepare state */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008185 MYDB_BEGIN_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008186 err = self->txn->prepare(self->txn, (u_int8_t*)gid);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008187 MYDB_END_ALLOW_THREADS;
8188 RETURN_IF_ERR();
8189 RETURN_NONE();
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008190}
8191
8192
8193static PyObject*
Jesus Ceaef9764f2008-05-13 18:45:46 +00008194DBTxn_abort_discard_internal(DBTxnObject* self, int discard)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008195{
Jesus Ceaef9764f2008-05-13 18:45:46 +00008196 PyObject *dummy;
8197 int err=0;
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008198 DB_TXN *txn;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008199
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008200 if (!self->txn) {
Thomas Woutersb3153832006-03-08 01:47:19 +00008201 PyObject *t = Py_BuildValue("(is)", 0, "DBTxn must not be used "
Jesus Ceaef9764f2008-05-13 18:45:46 +00008202 "after txn_commit, txn_abort "
8203 "or txn_discard");
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008204 if (t) {
8205 PyErr_SetObject(DBError, t);
8206 Py_DECREF(t);
8207 }
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008208 return NULL;
8209 }
8210 txn = self->txn;
8211 self->txn = NULL; /* this DB_TXN is no longer valid after this call */
Jesus Ceaef9764f2008-05-13 18:45:46 +00008212
8213 _close_transaction_cursors(self);
Jesus Ceaef9764f2008-05-13 18:45:46 +00008214 while (self->children_sequences) {
8215 dummy=DBSequence_close_internal(self->children_sequences,0,0);
8216 Py_XDECREF(dummy);
8217 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00008218 while (self->children_dbs) {
Jesus Cea5cd5f122008-09-23 18:54:08 +00008219 dummy=DB_close_internal(self->children_dbs, 0, 0);
Jesus Ceaef9764f2008-05-13 18:45:46 +00008220 Py_XDECREF(dummy);
8221 }
8222
8223 EXTRACT_FROM_DOUBLE_LINKED_LIST(self);
8224
8225 MYDB_BEGIN_ALLOW_THREADS;
8226 if (discard) {
8227 assert(!self->flag_prepare);
Jesus Ceaef9764f2008-05-13 18:45:46 +00008228 err = txn->discard(txn,0);
Jesus Ceaef9764f2008-05-13 18:45:46 +00008229 } else {
8230 /*
8231 ** If the transaction is in the "prepare" or "recover" state,
8232 ** we better do not implicitly abort it.
8233 */
8234 if (!self->flag_prepare) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00008235 err = txn->abort(txn);
Jesus Ceaef9764f2008-05-13 18:45:46 +00008236 }
8237 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008238 MYDB_END_ALLOW_THREADS;
8239 RETURN_IF_ERR();
8240 RETURN_NONE();
8241}
8242
Jesus Ceaef9764f2008-05-13 18:45:46 +00008243static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008244DBTxn_abort(DBTxnObject* self)
Jesus Ceaef9764f2008-05-13 18:45:46 +00008245{
Jesus Ceaef9764f2008-05-13 18:45:46 +00008246 self->flag_prepare=0;
8247 _close_transaction_cursors(self);
8248
8249 return DBTxn_abort_discard_internal(self,0);
8250}
8251
8252static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008253DBTxn_discard(DBTxnObject* self)
Jesus Ceaef9764f2008-05-13 18:45:46 +00008254{
Jesus Ceaef9764f2008-05-13 18:45:46 +00008255 self->flag_prepare=0;
8256 _close_transaction_cursors(self);
8257
8258 return DBTxn_abort_discard_internal(self,1);
8259}
8260
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008261
8262static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008263DBTxn_id(DBTxnObject* self)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008264{
8265 int id;
8266
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008267 if (!self->txn) {
Thomas Woutersb3153832006-03-08 01:47:19 +00008268 PyObject *t = Py_BuildValue("(is)", 0, "DBTxn must not be used "
Jesus Ceaef9764f2008-05-13 18:45:46 +00008269 "after txn_commit, txn_abort "
8270 "or txn_discard");
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008271 if (t) {
8272 PyErr_SetObject(DBError, t);
8273 Py_DECREF(t);
8274 }
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008275 return NULL;
8276 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008277 MYDB_BEGIN_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008278 id = self->txn->id(self->txn);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008279 MYDB_END_ALLOW_THREADS;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008280 return NUMBER_FromLong(id);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008281}
8282
Jesus Cea6557aac2010-03-22 14:22:26 +00008283
8284static PyObject*
8285DBTxn_set_timeout(DBTxnObject* self, PyObject* args, PyObject* kwargs)
8286{
8287 int err;
8288 u_int32_t flags=0;
8289 u_int32_t timeout = 0;
8290 static char* kwnames[] = { "timeout", "flags", NULL };
8291
8292 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ii:set_timeout", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00008293 &timeout, &flags)) {
8294 return NULL;
Jesus Cea6557aac2010-03-22 14:22:26 +00008295 }
8296
8297 MYDB_BEGIN_ALLOW_THREADS;
8298 err = self->txn->set_timeout(self->txn, (db_timeout_t)timeout, flags);
8299 MYDB_END_ALLOW_THREADS;
8300
8301 RETURN_IF_ERR();
8302 RETURN_NONE();
8303}
8304
8305
8306#if (DBVER >= 44)
8307static PyObject*
8308DBTxn_set_name(DBTxnObject* self, PyObject* args)
8309{
8310 int err;
8311 const char *name;
8312
8313 if (!PyArg_ParseTuple(args, "s:set_name", &name))
8314 return NULL;
8315
8316 MYDB_BEGIN_ALLOW_THREADS;
8317 err = self->txn->set_name(self->txn, name);
8318 MYDB_END_ALLOW_THREADS;
8319
8320 RETURN_IF_ERR();
8321 RETURN_NONE();
8322}
8323#endif
8324
8325
8326#if (DBVER >= 44)
8327static PyObject*
8328DBTxn_get_name(DBTxnObject* self)
8329{
8330 int err;
8331 const char *name;
8332
8333 MYDB_BEGIN_ALLOW_THREADS;
8334 err = self->txn->get_name(self->txn, &name);
8335 MYDB_END_ALLOW_THREADS;
8336
8337 RETURN_IF_ERR();
8338#if (PY_VERSION_HEX < 0x03000000)
8339 if (!name) {
8340 return PyString_FromString("");
8341 }
8342 return PyString_FromString(name);
8343#else
8344 if (!name) {
8345 return PyUnicode_FromString("");
8346 }
8347 return PyUnicode_FromString(name);
8348#endif
8349}
8350#endif
8351
8352
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008353/* --------------------------------------------------------------------- */
8354/* DBSequence methods */
8355
8356
8357static PyObject*
Jesus Ceaef9764f2008-05-13 18:45:46 +00008358DBSequence_close_internal(DBSequenceObject* self, int flags, int do_not_close)
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008359{
Jesus Ceaef9764f2008-05-13 18:45:46 +00008360 int err=0;
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008361
Jesus Ceaef9764f2008-05-13 18:45:46 +00008362 if (self->sequence!=NULL) {
8363 EXTRACT_FROM_DOUBLE_LINKED_LIST(self);
8364 if (self->txn) {
8365 EXTRACT_FROM_DOUBLE_LINKED_LIST_TXN(self);
8366 self->txn=NULL;
8367 }
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008368
Jesus Cea5cd5f122008-09-23 18:54:08 +00008369 /*
8370 ** "do_not_close" is used to dispose all related objects in the
8371 ** tree, without actually releasing the "root" object.
8372 ** This is done, for example, because function calls like
8373 ** "DBSequence.remove()" implicitly close the underlying handle. So
8374 ** the handle doesn't need to be closed, but related objects
8375 ** must be cleaned up.
8376 */
Jesus Ceaef9764f2008-05-13 18:45:46 +00008377 if (!do_not_close) {
8378 MYDB_BEGIN_ALLOW_THREADS
8379 err = self->sequence->close(self->sequence, flags);
8380 MYDB_END_ALLOW_THREADS
8381 }
8382 self->sequence = NULL;
8383
8384 RETURN_IF_ERR();
8385 }
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008386
8387 RETURN_NONE();
8388}
8389
8390static PyObject*
Jesus Ceaef9764f2008-05-13 18:45:46 +00008391DBSequence_close(DBSequenceObject* self, PyObject* args)
8392{
8393 int flags=0;
8394 if (!PyArg_ParseTuple(args,"|i:close", &flags))
8395 return NULL;
8396
8397 return DBSequence_close_internal(self,flags,0);
8398}
8399
8400static PyObject*
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008401DBSequence_get(DBSequenceObject* self, PyObject* args, PyObject* kwargs)
8402{
8403 int err, flags = 0;
8404 int delta = 1;
8405 db_seq_t value;
8406 PyObject *txnobj = NULL;
8407 DB_TXN *txn = NULL;
8408 static char* kwnames[] = {"delta", "txn", "flags", NULL };
8409 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|iOi:get", kwnames, &delta, &txnobj, &flags))
8410 return NULL;
8411 CHECK_SEQUENCE_NOT_CLOSED(self)
8412
8413 if (!checkTxnObj(txnobj, &txn))
8414 return NULL;
8415
8416 MYDB_BEGIN_ALLOW_THREADS
8417 err = self->sequence->get(self->sequence, txn, delta, &value, flags);
8418 MYDB_END_ALLOW_THREADS
8419
8420 RETURN_IF_ERR();
8421 return PyLong_FromLongLong(value);
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008422}
8423
8424static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008425DBSequence_get_dbp(DBSequenceObject* self)
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008426{
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008427 CHECK_SEQUENCE_NOT_CLOSED(self)
8428 Py_INCREF(self->mydb);
8429 return (PyObject* )self->mydb;
8430}
8431
8432static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008433DBSequence_get_key(DBSequenceObject* self)
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008434{
8435 int err;
8436 DBT key;
Neal Norwitz088beae2007-10-12 03:01:54 +00008437 PyObject *retval = NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00008438
Gregory P. Smithe70be5c2007-10-06 07:48:10 +00008439 key.flags = DB_DBT_MALLOC;
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008440 CHECK_SEQUENCE_NOT_CLOSED(self)
8441 MYDB_BEGIN_ALLOW_THREADS
8442 err = self->sequence->get_key(self->sequence, &key);
8443 MYDB_END_ALLOW_THREADS
8444
Gregory P. Smithe70be5c2007-10-06 07:48:10 +00008445 if (!err)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008446 retval = Build_PyString(key.data, key.size);
Gregory P. Smithe70be5c2007-10-06 07:48:10 +00008447
8448 FREE_DBT(key);
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008449 RETURN_IF_ERR();
8450
Gregory P. Smithe70be5c2007-10-06 07:48:10 +00008451 return retval;
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008452}
8453
8454static PyObject*
Jesus Cea6557aac2010-03-22 14:22:26 +00008455DBSequence_initial_value(DBSequenceObject* self, PyObject* args)
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008456{
8457 int err;
Jesus Ceaef9764f2008-05-13 18:45:46 +00008458 PY_LONG_LONG value;
8459 db_seq_t value2;
Jesus Cea6557aac2010-03-22 14:22:26 +00008460 if (!PyArg_ParseTuple(args,"L:initial_value", &value))
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008461 return NULL;
8462 CHECK_SEQUENCE_NOT_CLOSED(self)
8463
Jesus Ceaef9764f2008-05-13 18:45:46 +00008464 value2=value; /* If truncation, compiler should show a warning */
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008465 MYDB_BEGIN_ALLOW_THREADS
Jesus Ceaef9764f2008-05-13 18:45:46 +00008466 err = self->sequence->initial_value(self->sequence, value2);
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008467 MYDB_END_ALLOW_THREADS
8468
8469 RETURN_IF_ERR();
8470
8471 RETURN_NONE();
8472}
8473
8474static PyObject*
8475DBSequence_open(DBSequenceObject* self, PyObject* args, PyObject* kwargs)
8476{
8477 int err, flags = 0;
8478 PyObject* keyobj;
8479 PyObject *txnobj = NULL;
8480 DB_TXN *txn = NULL;
8481 DBT key;
8482
8483 static char* kwnames[] = {"key", "txn", "flags", NULL };
Neal Norwitzdd2a6bf2006-06-06 07:23:01 +00008484 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|Oi:open", kwnames, &keyobj, &txnobj, &flags))
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008485 return NULL;
8486
8487 if (!checkTxnObj(txnobj, &txn))
8488 return NULL;
8489
8490 if (!make_key_dbt(self->mydb, keyobj, &key, NULL))
8491 return NULL;
8492
8493 MYDB_BEGIN_ALLOW_THREADS
8494 err = self->sequence->open(self->sequence, txn, &key, flags);
8495 MYDB_END_ALLOW_THREADS
8496
Jesus Ceaac25fab2008-09-03 17:50:32 +00008497 FREE_DBT(key);
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008498 RETURN_IF_ERR();
8499
Jesus Ceaef9764f2008-05-13 18:45:46 +00008500 if (txn) {
8501 INSERT_IN_DOUBLE_LINKED_LIST_TXN(((DBTxnObject *)txnobj)->children_sequences,self);
8502 self->txn=(DBTxnObject *)txnobj;
8503 }
8504
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008505 RETURN_NONE();
8506}
8507
8508static PyObject*
8509DBSequence_remove(DBSequenceObject* self, PyObject* args, PyObject* kwargs)
8510{
Jesus Ceaef9764f2008-05-13 18:45:46 +00008511 PyObject *dummy;
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008512 int err, flags = 0;
8513 PyObject *txnobj = NULL;
8514 DB_TXN *txn = NULL;
8515
8516 static char* kwnames[] = {"txn", "flags", NULL };
Neal Norwitzdd2a6bf2006-06-06 07:23:01 +00008517 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Oi:remove", kwnames, &txnobj, &flags))
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008518 return NULL;
8519
8520 if (!checkTxnObj(txnobj, &txn))
8521 return NULL;
8522
8523 CHECK_SEQUENCE_NOT_CLOSED(self)
8524
8525 MYDB_BEGIN_ALLOW_THREADS
8526 err = self->sequence->remove(self->sequence, txn, flags);
8527 MYDB_END_ALLOW_THREADS
8528
Jesus Ceaef9764f2008-05-13 18:45:46 +00008529 dummy=DBSequence_close_internal(self,flags,1);
8530 Py_XDECREF(dummy);
8531
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008532 RETURN_IF_ERR();
8533 RETURN_NONE();
8534}
8535
8536static PyObject*
8537DBSequence_set_cachesize(DBSequenceObject* self, PyObject* args)
8538{
8539 int err, size;
Neal Norwitzdd2a6bf2006-06-06 07:23:01 +00008540 if (!PyArg_ParseTuple(args,"i:set_cachesize", &size))
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008541 return NULL;
8542 CHECK_SEQUENCE_NOT_CLOSED(self)
8543
8544 MYDB_BEGIN_ALLOW_THREADS
8545 err = self->sequence->set_cachesize(self->sequence, size);
8546 MYDB_END_ALLOW_THREADS
8547
8548 RETURN_IF_ERR();
8549 RETURN_NONE();
8550}
8551
8552static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008553DBSequence_get_cachesize(DBSequenceObject* self)
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008554{
8555 int err, size;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008556
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008557 CHECK_SEQUENCE_NOT_CLOSED(self)
8558
8559 MYDB_BEGIN_ALLOW_THREADS
8560 err = self->sequence->get_cachesize(self->sequence, &size);
8561 MYDB_END_ALLOW_THREADS
8562
8563 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008564 return NUMBER_FromLong(size);
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008565}
8566
8567static PyObject*
8568DBSequence_set_flags(DBSequenceObject* self, PyObject* args)
8569{
8570 int err, flags = 0;
Neal Norwitzdd2a6bf2006-06-06 07:23:01 +00008571 if (!PyArg_ParseTuple(args,"i:set_flags", &flags))
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008572 return NULL;
8573 CHECK_SEQUENCE_NOT_CLOSED(self)
8574
8575 MYDB_BEGIN_ALLOW_THREADS
8576 err = self->sequence->set_flags(self->sequence, flags);
8577 MYDB_END_ALLOW_THREADS
8578
8579 RETURN_IF_ERR();
8580 RETURN_NONE();
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008581}
8582
8583static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008584DBSequence_get_flags(DBSequenceObject* self)
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008585{
8586 unsigned int flags;
8587 int err;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008588
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008589 CHECK_SEQUENCE_NOT_CLOSED(self)
8590
8591 MYDB_BEGIN_ALLOW_THREADS
8592 err = self->sequence->get_flags(self->sequence, &flags);
8593 MYDB_END_ALLOW_THREADS
8594
8595 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008596 return NUMBER_FromLong((int)flags);
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008597}
8598
8599static PyObject*
8600DBSequence_set_range(DBSequenceObject* self, PyObject* args)
8601{
8602 int err;
Jesus Ceaef9764f2008-05-13 18:45:46 +00008603 PY_LONG_LONG min, max;
8604 db_seq_t min2, max2;
Tim Petersbb21b2c2006-06-06 15:50:17 +00008605 if (!PyArg_ParseTuple(args,"(LL):set_range", &min, &max))
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008606 return NULL;
8607 CHECK_SEQUENCE_NOT_CLOSED(self)
8608
Jesus Ceaef9764f2008-05-13 18:45:46 +00008609 min2=min; /* If truncation, compiler should show a warning */
8610 max2=max;
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008611 MYDB_BEGIN_ALLOW_THREADS
Jesus Ceaef9764f2008-05-13 18:45:46 +00008612 err = self->sequence->set_range(self->sequence, min2, max2);
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008613 MYDB_END_ALLOW_THREADS
8614
8615 RETURN_IF_ERR();
8616 RETURN_NONE();
8617}
8618
8619static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008620DBSequence_get_range(DBSequenceObject* self)
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008621{
8622 int err;
Jesus Ceaef9764f2008-05-13 18:45:46 +00008623 PY_LONG_LONG min, max;
8624 db_seq_t min2, max2;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008625
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008626 CHECK_SEQUENCE_NOT_CLOSED(self)
8627
8628 MYDB_BEGIN_ALLOW_THREADS
Jesus Ceaef9764f2008-05-13 18:45:46 +00008629 err = self->sequence->get_range(self->sequence, &min2, &max2);
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008630 MYDB_END_ALLOW_THREADS
8631
8632 RETURN_IF_ERR();
Jesus Ceaef9764f2008-05-13 18:45:46 +00008633 min=min2; /* If truncation, compiler should show a warning */
8634 max=max2;
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008635 return Py_BuildValue("(LL)", min, max);
8636}
8637
Jesus Cea6557aac2010-03-22 14:22:26 +00008638
8639static PyObject*
8640DBSequence_stat_print(DBSequenceObject* self, PyObject* args, PyObject *kwargs)
8641{
8642 int err;
8643 int flags=0;
8644 static char* kwnames[] = { "flags", NULL };
8645
8646 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:stat_print",
8647 kwnames, &flags))
8648 {
8649 return NULL;
8650 }
8651
8652 CHECK_SEQUENCE_NOT_CLOSED(self);
8653
8654 MYDB_BEGIN_ALLOW_THREADS;
8655 err = self->sequence->stat_print(self->sequence, flags);
8656 MYDB_END_ALLOW_THREADS;
8657 RETURN_IF_ERR();
8658 RETURN_NONE();
8659}
8660
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008661static PyObject*
8662DBSequence_stat(DBSequenceObject* self, PyObject* args, PyObject* kwargs)
8663{
8664 int err, flags = 0;
8665 DB_SEQUENCE_STAT* sp = NULL;
8666 PyObject* dict_stat;
8667 static char* kwnames[] = {"flags", NULL };
8668 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:stat", kwnames, &flags))
8669 return NULL;
8670 CHECK_SEQUENCE_NOT_CLOSED(self);
8671
8672 MYDB_BEGIN_ALLOW_THREADS;
8673 err = self->sequence->stat(self->sequence, &sp, flags);
8674 MYDB_END_ALLOW_THREADS;
8675 RETURN_IF_ERR();
8676
8677 if ((dict_stat = PyDict_New()) == NULL) {
8678 free(sp);
8679 return NULL;
8680 }
8681
8682
8683#define MAKE_INT_ENTRY(name) _addIntToDict(dict_stat, #name, sp->st_##name)
8684#define MAKE_LONG_LONG_ENTRY(name) _addDb_seq_tToDict(dict_stat, #name, sp->st_##name)
8685
8686 MAKE_INT_ENTRY(wait);
8687 MAKE_INT_ENTRY(nowait);
8688 MAKE_LONG_LONG_ENTRY(current);
8689 MAKE_LONG_LONG_ENTRY(value);
8690 MAKE_LONG_LONG_ENTRY(last_value);
8691 MAKE_LONG_LONG_ENTRY(min);
8692 MAKE_LONG_LONG_ENTRY(max);
8693 MAKE_INT_ENTRY(cache_size);
8694 MAKE_INT_ENTRY(flags);
8695
8696#undef MAKE_INT_ENTRY
8697#undef MAKE_LONG_LONG_ENTRY
8698
8699 free(sp);
8700 return dict_stat;
8701}
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008702
8703
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008704/* --------------------------------------------------------------------- */
8705/* Method definition tables and type objects */
8706
8707static PyMethodDef DB_methods[] = {
Jesus Cea4907d272008-08-31 14:00:51 +00008708 {"append", (PyCFunction)DB_append, METH_VARARGS|METH_KEYWORDS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008709 {"associate", (PyCFunction)DB_associate, METH_VARARGS|METH_KEYWORDS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008710 {"close", (PyCFunction)DB_close, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008711#if (DBVER >= 47)
8712 {"compact", (PyCFunction)DB_compact, METH_VARARGS|METH_KEYWORDS},
8713#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008714 {"consume", (PyCFunction)DB_consume, METH_VARARGS|METH_KEYWORDS},
8715 {"consume_wait", (PyCFunction)DB_consume_wait, METH_VARARGS|METH_KEYWORDS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008716 {"cursor", (PyCFunction)DB_cursor, METH_VARARGS|METH_KEYWORDS},
8717 {"delete", (PyCFunction)DB_delete, METH_VARARGS|METH_KEYWORDS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008718 {"fd", (PyCFunction)DB_fd, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008719#if (DBVER >= 46)
8720 {"exists", (PyCFunction)DB_exists,
8721 METH_VARARGS|METH_KEYWORDS},
8722#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008723 {"get", (PyCFunction)DB_get, METH_VARARGS|METH_KEYWORDS},
Gregory P. Smith19699a92004-06-28 04:06:49 +00008724 {"pget", (PyCFunction)DB_pget, METH_VARARGS|METH_KEYWORDS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008725 {"get_both", (PyCFunction)DB_get_both, METH_VARARGS|METH_KEYWORDS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008726 {"get_byteswapped", (PyCFunction)DB_get_byteswapped,METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008727 {"get_size", (PyCFunction)DB_get_size, METH_VARARGS|METH_KEYWORDS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008728 {"get_type", (PyCFunction)DB_get_type, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008729 {"join", (PyCFunction)DB_join, METH_VARARGS},
8730 {"key_range", (PyCFunction)DB_key_range, METH_VARARGS|METH_KEYWORDS},
Jesus Cea4907d272008-08-31 14:00:51 +00008731 {"has_key", (PyCFunction)DB_has_key, METH_VARARGS|METH_KEYWORDS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008732 {"items", (PyCFunction)DB_items, METH_VARARGS},
8733 {"keys", (PyCFunction)DB_keys, METH_VARARGS},
8734 {"open", (PyCFunction)DB_open, METH_VARARGS|METH_KEYWORDS},
8735 {"put", (PyCFunction)DB_put, METH_VARARGS|METH_KEYWORDS},
8736 {"remove", (PyCFunction)DB_remove, METH_VARARGS|METH_KEYWORDS},
8737 {"rename", (PyCFunction)DB_rename, METH_VARARGS},
8738 {"set_bt_minkey", (PyCFunction)DB_set_bt_minkey, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008739 {"get_bt_minkey", (PyCFunction)DB_get_bt_minkey, METH_NOARGS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008740 {"set_bt_compare", (PyCFunction)DB_set_bt_compare, METH_O},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008741 {"set_cachesize", (PyCFunction)DB_set_cachesize, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008742 {"get_cachesize", (PyCFunction)DB_get_cachesize, METH_NOARGS},
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07008743 {"set_dup_compare", (PyCFunction)DB_set_dup_compare, METH_O},
Jesus Cea6557aac2010-03-22 14:22:26 +00008744 {"set_encrypt", (PyCFunction)DB_set_encrypt, METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008745 {"get_encrypt_flags", (PyCFunction)DB_get_encrypt_flags, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008746 {"set_flags", (PyCFunction)DB_set_flags, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008747 {"get_flags", (PyCFunction)DB_get_flags, METH_NOARGS},
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07008748 {"get_transactional", (PyCFunction)DB_get_transactional, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008749 {"set_h_ffactor", (PyCFunction)DB_set_h_ffactor, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008750 {"get_h_ffactor", (PyCFunction)DB_get_h_ffactor, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008751 {"set_h_nelem", (PyCFunction)DB_set_h_nelem, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008752 {"get_h_nelem", (PyCFunction)DB_get_h_nelem, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008753 {"set_lorder", (PyCFunction)DB_set_lorder, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008754 {"get_lorder", (PyCFunction)DB_get_lorder, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008755 {"set_pagesize", (PyCFunction)DB_set_pagesize, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008756 {"get_pagesize", (PyCFunction)DB_get_pagesize, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008757 {"set_re_delim", (PyCFunction)DB_set_re_delim, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008758 {"get_re_delim", (PyCFunction)DB_get_re_delim, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008759 {"set_re_len", (PyCFunction)DB_set_re_len, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008760 {"get_re_len", (PyCFunction)DB_get_re_len, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008761 {"set_re_pad", (PyCFunction)DB_set_re_pad, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008762 {"get_re_pad", (PyCFunction)DB_get_re_pad, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008763 {"set_re_source", (PyCFunction)DB_set_re_source, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008764 {"get_re_source", (PyCFunction)DB_get_re_source, METH_NOARGS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008765 {"set_q_extentsize",(PyCFunction)DB_set_q_extentsize, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008766 {"get_q_extentsize",(PyCFunction)DB_get_q_extentsize, METH_NOARGS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008767 {"set_private", (PyCFunction)DB_set_private, METH_O},
8768 {"get_private", (PyCFunction)DB_get_private, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008769#if (DBVER >= 46)
8770 {"set_priority", (PyCFunction)DB_set_priority, METH_VARARGS},
8771 {"get_priority", (PyCFunction)DB_get_priority, METH_NOARGS},
8772#endif
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07008773 {"get_dbname", (PyCFunction)DB_get_dbname, METH_NOARGS},
8774 {"get_open_flags", (PyCFunction)DB_get_open_flags, METH_NOARGS},
Gregory P. Smith8b7e9172004-12-13 09:51:23 +00008775 {"stat", (PyCFunction)DB_stat, METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008776 {"stat_print", (PyCFunction)DB_stat_print,
8777 METH_VARARGS|METH_KEYWORDS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008778 {"sync", (PyCFunction)DB_sync, METH_VARARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008779 {"truncate", (PyCFunction)DB_truncate, METH_VARARGS|METH_KEYWORDS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008780 {"type", (PyCFunction)DB_get_type, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008781 {"upgrade", (PyCFunction)DB_upgrade, METH_VARARGS},
8782 {"values", (PyCFunction)DB_values, METH_VARARGS},
8783 {"verify", (PyCFunction)DB_verify, METH_VARARGS|METH_KEYWORDS},
8784 {"set_get_returns_none",(PyCFunction)DB_set_get_returns_none, METH_VARARGS},
8785 {NULL, NULL} /* sentinel */
8786};
8787
8788
Jesus Cea6557aac2010-03-22 14:22:26 +00008789/* We need this to support __contains__() */
8790static PySequenceMethods DB_sequence = {
8791 0, /* sq_length, mapping wins here */
8792 0, /* sq_concat */
8793 0, /* sq_repeat */
8794 0, /* sq_item */
8795 0, /* sq_slice */
8796 0, /* sq_ass_item */
8797 0, /* sq_ass_slice */
8798 (objobjproc)DB_contains, /* sq_contains */
8799 0, /* sq_inplace_concat */
8800 0, /* sq_inplace_repeat */
8801};
8802
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008803static PyMappingMethods DB_mapping = {
Martin v. Löwis70ee3cc2006-06-12 04:26:31 +00008804 DB_length, /*mp_length*/
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008805 (binaryfunc)DB_subscript, /*mp_subscript*/
8806 (objobjargproc)DB_ass_sub, /*mp_ass_subscript*/
8807};
8808
8809
8810static PyMethodDef DBCursor_methods[] = {
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008811 {"close", (PyCFunction)DBC_close, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008812 {"count", (PyCFunction)DBC_count, METH_VARARGS},
8813 {"current", (PyCFunction)DBC_current, METH_VARARGS|METH_KEYWORDS},
8814 {"delete", (PyCFunction)DBC_delete, METH_VARARGS},
8815 {"dup", (PyCFunction)DBC_dup, METH_VARARGS},
8816 {"first", (PyCFunction)DBC_first, METH_VARARGS|METH_KEYWORDS},
8817 {"get", (PyCFunction)DBC_get, METH_VARARGS|METH_KEYWORDS},
Gregory P. Smith19699a92004-06-28 04:06:49 +00008818 {"pget", (PyCFunction)DBC_pget, METH_VARARGS|METH_KEYWORDS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008819 {"get_recno", (PyCFunction)DBC_get_recno, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008820 {"last", (PyCFunction)DBC_last, METH_VARARGS|METH_KEYWORDS},
8821 {"next", (PyCFunction)DBC_next, METH_VARARGS|METH_KEYWORDS},
8822 {"prev", (PyCFunction)DBC_prev, METH_VARARGS|METH_KEYWORDS},
8823 {"put", (PyCFunction)DBC_put, METH_VARARGS|METH_KEYWORDS},
8824 {"set", (PyCFunction)DBC_set, METH_VARARGS|METH_KEYWORDS},
8825 {"set_range", (PyCFunction)DBC_set_range, METH_VARARGS|METH_KEYWORDS},
8826 {"get_both", (PyCFunction)DBC_get_both, METH_VARARGS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008827 {"get_current_size",(PyCFunction)DBC_get_current_size, METH_NOARGS},
Gregory P. Smith455d46f2003-07-09 04:45:59 +00008828 {"set_both", (PyCFunction)DBC_set_both, METH_VARARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008829 {"set_recno", (PyCFunction)DBC_set_recno, METH_VARARGS|METH_KEYWORDS},
8830 {"consume", (PyCFunction)DBC_consume, METH_VARARGS|METH_KEYWORDS},
8831 {"next_dup", (PyCFunction)DBC_next_dup, METH_VARARGS|METH_KEYWORDS},
8832 {"next_nodup", (PyCFunction)DBC_next_nodup, METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008833#if (DBVER >= 46)
8834 {"prev_dup", (PyCFunction)DBC_prev_dup,
8835 METH_VARARGS|METH_KEYWORDS},
8836#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008837 {"prev_nodup", (PyCFunction)DBC_prev_nodup, METH_VARARGS|METH_KEYWORDS},
8838 {"join_item", (PyCFunction)DBC_join_item, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008839#if (DBVER >= 46)
8840 {"set_priority", (PyCFunction)DBC_set_priority,
8841 METH_VARARGS|METH_KEYWORDS},
8842 {"get_priority", (PyCFunction)DBC_get_priority, METH_NOARGS},
8843#endif
8844 {NULL, NULL} /* sentinel */
8845};
8846
8847
8848static PyMethodDef DBLogCursor_methods[] = {
8849 {"close", (PyCFunction)DBLogCursor_close, METH_NOARGS},
8850 {"current", (PyCFunction)DBLogCursor_current, METH_NOARGS},
8851 {"first", (PyCFunction)DBLogCursor_first, METH_NOARGS},
8852 {"last", (PyCFunction)DBLogCursor_last, METH_NOARGS},
8853 {"next", (PyCFunction)DBLogCursor_next, METH_NOARGS},
8854 {"prev", (PyCFunction)DBLogCursor_prev, METH_NOARGS},
8855 {"set", (PyCFunction)DBLogCursor_set, METH_VARARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008856 {NULL, NULL} /* sentinel */
8857};
8858
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07008859#if (DBVER >= 52)
8860static PyMethodDef DBSite_methods[] = {
8861 {"get_config", (PyCFunction)DBSite_get_config,
8862 METH_VARARGS | METH_KEYWORDS},
8863 {"set_config", (PyCFunction)DBSite_set_config,
8864 METH_VARARGS | METH_KEYWORDS},
8865 {"remove", (PyCFunction)DBSite_remove, METH_NOARGS},
8866 {"get_eid", (PyCFunction)DBSite_get_eid, METH_NOARGS},
8867 {"get_address", (PyCFunction)DBSite_get_address, METH_NOARGS},
8868 {"close", (PyCFunction)DBSite_close, METH_NOARGS},
8869 {NULL, NULL} /* sentinel */
8870};
8871#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008872
8873static PyMethodDef DBEnv_methods[] = {
8874 {"close", (PyCFunction)DBEnv_close, METH_VARARGS},
8875 {"open", (PyCFunction)DBEnv_open, METH_VARARGS},
8876 {"remove", (PyCFunction)DBEnv_remove, METH_VARARGS},
Barry Warsaw9a0d7792002-12-30 20:53:52 +00008877 {"dbremove", (PyCFunction)DBEnv_dbremove, METH_VARARGS|METH_KEYWORDS},
8878 {"dbrename", (PyCFunction)DBEnv_dbrename, METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008879#if (DBVER >= 46)
8880 {"set_thread_count", (PyCFunction)DBEnv_set_thread_count, METH_VARARGS},
8881 {"get_thread_count", (PyCFunction)DBEnv_get_thread_count, METH_NOARGS},
8882#endif
Barry Warsaw9a0d7792002-12-30 20:53:52 +00008883 {"set_encrypt", (PyCFunction)DBEnv_set_encrypt, METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008884 {"get_encrypt_flags", (PyCFunction)DBEnv_get_encrypt_flags, METH_NOARGS},
8885 {"get_timeout", (PyCFunction)DBEnv_get_timeout,
8886 METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008887 {"set_timeout", (PyCFunction)DBEnv_set_timeout, METH_VARARGS|METH_KEYWORDS},
8888 {"set_shm_key", (PyCFunction)DBEnv_set_shm_key, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008889 {"get_shm_key", (PyCFunction)DBEnv_get_shm_key, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008890#if (DBVER >= 46)
8891 {"set_cache_max", (PyCFunction)DBEnv_set_cache_max, METH_VARARGS},
8892 {"get_cache_max", (PyCFunction)DBEnv_get_cache_max, METH_NOARGS},
8893#endif
8894 {"set_cachesize", (PyCFunction)DBEnv_set_cachesize, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008895 {"get_cachesize", (PyCFunction)DBEnv_get_cachesize, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008896 {"memp_trickle", (PyCFunction)DBEnv_memp_trickle, METH_VARARGS},
8897 {"memp_sync", (PyCFunction)DBEnv_memp_sync, METH_VARARGS},
8898 {"memp_stat", (PyCFunction)DBEnv_memp_stat,
8899 METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008900 {"memp_stat_print", (PyCFunction)DBEnv_memp_stat_print,
8901 METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008902#if (DBVER >= 44)
8903 {"mutex_set_max", (PyCFunction)DBEnv_mutex_set_max, METH_VARARGS},
8904 {"mutex_get_max", (PyCFunction)DBEnv_mutex_get_max, METH_NOARGS},
8905 {"mutex_set_align", (PyCFunction)DBEnv_mutex_set_align, METH_VARARGS},
8906 {"mutex_get_align", (PyCFunction)DBEnv_mutex_get_align, METH_NOARGS},
8907 {"mutex_set_increment", (PyCFunction)DBEnv_mutex_set_increment,
8908 METH_VARARGS},
8909 {"mutex_get_increment", (PyCFunction)DBEnv_mutex_get_increment,
8910 METH_NOARGS},
8911 {"mutex_set_tas_spins", (PyCFunction)DBEnv_mutex_set_tas_spins,
8912 METH_VARARGS},
8913 {"mutex_get_tas_spins", (PyCFunction)DBEnv_mutex_get_tas_spins,
8914 METH_NOARGS},
8915 {"mutex_stat", (PyCFunction)DBEnv_mutex_stat, METH_VARARGS},
8916#if (DBVER >= 44)
8917 {"mutex_stat_print", (PyCFunction)DBEnv_mutex_stat_print,
8918 METH_VARARGS|METH_KEYWORDS},
8919#endif
8920#endif
8921 {"set_data_dir", (PyCFunction)DBEnv_set_data_dir, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008922 {"get_data_dirs", (PyCFunction)DBEnv_get_data_dirs, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008923 {"get_flags", (PyCFunction)DBEnv_get_flags, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008924 {"set_flags", (PyCFunction)DBEnv_set_flags, METH_VARARGS},
8925#if (DBVER >= 47)
8926 {"log_set_config", (PyCFunction)DBEnv_log_set_config, METH_VARARGS},
8927 {"log_get_config", (PyCFunction)DBEnv_log_get_config, METH_VARARGS},
8928#endif
8929 {"set_lg_bsize", (PyCFunction)DBEnv_set_lg_bsize, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008930 {"get_lg_bsize", (PyCFunction)DBEnv_get_lg_bsize, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008931 {"set_lg_dir", (PyCFunction)DBEnv_set_lg_dir, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008932 {"get_lg_dir", (PyCFunction)DBEnv_get_lg_dir, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008933 {"set_lg_max", (PyCFunction)DBEnv_set_lg_max, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008934 {"get_lg_max", (PyCFunction)DBEnv_get_lg_max, METH_NOARGS},
Gregory P. Smithe9477062005-06-04 06:46:59 +00008935 {"set_lg_regionmax",(PyCFunction)DBEnv_set_lg_regionmax, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008936 {"get_lg_regionmax",(PyCFunction)DBEnv_get_lg_regionmax, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008937#if (DBVER >= 44)
8938 {"set_lg_filemode", (PyCFunction)DBEnv_set_lg_filemode, METH_VARARGS},
8939 {"get_lg_filemode", (PyCFunction)DBEnv_get_lg_filemode, METH_NOARGS},
8940#endif
8941#if (DBVER >= 47)
8942 {"set_lk_partitions", (PyCFunction)DBEnv_set_lk_partitions, METH_VARARGS},
8943 {"get_lk_partitions", (PyCFunction)DBEnv_get_lk_partitions, METH_NOARGS},
8944#endif
8945 {"set_lk_detect", (PyCFunction)DBEnv_set_lk_detect, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008946 {"get_lk_detect", (PyCFunction)DBEnv_get_lk_detect, METH_NOARGS},
Gregory P. Smith8b96a352007-01-05 01:59:42 +00008947#if (DBVER < 45)
Jesus Cea6557aac2010-03-22 14:22:26 +00008948 {"set_lk_max", (PyCFunction)DBEnv_set_lk_max, METH_VARARGS},
Gregory P. Smith8b96a352007-01-05 01:59:42 +00008949#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008950 {"set_lk_max_locks", (PyCFunction)DBEnv_set_lk_max_locks, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008951 {"get_lk_max_locks", (PyCFunction)DBEnv_get_lk_max_locks, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008952 {"set_lk_max_lockers", (PyCFunction)DBEnv_set_lk_max_lockers, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008953 {"get_lk_max_lockers", (PyCFunction)DBEnv_get_lk_max_lockers, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008954 {"set_lk_max_objects", (PyCFunction)DBEnv_set_lk_max_objects, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008955 {"get_lk_max_objects", (PyCFunction)DBEnv_get_lk_max_objects, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008956 {"stat_print", (PyCFunction)DBEnv_stat_print,
8957 METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008958 {"set_mp_mmapsize", (PyCFunction)DBEnv_set_mp_mmapsize, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008959 {"get_mp_mmapsize", (PyCFunction)DBEnv_get_mp_mmapsize, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008960 {"set_tmp_dir", (PyCFunction)DBEnv_set_tmp_dir, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008961 {"get_tmp_dir", (PyCFunction)DBEnv_get_tmp_dir, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008962 {"txn_begin", (PyCFunction)DBEnv_txn_begin, METH_VARARGS|METH_KEYWORDS},
8963 {"txn_checkpoint", (PyCFunction)DBEnv_txn_checkpoint, METH_VARARGS},
8964 {"txn_stat", (PyCFunction)DBEnv_txn_stat, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008965 {"txn_stat_print", (PyCFunction)DBEnv_txn_stat_print,
8966 METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008967 {"get_tx_max", (PyCFunction)DBEnv_get_tx_max, METH_NOARGS},
8968 {"get_tx_timestamp", (PyCFunction)DBEnv_get_tx_timestamp, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008969 {"set_tx_max", (PyCFunction)DBEnv_set_tx_max, METH_VARARGS},
Gregory P. Smith8a474042006-01-27 07:05:40 +00008970 {"set_tx_timestamp", (PyCFunction)DBEnv_set_tx_timestamp, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008971 {"lock_detect", (PyCFunction)DBEnv_lock_detect, METH_VARARGS},
8972 {"lock_get", (PyCFunction)DBEnv_lock_get, METH_VARARGS},
8973 {"lock_id", (PyCFunction)DBEnv_lock_id, METH_NOARGS},
8974 {"lock_id_free", (PyCFunction)DBEnv_lock_id_free, METH_VARARGS},
8975 {"lock_put", (PyCFunction)DBEnv_lock_put, METH_VARARGS},
8976 {"lock_stat", (PyCFunction)DBEnv_lock_stat, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008977 {"lock_stat_print", (PyCFunction)DBEnv_lock_stat_print,
8978 METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008979 {"log_cursor", (PyCFunction)DBEnv_log_cursor, METH_NOARGS},
8980 {"log_file", (PyCFunction)DBEnv_log_file, METH_VARARGS},
Gregory P. Smithdb8a8072006-06-05 01:56:15 +00008981#if (DBVER >= 44)
Jesus Cea6557aac2010-03-22 14:22:26 +00008982 {"log_printf", (PyCFunction)DBEnv_log_printf,
8983 METH_VARARGS|METH_KEYWORDS},
8984#endif
8985 {"log_archive", (PyCFunction)DBEnv_log_archive, METH_VARARGS},
8986 {"log_flush", (PyCFunction)DBEnv_log_flush, METH_NOARGS},
8987 {"log_stat", (PyCFunction)DBEnv_log_stat, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008988 {"log_stat_print", (PyCFunction)DBEnv_log_stat_print,
8989 METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008990#if (DBVER >= 44)
8991 {"fileid_reset", (PyCFunction)DBEnv_fileid_reset, METH_VARARGS|METH_KEYWORDS},
8992 {"lsn_reset", (PyCFunction)DBEnv_lsn_reset, METH_VARARGS|METH_KEYWORDS},
Gregory P. Smithdb8a8072006-06-05 01:56:15 +00008993#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008994 {"set_get_returns_none",(PyCFunction)DBEnv_set_get_returns_none, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008995 {"txn_recover", (PyCFunction)DBEnv_txn_recover, METH_NOARGS},
Matthias Klose54cc5392010-03-15 12:46:18 +00008996#if (DBVER < 48)
Jesus Ceaca3939c2008-05-22 15:27:38 +00008997 {"set_rpc_server", (PyCFunction)DBEnv_set_rpc_server,
Stefan Krah77112732011-09-15 22:56:00 +02008998 METH_VARARGS|METH_KEYWORDS},
Matthias Klose54cc5392010-03-15 12:46:18 +00008999#endif
Jesus Cea6557aac2010-03-22 14:22:26 +00009000 {"set_mp_max_openfd", (PyCFunction)DBEnv_set_mp_max_openfd, METH_VARARGS},
9001 {"get_mp_max_openfd", (PyCFunction)DBEnv_get_mp_max_openfd, METH_NOARGS},
9002 {"set_mp_max_write", (PyCFunction)DBEnv_set_mp_max_write, METH_VARARGS},
9003 {"get_mp_max_write", (PyCFunction)DBEnv_get_mp_max_write, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00009004 {"set_verbose", (PyCFunction)DBEnv_set_verbose, METH_VARARGS},
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009005 {"get_verbose", (PyCFunction)DBEnv_get_verbose, METH_VARARGS},
9006 {"set_private", (PyCFunction)DBEnv_set_private, METH_O},
9007 {"get_private", (PyCFunction)DBEnv_get_private, METH_NOARGS},
9008 {"get_open_flags", (PyCFunction)DBEnv_get_open_flags, METH_NOARGS},
9009#if (DBVER >= 47)
9010 {"set_intermediate_dir_mode", (PyCFunction)DBEnv_set_intermediate_dir_mode,
9011 METH_VARARGS},
9012 {"get_intermediate_dir_mode", (PyCFunction)DBEnv_get_intermediate_dir_mode,
9013 METH_NOARGS},
Jesus Ceaef9764f2008-05-13 18:45:46 +00009014#endif
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009015#if (DBVER < 47)
9016 {"set_intermediate_dir", (PyCFunction)DBEnv_set_intermediate_dir,
9017 METH_VARARGS},
9018#endif
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009019 {"rep_start", (PyCFunction)DBEnv_rep_start,
9020 METH_VARARGS|METH_KEYWORDS},
9021 {"rep_set_transport", (PyCFunction)DBEnv_rep_set_transport, METH_VARARGS},
9022 {"rep_process_message", (PyCFunction)DBEnv_rep_process_message,
9023 METH_VARARGS},
9024#if (DBVER >= 46)
9025 {"rep_elect", (PyCFunction)DBEnv_rep_elect, METH_VARARGS},
9026#endif
9027#if (DBVER >= 44)
9028 {"rep_set_config", (PyCFunction)DBEnv_rep_set_config, METH_VARARGS},
9029 {"rep_get_config", (PyCFunction)DBEnv_rep_get_config, METH_VARARGS},
9030 {"rep_sync", (PyCFunction)DBEnv_rep_sync, METH_NOARGS},
Jesus Ceaef9764f2008-05-13 18:45:46 +00009031#endif
9032#if (DBVER >= 45)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009033 {"rep_set_limit", (PyCFunction)DBEnv_rep_set_limit, METH_VARARGS},
9034 {"rep_get_limit", (PyCFunction)DBEnv_rep_get_limit, METH_NOARGS},
9035#endif
9036#if (DBVER >= 47)
9037 {"rep_set_request", (PyCFunction)DBEnv_rep_set_request, METH_VARARGS},
9038 {"rep_get_request", (PyCFunction)DBEnv_rep_get_request, METH_NOARGS},
9039#endif
9040#if (DBVER >= 45)
9041 {"set_event_notify", (PyCFunction)DBEnv_set_event_notify, METH_O},
Jesus Ceaef9764f2008-05-13 18:45:46 +00009042#endif
9043#if (DBVER >= 45)
9044 {"rep_set_nsites", (PyCFunction)DBEnv_rep_set_nsites, METH_VARARGS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009045 {"rep_get_nsites", (PyCFunction)DBEnv_rep_get_nsites, METH_NOARGS},
Jesus Ceaef9764f2008-05-13 18:45:46 +00009046 {"rep_set_priority", (PyCFunction)DBEnv_rep_set_priority, METH_VARARGS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009047 {"rep_get_priority", (PyCFunction)DBEnv_rep_get_priority, METH_NOARGS},
Jesus Ceaef9764f2008-05-13 18:45:46 +00009048 {"rep_set_timeout", (PyCFunction)DBEnv_rep_set_timeout, METH_VARARGS},
9049 {"rep_get_timeout", (PyCFunction)DBEnv_rep_get_timeout, METH_VARARGS},
9050#endif
Jesus Cea6557aac2010-03-22 14:22:26 +00009051#if (DBVER >= 47)
9052 {"rep_set_clockskew", (PyCFunction)DBEnv_rep_set_clockskew, METH_VARARGS},
9053 {"rep_get_clockskew", (PyCFunction)DBEnv_rep_get_clockskew, METH_VARARGS},
9054#endif
9055 {"rep_stat", (PyCFunction)DBEnv_rep_stat,
9056 METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00009057 {"rep_stat_print", (PyCFunction)DBEnv_rep_stat_print,
9058 METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00009059
Jesus Ceaef9764f2008-05-13 18:45:46 +00009060#if (DBVER >= 45)
9061 {"repmgr_start", (PyCFunction)DBEnv_repmgr_start,
9062 METH_VARARGS|METH_KEYWORDS},
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009063#if (DBVER < 52)
Jesus Ceaef9764f2008-05-13 18:45:46 +00009064 {"repmgr_set_local_site", (PyCFunction)DBEnv_repmgr_set_local_site,
9065 METH_VARARGS|METH_KEYWORDS},
9066 {"repmgr_add_remote_site", (PyCFunction)DBEnv_repmgr_add_remote_site,
9067 METH_VARARGS|METH_KEYWORDS},
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009068#endif
Jesus Ceaef9764f2008-05-13 18:45:46 +00009069 {"repmgr_set_ack_policy", (PyCFunction)DBEnv_repmgr_set_ack_policy,
9070 METH_VARARGS},
9071 {"repmgr_get_ack_policy", (PyCFunction)DBEnv_repmgr_get_ack_policy,
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009072 METH_NOARGS},
Jesus Ceaef9764f2008-05-13 18:45:46 +00009073 {"repmgr_site_list", (PyCFunction)DBEnv_repmgr_site_list,
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009074 METH_NOARGS},
Jesus Ceaef9764f2008-05-13 18:45:46 +00009075#endif
9076#if (DBVER >= 46)
9077 {"repmgr_stat", (PyCFunction)DBEnv_repmgr_stat,
9078 METH_VARARGS|METH_KEYWORDS},
9079 {"repmgr_stat_print", (PyCFunction)DBEnv_repmgr_stat_print,
9080 METH_VARARGS|METH_KEYWORDS},
9081#endif
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009082#if (DBVER >= 52)
9083 {"repmgr_site", (PyCFunction)DBEnv_repmgr_site,
9084 METH_VARARGS | METH_KEYWORDS},
9085 {"repmgr_site_by_eid", (PyCFunction)DBEnv_repmgr_site_by_eid,
9086 METH_VARARGS | METH_KEYWORDS},
9087#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009088 {NULL, NULL} /* sentinel */
9089};
9090
9091
9092static PyMethodDef DBTxn_methods[] = {
9093 {"commit", (PyCFunction)DBTxn_commit, METH_VARARGS},
9094 {"prepare", (PyCFunction)DBTxn_prepare, METH_VARARGS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009095 {"discard", (PyCFunction)DBTxn_discard, METH_NOARGS},
9096 {"abort", (PyCFunction)DBTxn_abort, METH_NOARGS},
9097 {"id", (PyCFunction)DBTxn_id, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00009098 {"set_timeout", (PyCFunction)DBTxn_set_timeout,
9099 METH_VARARGS|METH_KEYWORDS},
9100#if (DBVER >= 44)
9101 {"set_name", (PyCFunction)DBTxn_set_name, METH_VARARGS},
9102 {"get_name", (PyCFunction)DBTxn_get_name, METH_NOARGS},
9103#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009104 {NULL, NULL} /* sentinel */
9105};
9106
9107
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009108static PyMethodDef DBSequence_methods[] = {
9109 {"close", (PyCFunction)DBSequence_close, METH_VARARGS},
9110 {"get", (PyCFunction)DBSequence_get, METH_VARARGS|METH_KEYWORDS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009111 {"get_dbp", (PyCFunction)DBSequence_get_dbp, METH_NOARGS},
9112 {"get_key", (PyCFunction)DBSequence_get_key, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00009113 {"initial_value", (PyCFunction)DBSequence_initial_value, METH_VARARGS},
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009114 {"open", (PyCFunction)DBSequence_open, METH_VARARGS|METH_KEYWORDS},
9115 {"remove", (PyCFunction)DBSequence_remove, METH_VARARGS|METH_KEYWORDS},
9116 {"set_cachesize", (PyCFunction)DBSequence_set_cachesize, METH_VARARGS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009117 {"get_cachesize", (PyCFunction)DBSequence_get_cachesize, METH_NOARGS},
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009118 {"set_flags", (PyCFunction)DBSequence_set_flags, METH_VARARGS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009119 {"get_flags", (PyCFunction)DBSequence_get_flags, METH_NOARGS},
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009120 {"set_range", (PyCFunction)DBSequence_set_range, METH_VARARGS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009121 {"get_range", (PyCFunction)DBSequence_get_range, METH_NOARGS},
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009122 {"stat", (PyCFunction)DBSequence_stat, METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00009123 {"stat_print", (PyCFunction)DBSequence_stat_print,
9124 METH_VARARGS|METH_KEYWORDS},
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009125 {NULL, NULL} /* sentinel */
9126};
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009127
9128
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009129static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009130DBEnv_db_home_get(DBEnvObject* self)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009131{
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009132 const char *home = NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009133
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009134 CHECK_ENV_NOT_CLOSED(self);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009135
Jesus Cea6557aac2010-03-22 14:22:26 +00009136 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009137 self->db_env->get_home(self->db_env, &home);
Jesus Cea6557aac2010-03-22 14:22:26 +00009138 MYDB_END_ALLOW_THREADS;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009139
9140 if (home == NULL) {
9141 RETURN_NONE();
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009142 }
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009143 return PyBytes_FromString(home);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009144}
9145
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009146static PyGetSetDef DBEnv_getsets[] = {
9147 {"db_home", (getter)DBEnv_db_home_get, NULL,},
9148 {NULL}
9149};
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009150
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009151
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009152statichere PyTypeObject DB_Type = {
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009153#if (PY_VERSION_HEX < 0x03000000)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009154 PyObject_HEAD_INIT(NULL)
9155 0, /*ob_size*/
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009156#else
9157 PyVarObject_HEAD_INIT(NULL, 0)
9158#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009159 "DB", /*tp_name*/
9160 sizeof(DBObject), /*tp_basicsize*/
9161 0, /*tp_itemsize*/
9162 /* methods */
9163 (destructor)DB_dealloc, /*tp_dealloc*/
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009164 0, /*tp_print*/
9165 0, /*tp_getattr*/
9166 0, /*tp_setattr*/
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009167 0, /*tp_compare*/
9168 0, /*tp_repr*/
9169 0, /*tp_as_number*/
Jesus Cea6557aac2010-03-22 14:22:26 +00009170 &DB_sequence,/*tp_as_sequence*/
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009171 &DB_mapping,/*tp_as_mapping*/
9172 0, /*tp_hash*/
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009173 0, /* tp_call */
9174 0, /* tp_str */
9175 0, /* tp_getattro */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009176 0, /* tp_setattro */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009177 0, /* tp_as_buffer */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009178#if (PY_VERSION_HEX < 0x03000000)
Gregory P. Smith31c50652004-06-28 01:20:40 +00009179 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009180#else
9181 Py_TPFLAGS_DEFAULT, /* tp_flags */
9182#endif
9183 0, /* tp_doc */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009184 0, /* tp_traverse */
9185 0, /* tp_clear */
9186 0, /* tp_richcompare */
Gregory P. Smith31c50652004-06-28 01:20:40 +00009187 offsetof(DBObject, in_weakreflist), /* tp_weaklistoffset */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009188 0, /*tp_iter*/
9189 0, /*tp_iternext*/
9190 DB_methods, /*tp_methods*/
9191 0, /*tp_members*/
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009192};
9193
9194
9195statichere PyTypeObject DBCursor_Type = {
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009196#if (PY_VERSION_HEX < 0x03000000)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009197 PyObject_HEAD_INIT(NULL)
9198 0, /*ob_size*/
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009199#else
9200 PyVarObject_HEAD_INIT(NULL, 0)
9201#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009202 "DBCursor", /*tp_name*/
9203 sizeof(DBCursorObject), /*tp_basicsize*/
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009204 0, /*tp_itemsize*/
9205 /* methods */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009206 (destructor)DBCursor_dealloc,/*tp_dealloc*/
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009207 0, /*tp_print*/
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009208 0, /*tp_getattr*/
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009209 0, /*tp_setattr*/
9210 0, /*tp_compare*/
9211 0, /*tp_repr*/
9212 0, /*tp_as_number*/
9213 0, /*tp_as_sequence*/
9214 0, /*tp_as_mapping*/
9215 0, /*tp_hash*/
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009216 0, /*tp_call*/
9217 0, /*tp_str*/
9218 0, /*tp_getattro*/
9219 0, /*tp_setattro*/
9220 0, /*tp_as_buffer*/
9221#if (PY_VERSION_HEX < 0x03000000)
Gregory P. Smith31c50652004-06-28 01:20:40 +00009222 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009223#else
9224 Py_TPFLAGS_DEFAULT, /* tp_flags */
9225#endif
9226 0, /* tp_doc */
9227 0, /* tp_traverse */
9228 0, /* tp_clear */
9229 0, /* tp_richcompare */
9230 offsetof(DBCursorObject, in_weakreflist), /* tp_weaklistoffset */
9231 0, /*tp_iter*/
9232 0, /*tp_iternext*/
9233 DBCursor_methods, /*tp_methods*/
9234 0, /*tp_members*/
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009235};
9236
9237
Jesus Cea6557aac2010-03-22 14:22:26 +00009238statichere PyTypeObject DBLogCursor_Type = {
9239#if (PY_VERSION_HEX < 0x03000000)
9240 PyObject_HEAD_INIT(NULL)
9241 0, /*ob_size*/
9242#else
9243 PyVarObject_HEAD_INIT(NULL, 0)
9244#endif
9245 "DBLogCursor", /*tp_name*/
9246 sizeof(DBLogCursorObject), /*tp_basicsize*/
9247 0, /*tp_itemsize*/
9248 /* methods */
9249 (destructor)DBLogCursor_dealloc,/*tp_dealloc*/
9250 0, /*tp_print*/
9251 0, /*tp_getattr*/
9252 0, /*tp_setattr*/
9253 0, /*tp_compare*/
9254 0, /*tp_repr*/
9255 0, /*tp_as_number*/
9256 0, /*tp_as_sequence*/
9257 0, /*tp_as_mapping*/
9258 0, /*tp_hash*/
9259 0, /*tp_call*/
9260 0, /*tp_str*/
9261 0, /*tp_getattro*/
9262 0, /*tp_setattro*/
9263 0, /*tp_as_buffer*/
9264#if (PY_VERSION_HEX < 0x03000000)
9265 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
9266#else
9267 Py_TPFLAGS_DEFAULT, /* tp_flags */
9268#endif
9269 0, /* tp_doc */
9270 0, /* tp_traverse */
9271 0, /* tp_clear */
9272 0, /* tp_richcompare */
9273 offsetof(DBLogCursorObject, in_weakreflist), /* tp_weaklistoffset */
9274 0, /*tp_iter*/
9275 0, /*tp_iternext*/
9276 DBLogCursor_methods, /*tp_methods*/
9277 0, /*tp_members*/
9278};
9279
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009280#if (DBVER >= 52)
9281statichere PyTypeObject DBSite_Type = {
9282#if (PY_VERSION_HEX < 0x03000000)
9283 PyObject_HEAD_INIT(NULL)
9284 0, /*ob_size*/
9285#else
9286 PyVarObject_HEAD_INIT(NULL, 0)
9287#endif
9288 "DBSite", /*tp_name*/
9289 sizeof(DBSiteObject), /*tp_basicsize*/
9290 0, /*tp_itemsize*/
9291 /* methods */
9292 (destructor)DBSite_dealloc,/*tp_dealloc*/
9293 0, /*tp_print*/
9294 0, /*tp_getattr*/
9295 0, /*tp_setattr*/
9296 0, /*tp_compare*/
9297 0, /*tp_repr*/
9298 0, /*tp_as_number*/
9299 0, /*tp_as_sequence*/
9300 0, /*tp_as_mapping*/
9301 0, /*tp_hash*/
9302 0, /*tp_call*/
9303 0, /*tp_str*/
9304 0, /*tp_getattro*/
9305 0, /*tp_setattro*/
9306 0, /*tp_as_buffer*/
9307#if (PY_VERSION_HEX < 0x03000000)
9308 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
9309#else
9310 Py_TPFLAGS_DEFAULT, /* tp_flags */
9311#endif
9312 0, /* tp_doc */
9313 0, /* tp_traverse */
9314 0, /* tp_clear */
9315 0, /* tp_richcompare */
9316 offsetof(DBSiteObject, in_weakreflist), /* tp_weaklistoffset */
9317 0, /*tp_iter*/
9318 0, /*tp_iternext*/
9319 DBSite_methods, /*tp_methods*/
9320 0, /*tp_members*/
9321};
9322#endif
Jesus Cea6557aac2010-03-22 14:22:26 +00009323
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009324statichere PyTypeObject DBEnv_Type = {
9325#if (PY_VERSION_HEX < 0x03000000)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009326 PyObject_HEAD_INIT(NULL)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009327 0, /*ob_size*/
9328#else
9329 PyVarObject_HEAD_INIT(NULL, 0)
9330#endif
9331 "DBEnv", /*tp_name*/
9332 sizeof(DBEnvObject), /*tp_basicsize*/
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009333 0, /*tp_itemsize*/
9334 /* methods */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009335 (destructor)DBEnv_dealloc, /*tp_dealloc*/
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009336 0, /*tp_print*/
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009337 0, /*tp_getattr*/
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009338 0, /*tp_setattr*/
9339 0, /*tp_compare*/
9340 0, /*tp_repr*/
9341 0, /*tp_as_number*/
9342 0, /*tp_as_sequence*/
9343 0, /*tp_as_mapping*/
9344 0, /*tp_hash*/
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009345 0, /* tp_call */
9346 0, /* tp_str */
9347 0, /* tp_getattro */
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009348 0, /* tp_setattro */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009349 0, /* tp_as_buffer */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009350#if (PY_VERSION_HEX < 0x03000000)
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009351 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009352#else
9353 Py_TPFLAGS_DEFAULT, /* tp_flags */
9354#endif
9355 0, /* tp_doc */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009356 0, /* tp_traverse */
9357 0, /* tp_clear */
9358 0, /* tp_richcompare */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009359 offsetof(DBEnvObject, in_weakreflist), /* tp_weaklistoffset */
9360 0, /* tp_iter */
9361 0, /* tp_iternext */
9362 DBEnv_methods, /* tp_methods */
9363 0, /* tp_members */
9364 DBEnv_getsets, /* tp_getsets */
9365};
9366
9367statichere PyTypeObject DBTxn_Type = {
9368#if (PY_VERSION_HEX < 0x03000000)
9369 PyObject_HEAD_INIT(NULL)
9370 0, /*ob_size*/
9371#else
9372 PyVarObject_HEAD_INIT(NULL, 0)
9373#endif
9374 "DBTxn", /*tp_name*/
9375 sizeof(DBTxnObject), /*tp_basicsize*/
9376 0, /*tp_itemsize*/
9377 /* methods */
9378 (destructor)DBTxn_dealloc, /*tp_dealloc*/
9379 0, /*tp_print*/
9380 0, /*tp_getattr*/
9381 0, /*tp_setattr*/
9382 0, /*tp_compare*/
9383 0, /*tp_repr*/
9384 0, /*tp_as_number*/
9385 0, /*tp_as_sequence*/
9386 0, /*tp_as_mapping*/
9387 0, /*tp_hash*/
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009388 0, /* tp_call */
9389 0, /* tp_str */
9390 0, /* tp_getattro */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009391 0, /* tp_setattro */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009392 0, /* tp_as_buffer */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009393#if (PY_VERSION_HEX < 0x03000000)
9394 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
9395#else
9396 Py_TPFLAGS_DEFAULT, /* tp_flags */
9397#endif
9398 0, /* tp_doc */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009399 0, /* tp_traverse */
9400 0, /* tp_clear */
9401 0, /* tp_richcompare */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009402 offsetof(DBTxnObject, in_weakreflist), /* tp_weaklistoffset */
9403 0, /*tp_iter*/
9404 0, /*tp_iternext*/
9405 DBTxn_methods, /*tp_methods*/
9406 0, /*tp_members*/
9407};
9408
9409
9410statichere PyTypeObject DBLock_Type = {
9411#if (PY_VERSION_HEX < 0x03000000)
9412 PyObject_HEAD_INIT(NULL)
9413 0, /*ob_size*/
9414#else
9415 PyVarObject_HEAD_INIT(NULL, 0)
9416#endif
9417 "DBLock", /*tp_name*/
9418 sizeof(DBLockObject), /*tp_basicsize*/
9419 0, /*tp_itemsize*/
9420 /* methods */
9421 (destructor)DBLock_dealloc, /*tp_dealloc*/
9422 0, /*tp_print*/
9423 0, /*tp_getattr*/
9424 0, /*tp_setattr*/
9425 0, /*tp_compare*/
9426 0, /*tp_repr*/
9427 0, /*tp_as_number*/
9428 0, /*tp_as_sequence*/
9429 0, /*tp_as_mapping*/
9430 0, /*tp_hash*/
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009431 0, /* tp_call */
9432 0, /* tp_str */
9433 0, /* tp_getattro */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009434 0, /* tp_setattro */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009435 0, /* tp_as_buffer */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009436#if (PY_VERSION_HEX < 0x03000000)
9437 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
9438#else
9439 Py_TPFLAGS_DEFAULT, /* tp_flags */
9440#endif
9441 0, /* tp_doc */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009442 0, /* tp_traverse */
9443 0, /* tp_clear */
9444 0, /* tp_richcompare */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009445 offsetof(DBLockObject, in_weakreflist), /* tp_weaklistoffset */
9446};
9447
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009448statichere PyTypeObject DBSequence_Type = {
9449#if (PY_VERSION_HEX < 0x03000000)
9450 PyObject_HEAD_INIT(NULL)
9451 0, /*ob_size*/
9452#else
9453 PyVarObject_HEAD_INIT(NULL, 0)
9454#endif
9455 "DBSequence", /*tp_name*/
9456 sizeof(DBSequenceObject), /*tp_basicsize*/
9457 0, /*tp_itemsize*/
9458 /* methods */
9459 (destructor)DBSequence_dealloc, /*tp_dealloc*/
9460 0, /*tp_print*/
9461 0, /*tp_getattr*/
9462 0, /*tp_setattr*/
9463 0, /*tp_compare*/
9464 0, /*tp_repr*/
9465 0, /*tp_as_number*/
9466 0, /*tp_as_sequence*/
9467 0, /*tp_as_mapping*/
9468 0, /*tp_hash*/
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009469 0, /* tp_call */
9470 0, /* tp_str */
9471 0, /* tp_getattro */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009472 0, /* tp_setattro */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009473 0, /* tp_as_buffer */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009474#if (PY_VERSION_HEX < 0x03000000)
9475 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
9476#else
9477 Py_TPFLAGS_DEFAULT, /* tp_flags */
9478#endif
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009479 0, /* tp_doc */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009480 0, /* tp_traverse */
9481 0, /* tp_clear */
9482 0, /* tp_richcompare */
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009483 offsetof(DBSequenceObject, in_weakreflist), /* tp_weaklistoffset */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009484 0, /*tp_iter*/
9485 0, /*tp_iternext*/
9486 DBSequence_methods, /*tp_methods*/
9487 0, /*tp_members*/
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009488};
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009489
9490/* --------------------------------------------------------------------- */
9491/* Module-level functions */
9492
9493static PyObject*
9494DB_construct(PyObject* self, PyObject* args, PyObject* kwargs)
9495{
9496 PyObject* dbenvobj = NULL;
9497 int flags = 0;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00009498 static char* kwnames[] = { "dbEnv", "flags", NULL};
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009499
Barry Warsaw9a0d7792002-12-30 20:53:52 +00009500 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Oi:DB", kwnames,
9501 &dbenvobj, &flags))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009502 return NULL;
9503 if (dbenvobj == Py_None)
9504 dbenvobj = NULL;
9505 else if (dbenvobj && !DBEnvObject_Check(dbenvobj)) {
9506 makeTypeError("DBEnv", dbenvobj);
9507 return NULL;
9508 }
9509
9510 return (PyObject* )newDBObject((DBEnvObject*)dbenvobj, flags);
9511}
9512
9513
9514static PyObject*
9515DBEnv_construct(PyObject* self, PyObject* args)
9516{
9517 int flags = 0;
9518 if (!PyArg_ParseTuple(args, "|i:DbEnv", &flags)) return NULL;
9519 return (PyObject* )newDBEnvObject(flags);
9520}
9521
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009522static PyObject*
9523DBSequence_construct(PyObject* self, PyObject* args, PyObject* kwargs)
9524{
Neal Norwitzb4fcf8d2006-06-11 05:44:18 +00009525 PyObject* dbobj;
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009526 int flags = 0;
9527 static char* kwnames[] = { "db", "flags", NULL};
9528
9529 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|i:DBSequence", kwnames, &dbobj, &flags))
9530 return NULL;
Neal Norwitzb4fcf8d2006-06-11 05:44:18 +00009531 if (!DBObject_Check(dbobj)) {
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009532 makeTypeError("DB", dbobj);
9533 return NULL;
9534 }
9535 return (PyObject* )newDBSequenceObject((DBObject*)dbobj, flags);
9536}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009537
9538static char bsddb_version_doc[] =
9539"Returns a tuple of major, minor, and patch release numbers of the\n\
9540underlying DB library.";
9541
9542static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009543bsddb_version(PyObject* self)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009544{
9545 int major, minor, patch;
9546
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009547 /* This should be instantaneous, no need to release the GIL */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009548 db_version(&major, &minor, &patch);
9549 return Py_BuildValue("(iii)", major, minor, patch);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009550}
9551
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009552#if (DBVER >= 50)
9553static PyObject*
9554bsddb_version_full(PyObject* self)
9555{
9556 char *version_string;
9557 int family, release, major, minor, patch;
9558
9559 /* This should be instantaneous, no need to release the GIL */
9560 version_string = db_full_version(&family, &release, &major, &minor, &patch);
9561 return Py_BuildValue("(siiiii)",
9562 version_string, family, release, major, minor, patch);
9563}
9564#endif
9565
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009566
9567/* List of functions defined in the module */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009568static PyMethodDef bsddb_methods[] = {
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009569 {"DB", (PyCFunction)DB_construct, METH_VARARGS | METH_KEYWORDS },
9570 {"DBEnv", (PyCFunction)DBEnv_construct, METH_VARARGS},
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009571 {"DBSequence", (PyCFunction)DBSequence_construct, METH_VARARGS | METH_KEYWORDS },
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009572 {"version", (PyCFunction)bsddb_version, METH_NOARGS, bsddb_version_doc},
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009573#if (DBVER >= 50)
9574 {"full_version", (PyCFunction)bsddb_version_full, METH_NOARGS},
9575#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009576 {NULL, NULL} /* sentinel */
9577};
9578
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009579
Gregory P. Smith39250532007-10-09 06:02:21 +00009580/* API structure */
9581static BSDDB_api bsddb_api;
9582
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009583
9584/* --------------------------------------------------------------------- */
9585/* Module initialization */
9586
9587
9588/* Convenience routine to export an integer value.
9589 * Errors are silently ignored, for better or for worse...
9590 */
9591#define ADD_INT(dict, NAME) _addIntToDict(dict, #NAME, NAME)
9592
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009593/*
9594** We can rename the module at import time, so the string allocated
9595** must be big enough, and any use of the name must use this particular
9596** string.
9597*/
Gregory P. Smith41631e82003-09-21 00:08:14 +00009598#define MODULE_NAME_MAX_LEN 11
9599static char _bsddbModuleName[MODULE_NAME_MAX_LEN+1] = "_bsddb";
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009600
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009601#if (PY_VERSION_HEX >= 0x03000000)
9602static struct PyModuleDef bsddbmodule = {
9603 PyModuleDef_HEAD_INIT,
9604 _bsddbModuleName, /* Name of module */
9605 NULL, /* module documentation, may be NULL */
9606 -1, /* size of per-interpreter state of the module,
9607 or -1 if the module keeps state in global variables. */
9608 bsddb_methods,
9609 NULL, /* Reload */
9610 NULL, /* Traverse */
9611 NULL, /* Clear */
9612 NULL /* Free */
9613};
9614#endif
9615
9616
9617#if (PY_VERSION_HEX < 0x03000000)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009618DL_EXPORT(void) init_bsddb(void)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009619#else
9620PyMODINIT_FUNC PyInit__bsddb(void) /* Note the two underscores */
9621#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009622{
9623 PyObject* m;
9624 PyObject* d;
Gregory P. Smith39250532007-10-09 06:02:21 +00009625 PyObject* py_api;
Jesus Cea6557aac2010-03-22 14:22:26 +00009626 PyObject* pybsddb_version_s;
9627 PyObject* db_version_s;
9628 PyObject* cvsid_s;
9629
9630#if (PY_VERSION_HEX < 0x03000000)
9631 pybsddb_version_s = PyString_FromString(PY_BSDDB_VERSION);
9632 db_version_s = PyString_FromString(DB_VERSION_STRING);
9633 cvsid_s = PyString_FromString(rcs_id);
9634#else
9635 /* This data should be ascii, so UTF-8 conversion is fine */
9636 pybsddb_version_s = PyUnicode_FromString(PY_BSDDB_VERSION);
9637 db_version_s = PyUnicode_FromString(DB_VERSION_STRING);
9638 cvsid_s = PyUnicode_FromString(rcs_id);
9639#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009640
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009641 /* Initialize object types */
9642 if ((PyType_Ready(&DB_Type) < 0)
9643 || (PyType_Ready(&DBCursor_Type) < 0)
Jesus Cea6557aac2010-03-22 14:22:26 +00009644 || (PyType_Ready(&DBLogCursor_Type) < 0)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009645 || (PyType_Ready(&DBEnv_Type) < 0)
9646 || (PyType_Ready(&DBTxn_Type) < 0)
9647 || (PyType_Ready(&DBLock_Type) < 0)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009648 || (PyType_Ready(&DBSequence_Type) < 0)
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009649#if (DBVER >= 52)
9650 || (PyType_Ready(&DBSite_Type) < 0)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009651#endif
9652 ) {
9653#if (PY_VERSION_HEX < 0x03000000)
9654 return;
9655#else
9656 return NULL;
9657#endif
9658 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009659
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009660 /* Create the module and add the functions */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009661#if (PY_VERSION_HEX < 0x03000000)
Gregory P. Smith41631e82003-09-21 00:08:14 +00009662 m = Py_InitModule(_bsddbModuleName, bsddb_methods);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009663#else
9664 m=PyModule_Create(&bsddbmodule);
9665#endif
9666 if (m == NULL) {
9667#if (PY_VERSION_HEX < 0x03000000)
9668 return;
9669#else
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009670 return NULL;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009671#endif
9672 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009673
9674 /* Add some symbolic constants to the module */
9675 d = PyModule_GetDict(m);
9676 PyDict_SetItemString(d, "__version__", pybsddb_version_s);
9677 PyDict_SetItemString(d, "cvsid", cvsid_s);
9678 PyDict_SetItemString(d, "DB_VERSION_STRING", db_version_s);
9679 Py_DECREF(pybsddb_version_s);
9680 pybsddb_version_s = NULL;
9681 Py_DECREF(cvsid_s);
9682 cvsid_s = NULL;
9683 Py_DECREF(db_version_s);
9684 db_version_s = NULL;
9685
9686 ADD_INT(d, DB_VERSION_MAJOR);
9687 ADD_INT(d, DB_VERSION_MINOR);
9688 ADD_INT(d, DB_VERSION_PATCH);
9689
9690 ADD_INT(d, DB_MAX_PAGES);
9691 ADD_INT(d, DB_MAX_RECORDS);
9692
Matthias Klose54cc5392010-03-15 12:46:18 +00009693#if (DBVER < 48)
Gregory P. Smith41631e82003-09-21 00:08:14 +00009694 ADD_INT(d, DB_RPCCLIENT);
Matthias Klose54cc5392010-03-15 12:46:18 +00009695#endif
9696
9697#if (DBVER < 48)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009698 ADD_INT(d, DB_XA_CREATE);
Matthias Klose54cc5392010-03-15 12:46:18 +00009699#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009700
9701 ADD_INT(d, DB_CREATE);
9702 ADD_INT(d, DB_NOMMAP);
9703 ADD_INT(d, DB_THREAD);
Jesus Ceaef9764f2008-05-13 18:45:46 +00009704#if (DBVER >= 45)
9705 ADD_INT(d, DB_MULTIVERSION);
9706#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009707
9708 ADD_INT(d, DB_FORCE);
9709 ADD_INT(d, DB_INIT_CDB);
9710 ADD_INT(d, DB_INIT_LOCK);
9711 ADD_INT(d, DB_INIT_LOG);
9712 ADD_INT(d, DB_INIT_MPOOL);
9713 ADD_INT(d, DB_INIT_TXN);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009714 ADD_INT(d, DB_JOINENV);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009715
Matthias Klose54cc5392010-03-15 12:46:18 +00009716#if (DBVER >= 48)
9717 ADD_INT(d, DB_GID_SIZE);
9718#else
Jesus Ceaef9764f2008-05-13 18:45:46 +00009719 ADD_INT(d, DB_XIDDATASIZE);
Matthias Klose54cc5392010-03-15 12:46:18 +00009720 /* Allow new code to work in old BDB releases */
9721 _addIntToDict(d, "DB_GID_SIZE", DB_XIDDATASIZE);
9722#endif
Jesus Ceaef9764f2008-05-13 18:45:46 +00009723
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009724 ADD_INT(d, DB_RECOVER);
9725 ADD_INT(d, DB_RECOVER_FATAL);
9726 ADD_INT(d, DB_TXN_NOSYNC);
9727 ADD_INT(d, DB_USE_ENVIRON);
9728 ADD_INT(d, DB_USE_ENVIRON_ROOT);
9729
9730 ADD_INT(d, DB_LOCKDOWN);
9731 ADD_INT(d, DB_PRIVATE);
9732 ADD_INT(d, DB_SYSTEM_MEM);
9733
9734 ADD_INT(d, DB_TXN_SYNC);
9735 ADD_INT(d, DB_TXN_NOWAIT);
9736
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009737#if (DBVER >= 51)
9738 ADD_INT(d, DB_TXN_BULK);
9739#endif
9740
9741#if (DBVER >= 48)
9742 ADD_INT(d, DB_CURSOR_BULK);
9743#endif
9744
Jesus Cea6557aac2010-03-22 14:22:26 +00009745#if (DBVER >= 46)
9746 ADD_INT(d, DB_TXN_WAIT);
9747#endif
9748
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009749 ADD_INT(d, DB_EXCL);
9750 ADD_INT(d, DB_FCNTL_LOCKING);
9751 ADD_INT(d, DB_ODDFILESIZE);
9752 ADD_INT(d, DB_RDWRMASTER);
9753 ADD_INT(d, DB_RDONLY);
9754 ADD_INT(d, DB_TRUNCATE);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009755 ADD_INT(d, DB_EXTENT);
9756 ADD_INT(d, DB_CDB_ALLDB);
9757 ADD_INT(d, DB_VERIFY);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009758 ADD_INT(d, DB_UPGRADE);
9759
Jesus Cea6557aac2010-03-22 14:22:26 +00009760 ADD_INT(d, DB_PRINTABLE);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009761 ADD_INT(d, DB_AGGRESSIVE);
9762 ADD_INT(d, DB_NOORDERCHK);
9763 ADD_INT(d, DB_ORDERCHKONLY);
9764 ADD_INT(d, DB_PR_PAGE);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009765
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009766 ADD_INT(d, DB_PR_RECOVERYTEST);
9767 ADD_INT(d, DB_SALVAGE);
9768
9769 ADD_INT(d, DB_LOCK_NORUN);
9770 ADD_INT(d, DB_LOCK_DEFAULT);
9771 ADD_INT(d, DB_LOCK_OLDEST);
9772 ADD_INT(d, DB_LOCK_RANDOM);
9773 ADD_INT(d, DB_LOCK_YOUNGEST);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009774 ADD_INT(d, DB_LOCK_MAXLOCKS);
9775 ADD_INT(d, DB_LOCK_MINLOCKS);
9776 ADD_INT(d, DB_LOCK_MINWRITE);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009777
Jesus Ceaef9764f2008-05-13 18:45:46 +00009778 ADD_INT(d, DB_LOCK_EXPIRE);
Jesus Ceaef9764f2008-05-13 18:45:46 +00009779 ADD_INT(d, DB_LOCK_MAXWRITE);
Jesus Ceaef9764f2008-05-13 18:45:46 +00009780
Barry Warsaw9a0d7792002-12-30 20:53:52 +00009781 _addIntToDict(d, "DB_LOCK_CONFLICT", 0);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009782
9783 ADD_INT(d, DB_LOCK_DUMP);
9784 ADD_INT(d, DB_LOCK_GET);
9785 ADD_INT(d, DB_LOCK_INHERIT);
9786 ADD_INT(d, DB_LOCK_PUT);
9787 ADD_INT(d, DB_LOCK_PUT_ALL);
9788 ADD_INT(d, DB_LOCK_PUT_OBJ);
9789
9790 ADD_INT(d, DB_LOCK_NG);
9791 ADD_INT(d, DB_LOCK_READ);
9792 ADD_INT(d, DB_LOCK_WRITE);
9793 ADD_INT(d, DB_LOCK_NOWAIT);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009794 ADD_INT(d, DB_LOCK_WAIT);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009795 ADD_INT(d, DB_LOCK_IWRITE);
9796 ADD_INT(d, DB_LOCK_IREAD);
9797 ADD_INT(d, DB_LOCK_IWR);
Gregory P. Smith29602d22006-01-24 09:46:48 +00009798#if (DBVER < 44)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009799 ADD_INT(d, DB_LOCK_DIRTY);
Gregory P. Smith29602d22006-01-24 09:46:48 +00009800#else
9801 ADD_INT(d, DB_LOCK_READ_UNCOMMITTED); /* renamed in 4.4 */
9802#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009803 ADD_INT(d, DB_LOCK_WWRITE);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009804
9805 ADD_INT(d, DB_LOCK_RECORD);
9806 ADD_INT(d, DB_LOCK_UPGRADE);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009807 ADD_INT(d, DB_LOCK_SWITCH);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009808 ADD_INT(d, DB_LOCK_UPGRADE_WRITE);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009809
9810 ADD_INT(d, DB_LOCK_NOWAIT);
9811 ADD_INT(d, DB_LOCK_RECORD);
9812 ADD_INT(d, DB_LOCK_UPGRADE);
9813
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009814 ADD_INT(d, DB_LSTAT_ABORTED);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009815 ADD_INT(d, DB_LSTAT_FREE);
9816 ADD_INT(d, DB_LSTAT_HELD);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009817
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009818 ADD_INT(d, DB_LSTAT_PENDING);
9819 ADD_INT(d, DB_LSTAT_WAITING);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009820
9821 ADD_INT(d, DB_ARCH_ABS);
9822 ADD_INT(d, DB_ARCH_DATA);
9823 ADD_INT(d, DB_ARCH_LOG);
Gregory P. Smith3dd20022006-06-05 00:31:01 +00009824 ADD_INT(d, DB_ARCH_REMOVE);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009825
9826 ADD_INT(d, DB_BTREE);
9827 ADD_INT(d, DB_HASH);
9828 ADD_INT(d, DB_RECNO);
9829 ADD_INT(d, DB_QUEUE);
9830 ADD_INT(d, DB_UNKNOWN);
9831
9832 ADD_INT(d, DB_DUP);
9833 ADD_INT(d, DB_DUPSORT);
9834 ADD_INT(d, DB_RECNUM);
9835 ADD_INT(d, DB_RENUMBER);
9836 ADD_INT(d, DB_REVSPLITOFF);
9837 ADD_INT(d, DB_SNAPSHOT);
9838
Jesus Cea6557aac2010-03-22 14:22:26 +00009839 ADD_INT(d, DB_INORDER);
Jesus Cea6557aac2010-03-22 14:22:26 +00009840
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009841 ADD_INT(d, DB_JOIN_NOSORT);
9842
9843 ADD_INT(d, DB_AFTER);
9844 ADD_INT(d, DB_APPEND);
9845 ADD_INT(d, DB_BEFORE);
Gregory P. Smith8b96a352007-01-05 01:59:42 +00009846#if (DBVER < 45)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009847 ADD_INT(d, DB_CACHED_COUNTS);
Gregory P. Smith8b96a352007-01-05 01:59:42 +00009848#endif
Jesus Ceaca3939c2008-05-22 15:27:38 +00009849
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009850 ADD_INT(d, DB_CONSUME);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009851 ADD_INT(d, DB_CONSUME_WAIT);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009852 ADD_INT(d, DB_CURRENT);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009853 ADD_INT(d, DB_FAST_STAT);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009854 ADD_INT(d, DB_FIRST);
9855 ADD_INT(d, DB_FLUSH);
9856 ADD_INT(d, DB_GET_BOTH);
Jesus Cea6557aac2010-03-22 14:22:26 +00009857 ADD_INT(d, DB_GET_BOTH_RANGE);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009858 ADD_INT(d, DB_GET_RECNO);
9859 ADD_INT(d, DB_JOIN_ITEM);
9860 ADD_INT(d, DB_KEYFIRST);
9861 ADD_INT(d, DB_KEYLAST);
9862 ADD_INT(d, DB_LAST);
9863 ADD_INT(d, DB_NEXT);
9864 ADD_INT(d, DB_NEXT_DUP);
9865 ADD_INT(d, DB_NEXT_NODUP);
9866 ADD_INT(d, DB_NODUPDATA);
9867 ADD_INT(d, DB_NOOVERWRITE);
9868 ADD_INT(d, DB_NOSYNC);
9869 ADD_INT(d, DB_POSITION);
9870 ADD_INT(d, DB_PREV);
9871 ADD_INT(d, DB_PREV_NODUP);
Jesus Cea6557aac2010-03-22 14:22:26 +00009872#if (DBVER >= 46)
9873 ADD_INT(d, DB_PREV_DUP);
9874#endif
Gregory P. Smith8b96a352007-01-05 01:59:42 +00009875#if (DBVER < 45)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009876 ADD_INT(d, DB_RECORDCOUNT);
Gregory P. Smith8b96a352007-01-05 01:59:42 +00009877#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009878 ADD_INT(d, DB_SET);
9879 ADD_INT(d, DB_SET_RANGE);
9880 ADD_INT(d, DB_SET_RECNO);
9881 ADD_INT(d, DB_WRITECURSOR);
9882
9883 ADD_INT(d, DB_OPFLAGS_MASK);
9884 ADD_INT(d, DB_RMW);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009885 ADD_INT(d, DB_DIRTY_READ);
9886 ADD_INT(d, DB_MULTIPLE);
9887 ADD_INT(d, DB_MULTIPLE_KEY);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009888
Gregory P. Smith29602d22006-01-24 09:46:48 +00009889#if (DBVER >= 44)
Jesus Cea6557aac2010-03-22 14:22:26 +00009890 ADD_INT(d, DB_IMMUTABLE_KEY);
Gregory P. Smith29602d22006-01-24 09:46:48 +00009891 ADD_INT(d, DB_READ_UNCOMMITTED); /* replaces DB_DIRTY_READ in 4.4 */
9892 ADD_INT(d, DB_READ_COMMITTED);
9893#endif
9894
Jesus Cea6557aac2010-03-22 14:22:26 +00009895#if (DBVER >= 44)
9896 ADD_INT(d, DB_FREELIST_ONLY);
9897 ADD_INT(d, DB_FREE_SPACE);
9898#endif
9899
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009900 ADD_INT(d, DB_DONOTINDEX);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009901
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009902 ADD_INT(d, DB_KEYEMPTY);
9903 ADD_INT(d, DB_KEYEXIST);
9904 ADD_INT(d, DB_LOCK_DEADLOCK);
9905 ADD_INT(d, DB_LOCK_NOTGRANTED);
9906 ADD_INT(d, DB_NOSERVER);
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009907#if (DBVER < 52)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009908 ADD_INT(d, DB_NOSERVER_HOME);
9909 ADD_INT(d, DB_NOSERVER_ID);
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009910#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009911 ADD_INT(d, DB_NOTFOUND);
9912 ADD_INT(d, DB_OLD_VERSION);
9913 ADD_INT(d, DB_RUNRECOVERY);
9914 ADD_INT(d, DB_VERIFY_BAD);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009915 ADD_INT(d, DB_PAGE_NOTFOUND);
9916 ADD_INT(d, DB_SECONDARY_BAD);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009917 ADD_INT(d, DB_STAT_CLEAR);
9918 ADD_INT(d, DB_REGION_INIT);
9919 ADD_INT(d, DB_NOLOCKING);
9920 ADD_INT(d, DB_YIELDCPU);
9921 ADD_INT(d, DB_PANIC_ENVIRONMENT);
9922 ADD_INT(d, DB_NOPANIC);
Jesus Ceaef9764f2008-05-13 18:45:46 +00009923 ADD_INT(d, DB_OVERWRITE);
Jesus Cea6557aac2010-03-22 14:22:26 +00009924
Jesus Cea6557aac2010-03-22 14:22:26 +00009925 ADD_INT(d, DB_STAT_SUBSYSTEM);
9926 ADD_INT(d, DB_STAT_MEMP_HASH);
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009927 ADD_INT(d, DB_STAT_LOCK_CONF);
9928 ADD_INT(d, DB_STAT_LOCK_LOCKERS);
9929 ADD_INT(d, DB_STAT_LOCK_OBJECTS);
9930 ADD_INT(d, DB_STAT_LOCK_PARAMS);
Jesus Ceaef9764f2008-05-13 18:45:46 +00009931
Jesus Cea6557aac2010-03-22 14:22:26 +00009932#if (DBVER >= 48)
9933 ADD_INT(d, DB_OVERWRITE_DUP);
9934#endif
9935
9936#if (DBVER >= 47)
9937 ADD_INT(d, DB_FOREIGN_ABORT);
9938 ADD_INT(d, DB_FOREIGN_CASCADE);
9939 ADD_INT(d, DB_FOREIGN_NULLIFY);
9940#endif
9941
9942#if (DBVER >= 44)
Gregory P. Smithaae141a2007-11-01 21:08:14 +00009943 ADD_INT(d, DB_REGISTER);
9944#endif
9945
Jesus Cea6557aac2010-03-22 14:22:26 +00009946 ADD_INT(d, DB_EID_INVALID);
9947 ADD_INT(d, DB_EID_BROADCAST);
9948
Gregory P. Smith41631e82003-09-21 00:08:14 +00009949 ADD_INT(d, DB_TIME_NOTGRANTED);
9950 ADD_INT(d, DB_TXN_NOT_DURABLE);
9951 ADD_INT(d, DB_TXN_WRITE_NOSYNC);
Gregory P. Smith41631e82003-09-21 00:08:14 +00009952 ADD_INT(d, DB_DIRECT_DB);
9953 ADD_INT(d, DB_INIT_REP);
9954 ADD_INT(d, DB_ENCRYPT);
9955 ADD_INT(d, DB_CHKSUM);
Gregory P. Smith41631e82003-09-21 00:08:14 +00009956
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009957#if (DBVER < 47)
Jesus Ceaca3939c2008-05-22 15:27:38 +00009958 ADD_INT(d, DB_LOG_AUTOREMOVE);
9959 ADD_INT(d, DB_DIRECT_LOG);
9960#endif
9961
9962#if (DBVER >= 47)
9963 ADD_INT(d, DB_LOG_DIRECT);
9964 ADD_INT(d, DB_LOG_DSYNC);
9965 ADD_INT(d, DB_LOG_IN_MEMORY);
9966 ADD_INT(d, DB_LOG_AUTO_REMOVE);
9967 ADD_INT(d, DB_LOG_ZERO);
9968#endif
9969
Jesus Ceaef9764f2008-05-13 18:45:46 +00009970#if (DBVER >= 44)
9971 ADD_INT(d, DB_DSYNC_DB);
9972#endif
9973
9974#if (DBVER >= 45)
9975 ADD_INT(d, DB_TXN_SNAPSHOT);
9976#endif
9977
Jesus Ceaef9764f2008-05-13 18:45:46 +00009978 ADD_INT(d, DB_VERB_DEADLOCK);
9979#if (DBVER >= 46)
9980 ADD_INT(d, DB_VERB_FILEOPS);
9981 ADD_INT(d, DB_VERB_FILEOPS_ALL);
9982#endif
9983 ADD_INT(d, DB_VERB_RECOVERY);
9984#if (DBVER >= 44)
9985 ADD_INT(d, DB_VERB_REGISTER);
9986#endif
9987 ADD_INT(d, DB_VERB_REPLICATION);
9988 ADD_INT(d, DB_VERB_WAITSFOR);
Jesus Ceaef9764f2008-05-13 18:45:46 +00009989
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009990#if (DBVER >= 50)
9991 ADD_INT(d, DB_VERB_REP_SYSTEM);
9992#endif
9993
9994#if (DBVER >= 47)
9995 ADD_INT(d, DB_VERB_REP_ELECT);
9996 ADD_INT(d, DB_VERB_REP_LEASE);
9997 ADD_INT(d, DB_VERB_REP_MISC);
9998 ADD_INT(d, DB_VERB_REP_MSGS);
9999 ADD_INT(d, DB_VERB_REP_SYNC);
10000 ADD_INT(d, DB_VERB_REPMGR_CONNFAIL);
10001 ADD_INT(d, DB_VERB_REPMGR_MISC);
10002#endif
10003
Jesus Ceaef9764f2008-05-13 18:45:46 +000010004#if (DBVER >= 45)
10005 ADD_INT(d, DB_EVENT_PANIC);
10006 ADD_INT(d, DB_EVENT_REP_CLIENT);
10007#if (DBVER >= 46)
10008 ADD_INT(d, DB_EVENT_REP_ELECTED);
10009#endif
10010 ADD_INT(d, DB_EVENT_REP_MASTER);
10011 ADD_INT(d, DB_EVENT_REP_NEWMASTER);
10012#if (DBVER >= 46)
10013 ADD_INT(d, DB_EVENT_REP_PERM_FAILED);
10014#endif
10015 ADD_INT(d, DB_EVENT_REP_STARTUPDONE);
10016 ADD_INT(d, DB_EVENT_WRITE_FAILED);
10017#endif
10018
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010019#if (DBVER >= 50)
10020 ADD_INT(d, DB_REPMGR_CONF_ELECTIONS);
10021 ADD_INT(d, DB_EVENT_REP_MASTER_FAILURE);
10022 ADD_INT(d, DB_EVENT_REP_DUPMASTER);
10023 ADD_INT(d, DB_EVENT_REP_ELECTION_FAILED);
10024#endif
10025#if (DBVER >= 48)
10026 ADD_INT(d, DB_EVENT_REG_ALIVE);
10027 ADD_INT(d, DB_EVENT_REG_PANIC);
10028#endif
10029
10030#if (DBVER >=52)
10031 ADD_INT(d, DB_EVENT_REP_SITE_ADDED);
10032 ADD_INT(d, DB_EVENT_REP_SITE_REMOVED);
10033 ADD_INT(d, DB_EVENT_REP_LOCAL_SITE_REMOVED);
10034 ADD_INT(d, DB_EVENT_REP_CONNECT_BROKEN);
10035 ADD_INT(d, DB_EVENT_REP_CONNECT_ESTD);
10036 ADD_INT(d, DB_EVENT_REP_CONNECT_TRY_FAILED);
10037 ADD_INT(d, DB_EVENT_REP_INIT_DONE);
10038
10039 ADD_INT(d, DB_MEM_LOCK);
10040 ADD_INT(d, DB_MEM_LOCKOBJECT);
10041 ADD_INT(d, DB_MEM_LOCKER);
10042 ADD_INT(d, DB_MEM_LOGID);
10043 ADD_INT(d, DB_MEM_TRANSACTION);
10044 ADD_INT(d, DB_MEM_THREAD);
10045
10046 ADD_INT(d, DB_BOOTSTRAP_HELPER);
10047 ADD_INT(d, DB_GROUP_CREATOR);
10048 ADD_INT(d, DB_LEGACY);
10049 ADD_INT(d, DB_LOCAL_SITE);
10050 ADD_INT(d, DB_REPMGR_PEER);
10051#endif
10052
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010053 ADD_INT(d, DB_REP_DUPMASTER);
10054 ADD_INT(d, DB_REP_HOLDELECTION);
10055#if (DBVER >= 44)
10056 ADD_INT(d, DB_REP_IGNORE);
10057 ADD_INT(d, DB_REP_JOIN_FAILURE);
10058#endif
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010059 ADD_INT(d, DB_REP_ISPERM);
10060 ADD_INT(d, DB_REP_NOTPERM);
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010061 ADD_INT(d, DB_REP_NEWSITE);
10062
Jesus Ceaef9764f2008-05-13 18:45:46 +000010063 ADD_INT(d, DB_REP_MASTER);
10064 ADD_INT(d, DB_REP_CLIENT);
Jesus Cea6557aac2010-03-22 14:22:26 +000010065
10066 ADD_INT(d, DB_REP_PERMANENT);
10067
10068#if (DBVER >= 44)
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010069#if (DBVER >= 50)
10070 ADD_INT(d, DB_REP_CONF_AUTOINIT);
10071#else
Jesus Cea6557aac2010-03-22 14:22:26 +000010072 ADD_INT(d, DB_REP_CONF_NOAUTOINIT);
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010073#endif /* 5.0 */
10074#endif /* 4.4 */
10075#if (DBVER >= 44)
Jesus Cea6557aac2010-03-22 14:22:26 +000010076 ADD_INT(d, DB_REP_CONF_DELAYCLIENT);
10077 ADD_INT(d, DB_REP_CONF_BULK);
10078 ADD_INT(d, DB_REP_CONF_NOWAIT);
10079 ADD_INT(d, DB_REP_ANYWHERE);
10080 ADD_INT(d, DB_REP_REREQUEST);
10081#endif
10082
Jesus Cea6557aac2010-03-22 14:22:26 +000010083 ADD_INT(d, DB_REP_NOBUFFER);
Jesus Cea6557aac2010-03-22 14:22:26 +000010084
10085#if (DBVER >= 46)
10086 ADD_INT(d, DB_REP_LEASE_EXPIRED);
10087 ADD_INT(d, DB_IGNORE_LEASE);
10088#endif
10089
10090#if (DBVER >= 47)
10091 ADD_INT(d, DB_REP_CONF_LEASE);
10092 ADD_INT(d, DB_REPMGR_CONF_2SITE_STRICT);
10093#endif
10094
Jesus Ceaef9764f2008-05-13 18:45:46 +000010095#if (DBVER >= 45)
10096 ADD_INT(d, DB_REP_ELECTION);
10097
10098 ADD_INT(d, DB_REP_ACK_TIMEOUT);
10099 ADD_INT(d, DB_REP_CONNECTION_RETRY);
10100 ADD_INT(d, DB_REP_ELECTION_TIMEOUT);
10101 ADD_INT(d, DB_REP_ELECTION_RETRY);
10102#endif
10103#if (DBVER >= 46)
10104 ADD_INT(d, DB_REP_CHECKPOINT_DELAY);
10105 ADD_INT(d, DB_REP_FULL_ELECTION_TIMEOUT);
Jesus Cea6557aac2010-03-22 14:22:26 +000010106 ADD_INT(d, DB_REP_LEASE_TIMEOUT);
10107#endif
10108#if (DBVER >= 47)
10109 ADD_INT(d, DB_REP_HEARTBEAT_MONITOR);
10110 ADD_INT(d, DB_REP_HEARTBEAT_SEND);
Jesus Ceaef9764f2008-05-13 18:45:46 +000010111#endif
Jesus Ceaef9764f2008-05-13 18:45:46 +000010112
10113#if (DBVER >= 45)
10114 ADD_INT(d, DB_REPMGR_PEER);
10115 ADD_INT(d, DB_REPMGR_ACKS_ALL);
10116 ADD_INT(d, DB_REPMGR_ACKS_ALL_PEERS);
10117 ADD_INT(d, DB_REPMGR_ACKS_NONE);
10118 ADD_INT(d, DB_REPMGR_ACKS_ONE);
10119 ADD_INT(d, DB_REPMGR_ACKS_ONE_PEER);
10120 ADD_INT(d, DB_REPMGR_ACKS_QUORUM);
10121 ADD_INT(d, DB_REPMGR_CONNECTED);
10122 ADD_INT(d, DB_REPMGR_DISCONNECTED);
Jesus Ceaef9764f2008-05-13 18:45:46 +000010123 ADD_INT(d, DB_STAT_ALL);
10124#endif
10125
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010126#if (DBVER >= 51)
10127 ADD_INT(d, DB_REPMGR_ACKS_ALL_AVAILABLE);
10128#endif
10129
10130#if (DBVER >= 48)
10131 ADD_INT(d, DB_REP_CONF_INMEM);
10132#endif
10133
10134 ADD_INT(d, DB_TIMEOUT);
10135
10136#if (DBVER >= 50)
10137 ADD_INT(d, DB_FORCESYNC);
10138#endif
10139
10140#if (DBVER >= 48)
10141 ADD_INT(d, DB_FAILCHK);
10142#endif
10143
10144#if (DBVER >= 51)
10145 ADD_INT(d, DB_HOTBACKUP_IN_PROGRESS);
10146#endif
10147
Gregory P. Smith8b7e9172004-12-13 09:51:23 +000010148 ADD_INT(d, DB_BUFFER_SMALL);
Gregory P. Smithf0547d02006-06-05 17:38:04 +000010149 ADD_INT(d, DB_SEQ_DEC);
10150 ADD_INT(d, DB_SEQ_INC);
10151 ADD_INT(d, DB_SEQ_WRAP);
Gregory P. Smith8b7e9172004-12-13 09:51:23 +000010152
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010153#if (DBVER < 47)
Jesus Ceaca3939c2008-05-22 15:27:38 +000010154 ADD_INT(d, DB_LOG_INMEMORY);
10155 ADD_INT(d, DB_DSYNC_LOG);
10156#endif
10157
Barry Warsaw9a0d7792002-12-30 20:53:52 +000010158 ADD_INT(d, DB_ENCRYPT_AES);
10159 ADD_INT(d, DB_AUTO_COMMIT);
Jesus Cea6557aac2010-03-22 14:22:26 +000010160 ADD_INT(d, DB_PRIORITY_VERY_LOW);
10161 ADD_INT(d, DB_PRIORITY_LOW);
10162 ADD_INT(d, DB_PRIORITY_DEFAULT);
10163 ADD_INT(d, DB_PRIORITY_HIGH);
10164 ADD_INT(d, DB_PRIORITY_VERY_HIGH);
10165
10166#if (DBVER >= 46)
10167 ADD_INT(d, DB_PRIORITY_UNCHANGED);
Barry Warsaw9a0d7792002-12-30 20:53:52 +000010168#endif
10169
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010170 ADD_INT(d, EINVAL);
10171 ADD_INT(d, EACCES);
10172 ADD_INT(d, ENOSPC);
10173 ADD_INT(d, ENOMEM);
10174 ADD_INT(d, EAGAIN);
10175 ADD_INT(d, EBUSY);
10176 ADD_INT(d, EEXIST);
10177 ADD_INT(d, ENOENT);
10178 ADD_INT(d, EPERM);
10179
Barry Warsaw1baa9822003-03-31 19:51:29 +000010180 ADD_INT(d, DB_SET_LOCK_TIMEOUT);
10181 ADD_INT(d, DB_SET_TXN_TIMEOUT);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010182
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010183#if (DBVER >= 48)
10184 ADD_INT(d, DB_SET_REG_TIMEOUT);
10185#endif
10186
Gregory P. Smith7f5b6f42006-04-08 07:10:51 +000010187 /* The exception name must be correct for pickled exception *
10188 * objects to unpickle properly. */
10189#ifdef PYBSDDB_STANDALONE /* different value needed for standalone pybsddb */
10190#define PYBSDDB_EXCEPTION_BASE "bsddb3.db."
10191#else
10192#define PYBSDDB_EXCEPTION_BASE "bsddb.db."
10193#endif
10194
10195 /* All the rest of the exceptions derive only from DBError */
10196#define MAKE_EX(name) name = PyErr_NewException(PYBSDDB_EXCEPTION_BASE #name, DBError, NULL); \
10197 PyDict_SetItemString(d, #name, name)
10198
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010199 /* The base exception class is DBError */
Gregory P. Smith7f5b6f42006-04-08 07:10:51 +000010200 DBError = NULL; /* used in MAKE_EX so that it derives from nothing */
10201 MAKE_EX(DBError);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010202
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010203#if (PY_VERSION_HEX < 0x03000000)
Gregory P. Smithe9477062005-06-04 06:46:59 +000010204 /* Some magic to make DBNotFoundError and DBKeyEmptyError derive
10205 * from both DBError and KeyError, since the API only supports
10206 * using one base class. */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010207 PyDict_SetItemString(d, "KeyError", PyExc_KeyError);
Gregory P. Smithe9477062005-06-04 06:46:59 +000010208 PyRun_String("class DBNotFoundError(DBError, KeyError): pass\n"
Antoine Pitrouc83ea132010-05-09 14:46:46 +000010209 "class DBKeyEmptyError(DBError, KeyError): pass",
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010210 Py_file_input, d, d);
10211 DBNotFoundError = PyDict_GetItemString(d, "DBNotFoundError");
Gregory P. Smithe9477062005-06-04 06:46:59 +000010212 DBKeyEmptyError = PyDict_GetItemString(d, "DBKeyEmptyError");
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010213 PyDict_DelItemString(d, "KeyError");
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010214#else
10215 /* Since Python 2.5, PyErr_NewException() accepts a tuple, to be able to
10216 ** derive from several classes. We use this new API only for Python 3.0,
10217 ** though.
10218 */
10219 {
10220 PyObject* bases;
10221
10222 bases = PyTuple_Pack(2, DBError, PyExc_KeyError);
10223
10224#define MAKE_EX2(name) name = PyErr_NewException(PYBSDDB_EXCEPTION_BASE #name, bases, NULL); \
10225 PyDict_SetItemString(d, #name, name)
10226 MAKE_EX2(DBNotFoundError);
10227 MAKE_EX2(DBKeyEmptyError);
10228
10229#undef MAKE_EX2
10230
10231 Py_XDECREF(bases);
10232 }
10233#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010234
Gregory P. Smithe2767172003-11-02 08:06:29 +000010235 MAKE_EX(DBCursorClosedError);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010236 MAKE_EX(DBKeyExistError);
10237 MAKE_EX(DBLockDeadlockError);
10238 MAKE_EX(DBLockNotGrantedError);
10239 MAKE_EX(DBOldVersionError);
10240 MAKE_EX(DBRunRecoveryError);
10241 MAKE_EX(DBVerifyBadError);
10242 MAKE_EX(DBNoServerError);
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010243#if (DBVER < 52)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010244 MAKE_EX(DBNoServerHomeError);
10245 MAKE_EX(DBNoServerIDError);
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010246#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010247 MAKE_EX(DBPageNotFoundError);
10248 MAKE_EX(DBSecondaryBadError);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010249
10250 MAKE_EX(DBInvalidArgError);
10251 MAKE_EX(DBAccessError);
10252 MAKE_EX(DBNoSpaceError);
10253 MAKE_EX(DBNoMemoryError);
10254 MAKE_EX(DBAgainError);
10255 MAKE_EX(DBBusyError);
10256 MAKE_EX(DBFileExistsError);
10257 MAKE_EX(DBNoSuchFileError);
10258 MAKE_EX(DBPermissionsError);
10259
Jesus Ceaef9764f2008-05-13 18:45:46 +000010260 MAKE_EX(DBRepHandleDeadError);
Jesus Cea6557aac2010-03-22 14:22:26 +000010261#if (DBVER >= 44)
10262 MAKE_EX(DBRepLockoutError);
10263#endif
Jesus Ceaef9764f2008-05-13 18:45:46 +000010264
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010265 MAKE_EX(DBRepUnavailError);
10266
Jesus Cea6557aac2010-03-22 14:22:26 +000010267#if (DBVER >= 46)
10268 MAKE_EX(DBRepLeaseExpiredError);
10269#endif
10270
10271#if (DBVER >= 47)
10272 MAKE_EX(DBForeignConflictError);
10273#endif
10274
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010275#undef MAKE_EX
10276
Jesus Cea6557aac2010-03-22 14:22:26 +000010277 /* Initialise the C API structure and add it to the module */
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010278 bsddb_api.api_version = PYBSDDB_API_VERSION;
Jesus Cea6557aac2010-03-22 14:22:26 +000010279 bsddb_api.db_type = &DB_Type;
10280 bsddb_api.dbcursor_type = &DBCursor_Type;
10281 bsddb_api.dblogcursor_type = &DBLogCursor_Type;
10282 bsddb_api.dbenv_type = &DBEnv_Type;
10283 bsddb_api.dbtxn_type = &DBTxn_Type;
10284 bsddb_api.dblock_type = &DBLock_Type;
Jesus Cea6557aac2010-03-22 14:22:26 +000010285 bsddb_api.dbsequence_type = &DBSequence_Type;
Jesus Cea6557aac2010-03-22 14:22:26 +000010286 bsddb_api.makeDBError = makeDBError;
Gregory P. Smith39250532007-10-09 06:02:21 +000010287
Jesus Cea6557aac2010-03-22 14:22:26 +000010288 /*
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010289 ** Capsules exist from Python 2.7 and 3.1.
10290 ** We don't support Python 3.0 anymore, so...
10291 ** #if (PY_VERSION_HEX < ((PY_MAJOR_VERSION < 3) ? 0x02070000 : 0x03020000))
Jesus Cea6557aac2010-03-22 14:22:26 +000010292 */
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010293#if (PY_VERSION_HEX < 0x02070000)
Gregory P. Smith39250532007-10-09 06:02:21 +000010294 py_api = PyCObject_FromVoidPtr((void*)&bsddb_api, NULL);
Jesus Cea6557aac2010-03-22 14:22:26 +000010295#else
10296 {
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010297 /*
10298 ** The data must outlive the call!!. So, the static definition.
10299 ** The buffer must be big enough...
10300 */
10301 static char py_api_name[MODULE_NAME_MAX_LEN+10];
Jesus Cea6557aac2010-03-22 14:22:26 +000010302
10303 strcpy(py_api_name, _bsddbModuleName);
10304 strcat(py_api_name, ".api");
10305
10306 py_api = PyCapsule_New((void*)&bsddb_api, py_api_name, NULL);
10307 }
10308#endif
10309
Jesus Cea84f2c322010-11-05 00:13:50 +000010310 /* Check error control */
10311 /*
10312 ** PyErr_NoMemory();
10313 ** py_api = NULL;
10314 */
10315
10316 if (py_api) {
10317 PyDict_SetItemString(d, "api", py_api);
10318 Py_DECREF(py_api);
10319 } else { /* Something bad happened */
10320 PyErr_WriteUnraisable(m);
Jesus Ceabf088f82010-11-08 12:57:59 +000010321 if(PyErr_Warn(PyExc_RuntimeWarning,
10322 "_bsddb/_pybsddb C API will be not available")) {
10323 PyErr_WriteUnraisable(m);
10324 }
Jesus Cea84f2c322010-11-05 00:13:50 +000010325 PyErr_Clear();
10326 }
Gregory P. Smith39250532007-10-09 06:02:21 +000010327
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010328 /* Check for errors */
10329 if (PyErr_Occurred()) {
10330 PyErr_Print();
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010331 Py_FatalError("can't initialize module _bsddb/_pybsddb");
10332 Py_DECREF(m);
10333 m = NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010334 }
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010335#if (PY_VERSION_HEX < 0x03000000)
10336 return;
10337#else
10338 return m;
10339#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010340}
Gregory P. Smith41631e82003-09-21 00:08:14 +000010341
10342/* allow this module to be named _pybsddb so that it can be installed
10343 * and imported on top of python >= 2.3 that includes its own older
10344 * copy of the library named _bsddb without importing the old version. */
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010345#if (PY_VERSION_HEX < 0x03000000)
Gregory P. Smith41631e82003-09-21 00:08:14 +000010346DL_EXPORT(void) init_pybsddb(void)
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010347#else
10348PyMODINIT_FUNC PyInit__pybsddb(void) /* Note the two underscores */
10349#endif
Gregory P. Smith41631e82003-09-21 00:08:14 +000010350{
10351 strncpy(_bsddbModuleName, "_pybsddb", MODULE_NAME_MAX_LEN);
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010352#if (PY_VERSION_HEX < 0x03000000)
Gregory P. Smith41631e82003-09-21 00:08:14 +000010353 init_bsddb();
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010354#else
10355 return PyInit__bsddb(); /* Note the two underscores */
10356#endif
Gregory P. Smith41631e82003-09-21 00:08:14 +000010357}