blob: cee447bfc67dc90288c1ec52b8233c2615110145 [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
Victor Stinner2c277312017-05-03 18:04:18 +0200934 if (self->myenvobj) {
Gregory P. Smith455d46f2003-07-09 04:45:59 +0000935 self->moduleFlags = self->myenvobj->moduleFlags;
Victor Stinner2c277312017-05-03 18:04:18 +0200936 }
937 else {
Gregory P. Smith455d46f2003-07-09 04:45:59 +0000938 self->moduleFlags.getReturnsNone = DEFAULT_GET_RETURNS_NONE;
939 self->moduleFlags.cursorSetReturnsNone = DEFAULT_CURSOR_SET_RETURNS_NONE;
Victor Stinner2c277312017-05-03 18:04:18 +0200940 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000941
942 MYDB_BEGIN_ALLOW_THREADS;
943 err = db_create(&self->db, db_env, flags);
Neal Norwitzdce937f2006-07-23 08:01:43 +0000944 if (self->db != NULL) {
945 self->db->set_errcall(self->db, _db_errorCallback);
Neal Norwitzdce937f2006-07-23 08:01:43 +0000946 self->db->app_private = (void*)self;
Neal Norwitzdce937f2006-07-23 08:01:43 +0000947 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000948 MYDB_END_ALLOW_THREADS;
Gregory P. Smith31c50652004-06-28 01:20:40 +0000949 /* TODO add a weakref(self) to the self->myenvobj->open_child_weakrefs
950 * list so that a DBEnv can refuse to close without aborting any open
Gregory P. Smithf0547d02006-06-05 17:38:04 +0000951 * DBTxns and closing any open DBs first. */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000952 if (makeDBError(err)) {
953 if (self->myenvobj) {
Serhiy Storchaka98a97222014-02-09 13:14:04 +0200954 Py_CLEAR(self->myenvobj);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000955 }
Gregory P. Smith664782e2008-05-17 06:12:02 +0000956 Py_DECREF(self);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000957 self = NULL;
958 }
959 return self;
960}
961
962
Jesus Ceaef9764f2008-05-13 18:45:46 +0000963/* Forward declaration */
Jesus Cea5cd5f122008-09-23 18:54:08 +0000964static PyObject *DB_close_internal(DBObject* self, int flags, int do_not_close);
Jesus Ceaef9764f2008-05-13 18:45:46 +0000965
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000966static void
967DB_dealloc(DBObject* self)
968{
Jesus Ceaef9764f2008-05-13 18:45:46 +0000969 PyObject *dummy;
970
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000971 if (self->db != NULL) {
Jesus Cea5cd5f122008-09-23 18:54:08 +0000972 dummy=DB_close_internal(self, 0, 0);
973 /*
974 ** Raising exceptions while doing
975 ** garbage collection is a fatal error.
976 */
977 if (dummy)
978 Py_DECREF(dummy);
979 else
980 PyErr_Clear();
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000981 }
Gregory P. Smith31c50652004-06-28 01:20:40 +0000982 if (self->in_weakreflist != NULL) {
983 PyObject_ClearWeakRefs((PyObject *) self);
984 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000985 if (self->myenvobj) {
Serhiy Storchaka98a97222014-02-09 13:14:04 +0200986 Py_CLEAR(self->myenvobj);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000987 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000988 if (self->associateCallback != NULL) {
Serhiy Storchaka98a97222014-02-09 13:14:04 +0200989 Py_CLEAR(self->associateCallback);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000990 }
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +0000991 if (self->btCompareCallback != NULL) {
Serhiy Storchaka98a97222014-02-09 13:14:04 +0200992 Py_CLEAR(self->btCompareCallback);
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +0000993 }
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -0700994 if (self->dupCompareCallback != NULL) {
Serhiy Storchaka98a97222014-02-09 13:14:04 +0200995 Py_CLEAR(self->dupCompareCallback);
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -0700996 }
Jesus Cea4907d272008-08-31 14:00:51 +0000997 Py_DECREF(self->private_obj);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000998 PyObject_Del(self);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000999}
1000
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001001static DBCursorObject*
Jesus Ceaef9764f2008-05-13 18:45:46 +00001002newDBCursorObject(DBC* dbc, DBTxnObject *txn, DBObject* db)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001003{
Neal Norwitzb4a55812004-07-09 23:30:57 +00001004 DBCursorObject* self = PyObject_New(DBCursorObject, &DBCursor_Type);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001005 if (self == NULL)
1006 return NULL;
1007
1008 self->dbc = dbc;
1009 self->mydb = db;
Jesus Ceaef9764f2008-05-13 18:45:46 +00001010
1011 INSERT_IN_DOUBLE_LINKED_LIST(self->mydb->children_cursors,self);
1012 if (txn && ((PyObject *)txn!=Py_None)) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001013 INSERT_IN_DOUBLE_LINKED_LIST_TXN(txn->children_cursors,self);
1014 self->txn=txn;
Jesus Ceaef9764f2008-05-13 18:45:46 +00001015 } else {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001016 self->txn=NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00001017 }
1018
Gregory P. Smitha703a212003-11-03 01:04:41 +00001019 self->in_weakreflist = NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001020 Py_INCREF(self->mydb);
1021 return self;
1022}
1023
1024
Jesus Ceaef9764f2008-05-13 18:45:46 +00001025/* Forward declaration */
1026static PyObject *DBC_close_internal(DBCursorObject* self);
1027
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001028static void
1029DBCursor_dealloc(DBCursorObject* self)
1030{
Jesus Ceaef9764f2008-05-13 18:45:46 +00001031 PyObject *dummy;
Gregory P. Smitha703a212003-11-03 01:04:41 +00001032
Jesus Ceaef9764f2008-05-13 18:45:46 +00001033 if (self->dbc != NULL) {
Jesus Cea5cd5f122008-09-23 18:54:08 +00001034 dummy=DBC_close_internal(self);
1035 /*
1036 ** Raising exceptions while doing
1037 ** garbage collection is a fatal error.
1038 */
1039 if (dummy)
1040 Py_DECREF(dummy);
1041 else
1042 PyErr_Clear();
Jesus Ceaef9764f2008-05-13 18:45:46 +00001043 }
Gregory P. Smitha703a212003-11-03 01:04:41 +00001044 if (self->in_weakreflist != NULL) {
1045 PyObject_ClearWeakRefs((PyObject *) self);
1046 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00001047 Py_DECREF(self->mydb);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001048 PyObject_Del(self);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001049}
1050
1051
Jesus Cea6557aac2010-03-22 14:22:26 +00001052static DBLogCursorObject*
1053newDBLogCursorObject(DB_LOGC* dblogc, DBEnvObject* env)
1054{
1055 DBLogCursorObject* self;
1056
1057 self = PyObject_New(DBLogCursorObject, &DBLogCursor_Type);
1058
1059 if (self == NULL)
1060 return NULL;
1061
1062 self->logc = dblogc;
1063 self->env = env;
1064
1065 INSERT_IN_DOUBLE_LINKED_LIST(self->env->children_logcursors, self);
1066
1067 self->in_weakreflist = NULL;
1068 Py_INCREF(self->env);
1069 return self;
1070}
1071
1072
1073/* Forward declaration */
1074static PyObject *DBLogCursor_close_internal(DBLogCursorObject* self);
1075
1076static void
1077DBLogCursor_dealloc(DBLogCursorObject* self)
1078{
1079 PyObject *dummy;
1080
1081 if (self->logc != NULL) {
1082 dummy = DBLogCursor_close_internal(self);
1083 /*
1084 ** Raising exceptions while doing
1085 ** garbage collection is a fatal error.
1086 */
1087 if (dummy)
1088 Py_DECREF(dummy);
1089 else
1090 PyErr_Clear();
1091 }
1092 if (self->in_weakreflist != NULL) {
1093 PyObject_ClearWeakRefs((PyObject *) self);
1094 }
1095 Py_DECREF(self->env);
1096 PyObject_Del(self);
1097}
1098
1099
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001100static DBEnvObject*
1101newDBEnvObject(int flags)
1102{
1103 int err;
Neal Norwitzb4a55812004-07-09 23:30:57 +00001104 DBEnvObject* self = PyObject_New(DBEnvObject, &DBEnv_Type);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001105 if (self == NULL)
1106 return NULL;
1107
Jesus Cea5cd5f122008-09-23 18:54:08 +00001108 self->db_env = NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001109 self->closed = 1;
1110 self->flags = flags;
Gregory P. Smith455d46f2003-07-09 04:45:59 +00001111 self->moduleFlags.getReturnsNone = DEFAULT_GET_RETURNS_NONE;
1112 self->moduleFlags.cursorSetReturnsNone = DEFAULT_CURSOR_SET_RETURNS_NONE;
Jesus Ceaef9764f2008-05-13 18:45:46 +00001113 self->children_dbs = NULL;
1114 self->children_txns = NULL;
Jesus Cea6557aac2010-03-22 14:22:26 +00001115 self->children_logcursors = NULL ;
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07001116#if (DBVER >= 52)
1117 self->children_sites = NULL;
1118#endif
Jesus Ceac5a11fa2008-07-23 11:38:42 +00001119 Py_INCREF(Py_None);
Jesus Cea4907d272008-08-31 14:00:51 +00001120 self->private_obj = Py_None;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00001121 Py_INCREF(Py_None);
1122 self->rep_transport = Py_None;
Gregory P. Smith31c50652004-06-28 01:20:40 +00001123 self->in_weakreflist = NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00001124 self->event_notifyCallback = NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00001125
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001126 MYDB_BEGIN_ALLOW_THREADS;
1127 err = db_env_create(&self->db_env, flags);
1128 MYDB_END_ALLOW_THREADS;
1129 if (makeDBError(err)) {
Gregory P. Smith664782e2008-05-17 06:12:02 +00001130 Py_DECREF(self);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001131 self = NULL;
1132 }
1133 else {
1134 self->db_env->set_errcall(self->db_env, _db_errorCallback);
Jesus Cea4907d272008-08-31 14:00:51 +00001135 self->db_env->app_private = self;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001136 }
1137 return self;
1138}
1139
Jesus Ceaef9764f2008-05-13 18:45:46 +00001140/* Forward declaration */
1141static PyObject *DBEnv_close_internal(DBEnvObject* self, int flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001142
1143static void
1144DBEnv_dealloc(DBEnvObject* self)
1145{
Jesus Ceaef9764f2008-05-13 18:45:46 +00001146 PyObject *dummy;
1147
Jesus Ceaac25fab2008-09-03 17:50:32 +00001148 if (self->db_env) {
Jesus Cea5cd5f122008-09-23 18:54:08 +00001149 dummy=DBEnv_close_internal(self, 0);
1150 /*
1151 ** Raising exceptions while doing
1152 ** garbage collection is a fatal error.
1153 */
1154 if (dummy)
1155 Py_DECREF(dummy);
1156 else
1157 PyErr_Clear();
Jesus Ceaef9764f2008-05-13 18:45:46 +00001158 }
1159
Serhiy Storchaka98a97222014-02-09 13:14:04 +02001160 Py_CLEAR(self->event_notifyCallback);
Jesus Ceaef9764f2008-05-13 18:45:46 +00001161
Gregory P. Smith31c50652004-06-28 01:20:40 +00001162 if (self->in_weakreflist != NULL) {
1163 PyObject_ClearWeakRefs((PyObject *) self);
1164 }
Jesus Cea4907d272008-08-31 14:00:51 +00001165 Py_DECREF(self->private_obj);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00001166 Py_DECREF(self->rep_transport);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001167 PyObject_Del(self);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001168}
1169
1170
1171static DBTxnObject*
Jesus Ceaef9764f2008-05-13 18:45:46 +00001172newDBTxnObject(DBEnvObject* myenv, DBTxnObject *parent, DB_TXN *txn, int flags)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001173{
1174 int err;
Gregory P. Smith664782e2008-05-17 06:12:02 +00001175 DB_TXN *parent_txn = NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00001176
Neal Norwitzb4a55812004-07-09 23:30:57 +00001177 DBTxnObject* self = PyObject_New(DBTxnObject, &DBTxn_Type);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001178 if (self == NULL)
1179 return NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00001180
Gregory P. Smith31c50652004-06-28 01:20:40 +00001181 self->in_weakreflist = NULL;
Gregory P. Smith664782e2008-05-17 06:12:02 +00001182 self->children_txns = NULL;
1183 self->children_dbs = NULL;
1184 self->children_cursors = NULL;
1185 self->children_sequences = NULL;
1186 self->flag_prepare = 0;
1187 self->parent_txn = NULL;
1188 self->env = NULL;
Jesus Cea6557aac2010-03-22 14:22:26 +00001189 /* We initialize just in case "txn_begin" fails */
1190 self->txn = NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001191
Jesus Ceaef9764f2008-05-13 18:45:46 +00001192 if (parent && ((PyObject *)parent!=Py_None)) {
Gregory P. Smith664782e2008-05-17 06:12:02 +00001193 parent_txn = parent->txn;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001194 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00001195
1196 if (txn) {
Gregory P. Smith664782e2008-05-17 06:12:02 +00001197 self->txn = txn;
Jesus Ceaef9764f2008-05-13 18:45:46 +00001198 } else {
1199 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00001200 err = myenv->db_env->txn_begin(myenv->db_env, parent_txn, &(self->txn), flags);
Jesus Ceaef9764f2008-05-13 18:45:46 +00001201 MYDB_END_ALLOW_THREADS;
1202
1203 if (makeDBError(err)) {
Jesus Cea6557aac2010-03-22 14:22:26 +00001204 /* Free object half initialized */
Gregory P. Smith664782e2008-05-17 06:12:02 +00001205 Py_DECREF(self);
Jesus Ceaef9764f2008-05-13 18:45:46 +00001206 return NULL;
1207 }
1208 }
1209
Gregory P. Smith664782e2008-05-17 06:12:02 +00001210 /* Can't use 'parent' because could be 'parent==Py_None' */
1211 if (parent_txn) {
1212 self->parent_txn = parent;
Jesus Ceaef9764f2008-05-13 18:45:46 +00001213 Py_INCREF(parent);
1214 self->env = NULL;
Gregory P. Smith664782e2008-05-17 06:12:02 +00001215 INSERT_IN_DOUBLE_LINKED_LIST(parent->children_txns, self);
Jesus Ceaef9764f2008-05-13 18:45:46 +00001216 } else {
Gregory P. Smith664782e2008-05-17 06:12:02 +00001217 self->parent_txn = NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00001218 Py_INCREF(myenv);
1219 self->env = myenv;
Gregory P. Smith664782e2008-05-17 06:12:02 +00001220 INSERT_IN_DOUBLE_LINKED_LIST(myenv->children_txns, self);
Jesus Ceaef9764f2008-05-13 18:45:46 +00001221 }
1222
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001223 return self;
1224}
1225
Jesus Ceaef9764f2008-05-13 18:45:46 +00001226/* Forward declaration */
1227static PyObject *
1228DBTxn_abort_discard_internal(DBTxnObject* self, int discard);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001229
1230static void
1231DBTxn_dealloc(DBTxnObject* self)
1232{
Jesus Ceaef9764f2008-05-13 18:45:46 +00001233 PyObject *dummy;
1234
1235 if (self->txn) {
1236 int flag_prepare = self->flag_prepare;
Jesus Cea5cd5f122008-09-23 18:54:08 +00001237
Jesus Cea6557aac2010-03-22 14:22:26 +00001238 dummy=DBTxn_abort_discard_internal(self, 0);
Jesus Cea5cd5f122008-09-23 18:54:08 +00001239 /*
1240 ** Raising exceptions while doing
1241 ** garbage collection is a fatal error.
1242 */
1243 if (dummy)
1244 Py_DECREF(dummy);
1245 else
1246 PyErr_Clear();
1247
Jesus Ceaef9764f2008-05-13 18:45:46 +00001248 if (!flag_prepare) {
1249 PyErr_Warn(PyExc_RuntimeWarning,
1250 "DBTxn aborted in destructor. No prior commit() or abort().");
1251 }
1252 }
1253
Gregory P. Smith31c50652004-06-28 01:20:40 +00001254 if (self->in_weakreflist != NULL) {
1255 PyObject_ClearWeakRefs((PyObject *) self);
1256 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001257
Jesus Ceaef9764f2008-05-13 18:45:46 +00001258 if (self->env) {
1259 Py_DECREF(self->env);
1260 } else {
Jesus Cea6557aac2010-03-22 14:22:26 +00001261 /*
1262 ** We can have "self->env==NULL" and "self->parent_txn==NULL"
1263 ** if something happens when creating the transaction object
1264 ** and we abort the object while half done.
1265 */
1266 Py_XDECREF(self->parent_txn);
Gregory P. Smith31c50652004-06-28 01:20:40 +00001267 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001268 PyObject_Del(self);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001269}
1270
1271
1272static DBLockObject*
1273newDBLockObject(DBEnvObject* myenv, u_int32_t locker, DBT* obj,
1274 db_lockmode_t lock_mode, int flags)
1275{
1276 int err;
Neal Norwitzb4a55812004-07-09 23:30:57 +00001277 DBLockObject* self = PyObject_New(DBLockObject, &DBLock_Type);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001278 if (self == NULL)
1279 return NULL;
Gregory P. Smith31c50652004-06-28 01:20:40 +00001280 self->in_weakreflist = NULL;
Jesus Cea6557aac2010-03-22 14:22:26 +00001281 self->lock_initialized = 0; /* Just in case the call fails */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001282
1283 MYDB_BEGIN_ALLOW_THREADS;
Barry Warsaw9a0d7792002-12-30 20:53:52 +00001284 err = myenv->db_env->lock_get(myenv->db_env, locker, flags, obj, lock_mode,
1285 &self->lock);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001286 MYDB_END_ALLOW_THREADS;
1287 if (makeDBError(err)) {
Gregory P. Smith664782e2008-05-17 06:12:02 +00001288 Py_DECREF(self);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001289 self = NULL;
Jesus Cea6557aac2010-03-22 14:22:26 +00001290 } else {
1291 self->lock_initialized = 1;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001292 }
1293
1294 return self;
1295}
1296
1297
1298static void
1299DBLock_dealloc(DBLockObject* self)
1300{
Gregory P. Smith31c50652004-06-28 01:20:40 +00001301 if (self->in_weakreflist != NULL) {
1302 PyObject_ClearWeakRefs((PyObject *) self);
1303 }
Gregory P. Smith31c50652004-06-28 01:20:40 +00001304 /* TODO: is this lock held? should we release it? */
Jesus Cea6557aac2010-03-22 14:22:26 +00001305 /* CAUTION: The lock can be not initialized if the creation has failed */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001306
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001307 PyObject_Del(self);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001308}
1309
1310
Gregory P. Smithf0547d02006-06-05 17:38:04 +00001311static DBSequenceObject*
1312newDBSequenceObject(DBObject* mydb, int flags)
1313{
1314 int err;
1315 DBSequenceObject* self = PyObject_New(DBSequenceObject, &DBSequence_Type);
1316 if (self == NULL)
1317 return NULL;
1318 Py_INCREF(mydb);
1319 self->mydb = mydb;
Gregory P. Smithf0547d02006-06-05 17:38:04 +00001320
Jesus Ceaef9764f2008-05-13 18:45:46 +00001321 INSERT_IN_DOUBLE_LINKED_LIST(self->mydb->children_sequences,self);
Gregory P. Smith664782e2008-05-17 06:12:02 +00001322 self->txn = NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00001323
1324 self->in_weakreflist = NULL;
Jesus Cea6557aac2010-03-22 14:22:26 +00001325 self->sequence = NULL; /* Just in case the call fails */
Gregory P. Smithf0547d02006-06-05 17:38:04 +00001326
1327 MYDB_BEGIN_ALLOW_THREADS;
1328 err = db_sequence_create(&self->sequence, self->mydb->db, flags);
1329 MYDB_END_ALLOW_THREADS;
1330 if (makeDBError(err)) {
Gregory P. Smith664782e2008-05-17 06:12:02 +00001331 Py_DECREF(self);
Gregory P. Smithf0547d02006-06-05 17:38:04 +00001332 self = NULL;
1333 }
1334
1335 return self;
1336}
1337
Jesus Ceaef9764f2008-05-13 18:45:46 +00001338/* Forward declaration */
1339static PyObject
1340*DBSequence_close_internal(DBSequenceObject* self, int flags, int do_not_close);
Gregory P. Smithf0547d02006-06-05 17:38:04 +00001341
1342static void
1343DBSequence_dealloc(DBSequenceObject* self)
1344{
Jesus Ceaef9764f2008-05-13 18:45:46 +00001345 PyObject *dummy;
1346
1347 if (self->sequence != NULL) {
1348 dummy=DBSequence_close_internal(self,0,0);
Jesus Cea5cd5f122008-09-23 18:54:08 +00001349 /*
1350 ** Raising exceptions while doing
1351 ** garbage collection is a fatal error.
1352 */
1353 if (dummy)
1354 Py_DECREF(dummy);
1355 else
1356 PyErr_Clear();
Jesus Ceaef9764f2008-05-13 18:45:46 +00001357 }
1358
Gregory P. Smithf0547d02006-06-05 17:38:04 +00001359 if (self->in_weakreflist != NULL) {
1360 PyObject_ClearWeakRefs((PyObject *) self);
1361 }
Gregory P. Smithf0547d02006-06-05 17:38:04 +00001362
1363 Py_DECREF(self->mydb);
1364 PyObject_Del(self);
1365}
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07001366
1367#if (DBVER >= 52)
1368static DBSiteObject*
1369newDBSiteObject(DB_SITE* sitep, DBEnvObject* env)
1370{
1371 DBSiteObject* self;
1372
1373 self = PyObject_New(DBSiteObject, &DBSite_Type);
1374
1375 if (self == NULL)
1376 return NULL;
1377
1378 self->site = sitep;
1379 self->env = env;
1380
1381 INSERT_IN_DOUBLE_LINKED_LIST(self->env->children_sites, self);
1382
1383 self->in_weakreflist = NULL;
1384 Py_INCREF(self->env);
1385 return self;
1386}
1387
1388/* Forward declaration */
1389static PyObject *DBSite_close_internal(DBSiteObject* self);
1390
1391static void
1392DBSite_dealloc(DBSiteObject* self)
1393{
1394 PyObject *dummy;
1395
1396 if (self->site != NULL) {
1397 dummy = DBSite_close_internal(self);
1398 /*
1399 ** Raising exceptions while doing
1400 ** garbage collection is a fatal error.
1401 */
1402 if (dummy)
1403 Py_DECREF(dummy);
1404 else
1405 PyErr_Clear();
1406 }
1407 if (self->in_weakreflist != NULL) {
1408 PyObject_ClearWeakRefs((PyObject *) self);
1409 }
1410 Py_DECREF(self->env);
1411 PyObject_Del(self);
1412}
Gregory P. Smithf0547d02006-06-05 17:38:04 +00001413#endif
1414
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001415/* --------------------------------------------------------------------- */
1416/* DB methods */
1417
1418static PyObject*
Jesus Cea4907d272008-08-31 14:00:51 +00001419DB_append(DBObject* self, PyObject* args, PyObject* kwargs)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001420{
1421 PyObject* txnobj = NULL;
1422 PyObject* dataobj;
1423 db_recno_t recno;
1424 DBT key, data;
1425 DB_TXN *txn = NULL;
Jesus Cea4907d272008-08-31 14:00:51 +00001426 static char* kwnames[] = { "data", "txn", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001427
Jesus Cea4907d272008-08-31 14:00:51 +00001428 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O:append", kwnames,
1429 &dataobj, &txnobj))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001430 return NULL;
1431
1432 CHECK_DB_NOT_CLOSED(self);
1433
1434 /* make a dummy key out of a recno */
1435 recno = 0;
1436 CLEAR_DBT(key);
1437 key.data = &recno;
1438 key.size = sizeof(recno);
1439 key.ulen = key.size;
1440 key.flags = DB_DBT_USERMEM;
1441
1442 if (!make_dbt(dataobj, &data)) return NULL;
1443 if (!checkTxnObj(txnobj, &txn)) return NULL;
1444
1445 if (-1 == _DB_put(self, txn, &key, &data, DB_APPEND))
1446 return NULL;
1447
Jesus Ceac5a11fa2008-07-23 11:38:42 +00001448 return NUMBER_FromLong(recno);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001449}
1450
1451
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001452static int
Barry Warsaw9a0d7792002-12-30 20:53:52 +00001453_db_associateCallback(DB* db, const DBT* priKey, const DBT* priData,
1454 DBT* secKey)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001455{
1456 int retval = DB_DONOTINDEX;
1457 DBObject* secondaryDB = (DBObject*)db->app_private;
1458 PyObject* callback = secondaryDB->associateCallback;
1459 int type = secondaryDB->primaryDBType;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001460 PyObject* args;
Thomas Wouters89ba3812006-03-07 14:14:51 +00001461 PyObject* result = NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001462
1463
1464 if (callback != NULL) {
1465 MYDB_BEGIN_BLOCK_THREADS;
1466
Thomas Woutersb3153832006-03-08 01:47:19 +00001467 if (type == DB_RECNO || type == DB_QUEUE)
Jesus Ceaef9764f2008-05-13 18:45:46 +00001468 args = BuildValue_LS(*((db_recno_t*)priKey->data), priData->data, priData->size);
Thomas Woutersb3153832006-03-08 01:47:19 +00001469 else
Jesus Ceaef9764f2008-05-13 18:45:46 +00001470 args = BuildValue_SS(priKey->data, priKey->size, priData->data, priData->size);
Thomas Wouters098f6942006-03-07 14:13:17 +00001471 if (args != NULL) {
Thomas Wouters098f6942006-03-07 14:13:17 +00001472 result = PyEval_CallObject(callback, args);
1473 }
1474 if (args == NULL || result == NULL) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001475 PyErr_Print();
1476 }
1477 else if (result == Py_None) {
1478 retval = DB_DONOTINDEX;
1479 }
Jesus Ceac5a11fa2008-07-23 11:38:42 +00001480 else if (NUMBER_Check(result)) {
1481 retval = NUMBER_AsLong(result);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001482 }
Christian Heimes593daf52008-05-26 12:51:38 +00001483 else if (PyBytes_Check(result)) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001484 char* data;
Martin v. Löwis18e16552006-02-15 17:27:45 +00001485 Py_ssize_t size;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001486
1487 CLEAR_DBT(*secKey);
Christian Heimes593daf52008-05-26 12:51:38 +00001488 PyBytes_AsStringAndSize(result, &data, &size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001489 secKey->flags = DB_DBT_APPMALLOC; /* DB will free */
1490 secKey->data = malloc(size); /* TODO, check this */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001491 if (secKey->data) {
1492 memcpy(secKey->data, data, size);
1493 secKey->size = size;
1494 retval = 0;
1495 }
1496 else {
1497 PyErr_SetString(PyExc_MemoryError,
Barry Warsaw9a0d7792002-12-30 20:53:52 +00001498 "malloc failed in _db_associateCallback");
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001499 PyErr_Print();
1500 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001501 }
Jesus Cea6557aac2010-03-22 14:22:26 +00001502#if (DBVER >= 46)
1503 else if (PyList_Check(result))
1504 {
1505 char* data;
Zackery Spytz32522052018-07-21 02:27:44 -06001506 Py_ssize_t size, listlen, i;
Jesus Cea6557aac2010-03-22 14:22:26 +00001507 DBT* dbts;
1508
1509 listlen = PyList_Size(result);
1510
Zackery Spytz32522052018-07-21 02:27:44 -06001511 if (listlen > PY_SIZE_MAX / sizeof(DBT)) {
1512 PyErr_NoMemory();
1513 PyErr_Print();
1514 }
1515 else {
1516 dbts = (DBT *)malloc(sizeof(DBT) * listlen);
1517 if (dbts == NULL) {
1518 PyErr_NoMemory();
1519 PyErr_Print();
1520 }
1521 else {
1522 for (i = 0; i < listlen; i++) {
1523 if (!PyBytes_Check(PyList_GetItem(result, i))) {
1524 PyErr_SetString(PyExc_TypeError,
Jesus Cea6557aac2010-03-22 14:22:26 +00001525#if (PY_VERSION_HEX < 0x03000000)
1526"The list returned by DB->associate callback should be a list of strings.");
1527#else
1528"The list returned by DB->associate callback should be a list of bytes.");
1529#endif
Zackery Spytz32522052018-07-21 02:27:44 -06001530 break;
1531 }
Jesus Cea6557aac2010-03-22 14:22:26 +00001532
Zackery Spytz32522052018-07-21 02:27:44 -06001533 if (PyBytes_AsStringAndSize(PyList_GetItem(result, i),
1534 &data, &size) < 0) {
1535 break;
1536 }
Jesus Cea6557aac2010-03-22 14:22:26 +00001537
Zackery Spytz32522052018-07-21 02:27:44 -06001538 CLEAR_DBT(dbts[i]);
1539 dbts[i].data = malloc(size);
1540 if (dbts[i].data) {
1541 memcpy(dbts[i].data, data, size);
1542 dbts[i].size = size;
1543 dbts[i].ulen = dbts[i].size;
1544 /* DB will free. */
1545 dbts[i].flags = DB_DBT_APPMALLOC;
1546 }
1547 else {
1548 PyErr_SetString(PyExc_MemoryError,
1549 "malloc failed in "
1550 "_db_associateCallback (list)");
1551 break;
1552 }
1553 }
1554 if (PyErr_Occurred()) {
1555 PyErr_Print();
1556 while (i--) {
1557 free(dbts[i].data);
1558 }
1559 free(dbts);
1560 }
1561 else {
1562 CLEAR_DBT(*secKey);
Jesus Cea6557aac2010-03-22 14:22:26 +00001563
Zackery Spytz32522052018-07-21 02:27:44 -06001564 secKey->data = dbts;
1565 secKey->size = listlen;
1566 secKey->flags = DB_DBT_APPMALLOC | DB_DBT_MULTIPLE;
1567 retval = 0;
1568 }
Jesus Cea6557aac2010-03-22 14:22:26 +00001569 }
1570 }
Jesus Cea6557aac2010-03-22 14:22:26 +00001571 }
1572#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001573 else {
Barry Warsaw9a0d7792002-12-30 20:53:52 +00001574 PyErr_SetString(
1575 PyExc_TypeError,
Jesus Cea6557aac2010-03-22 14:22:26 +00001576#if (PY_VERSION_HEX < 0x03000000)
1577"DB associate callback should return DB_DONOTINDEX/string/list of strings.");
1578#else
1579"DB associate callback should return DB_DONOTINDEX/bytes/list of bytes.");
1580#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001581 PyErr_Print();
1582 }
1583
Thomas Woutersb3153832006-03-08 01:47:19 +00001584 Py_XDECREF(args);
1585 Py_XDECREF(result);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001586
1587 MYDB_END_BLOCK_THREADS;
1588 }
1589 return retval;
1590}
1591
1592
1593static PyObject*
1594DB_associate(DBObject* self, PyObject* args, PyObject* kwargs)
1595{
1596 int err, flags=0;
1597 DBObject* secondaryDB;
1598 PyObject* callback;
Barry Warsaw9a0d7792002-12-30 20:53:52 +00001599 PyObject *txnobj = NULL;
1600 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00001601 static char* kwnames[] = {"secondaryDB", "callback", "flags", "txn",
Jeremy Hyltonaf68c872005-12-10 18:50:16 +00001602 NULL};
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001603
Barry Warsaw9a0d7792002-12-30 20:53:52 +00001604 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|iO:associate", kwnames,
1605 &secondaryDB, &callback, &flags,
1606 &txnobj)) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001607 return NULL;
Barry Warsaw9a0d7792002-12-30 20:53:52 +00001608 }
1609
Barry Warsaw9a0d7792002-12-30 20:53:52 +00001610 if (!checkTxnObj(txnobj, &txn)) return NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001611
1612 CHECK_DB_NOT_CLOSED(self);
1613 if (!DBObject_Check(secondaryDB)) {
1614 makeTypeError("DB", (PyObject*)secondaryDB);
1615 return NULL;
1616 }
Gregory P. Smith91116b62005-06-06 10:28:06 +00001617 CHECK_DB_NOT_CLOSED(secondaryDB);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001618 if (callback == Py_None) {
1619 callback = NULL;
1620 }
1621 else if (!PyCallable_Check(callback)) {
1622 makeTypeError("Callable", callback);
1623 return NULL;
1624 }
1625
1626 /* Save a reference to the callback in the secondary DB. */
Thomas Woutersb3153832006-03-08 01:47:19 +00001627 Py_XINCREF(callback);
Serhiy Storchakabc62af12016-04-06 09:51:18 +03001628 Py_XSETREF(secondaryDB->associateCallback, callback);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001629 secondaryDB->primaryDBType = _DB_get_type(self);
1630
Martin v. Löwisb2c7aff2002-11-23 11:26:07 +00001631 /* PyEval_InitThreads is called here due to a quirk in python 1.5
1632 * - 2.2.1 (at least) according to Russell Williamson <merel@wt.net>:
1633 * The global interepreter lock is not initialized until the first
1634 * thread is created using thread.start_new_thread() or fork() is
1635 * called. that would cause the ALLOW_THREADS here to segfault due
1636 * to a null pointer reference if no threads or child processes
1637 * have been created. This works around that and is a no-op if
1638 * threads have already been initialized.
1639 * (see pybsddb-users mailing list post on 2002-08-07)
1640 */
Gregory P. Smithaa71f5f2003-01-17 07:56:16 +00001641#ifdef WITH_THREAD
Martin v. Löwisb2c7aff2002-11-23 11:26:07 +00001642 PyEval_InitThreads();
Gregory P. Smithaa71f5f2003-01-17 07:56:16 +00001643#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001644 MYDB_BEGIN_ALLOW_THREADS;
Barry Warsaw9a0d7792002-12-30 20:53:52 +00001645 err = self->db->associate(self->db,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001646 txn,
Barry Warsaw9a0d7792002-12-30 20:53:52 +00001647 secondaryDB->db,
1648 _db_associateCallback,
1649 flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001650 MYDB_END_ALLOW_THREADS;
1651
1652 if (err) {
Serhiy Storchaka98a97222014-02-09 13:14:04 +02001653 Py_CLEAR(secondaryDB->associateCallback);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001654 secondaryDB->primaryDBType = 0;
1655 }
1656
1657 RETURN_IF_ERR();
1658 RETURN_NONE();
1659}
1660
1661
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001662static PyObject*
Jesus Cea5cd5f122008-09-23 18:54:08 +00001663DB_close_internal(DBObject* self, int flags, int do_not_close)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001664{
Jesus Ceaef9764f2008-05-13 18:45:46 +00001665 PyObject *dummy;
Jesus Cea5cd5f122008-09-23 18:54:08 +00001666 int err = 0;
Jesus Ceaef9764f2008-05-13 18:45:46 +00001667
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001668 if (self->db != NULL) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00001669 /* Can be NULL if db is not in an environment */
1670 EXTRACT_FROM_DOUBLE_LINKED_LIST_MAYBE_NULL(self);
Jesus Cea4907d272008-08-31 14:00:51 +00001671
Jesus Ceaef9764f2008-05-13 18:45:46 +00001672 if (self->txn) {
1673 EXTRACT_FROM_DOUBLE_LINKED_LIST_TXN(self);
1674 self->txn=NULL;
1675 }
1676
1677 while(self->children_cursors) {
1678 dummy=DBC_close_internal(self->children_cursors);
1679 Py_XDECREF(dummy);
1680 }
1681
Jesus Ceaef9764f2008-05-13 18:45:46 +00001682 while(self->children_sequences) {
1683 dummy=DBSequence_close_internal(self->children_sequences,0,0);
1684 Py_XDECREF(dummy);
1685 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00001686
Jesus Cea5cd5f122008-09-23 18:54:08 +00001687 /*
1688 ** "do_not_close" is used to dispose all related objects in the
1689 ** tree, without actually releasing the "root" object.
1690 ** This is done, for example, because function calls like
1691 ** "DB.verify()" implicitly close the underlying handle. So
1692 ** the handle doesn't need to be closed, but related objects
1693 ** must be cleaned up.
1694 */
1695 if (!do_not_close) {
1696 MYDB_BEGIN_ALLOW_THREADS;
1697 err = self->db->close(self->db, flags);
1698 MYDB_END_ALLOW_THREADS;
1699 self->db = NULL;
1700 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001701 RETURN_IF_ERR();
1702 }
1703 RETURN_NONE();
1704}
1705
Jesus Ceaef9764f2008-05-13 18:45:46 +00001706static PyObject*
1707DB_close(DBObject* self, PyObject* args)
1708{
1709 int flags=0;
1710 if (!PyArg_ParseTuple(args,"|i:close", &flags))
1711 return NULL;
Jesus Cea5cd5f122008-09-23 18:54:08 +00001712 return DB_close_internal(self, flags, 0);
Jesus Ceaef9764f2008-05-13 18:45:46 +00001713}
1714
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001715
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001716static PyObject*
1717_DB_consume(DBObject* self, PyObject* args, PyObject* kwargs, int consume_flag)
1718{
1719 int err, flags=0, type;
1720 PyObject* txnobj = NULL;
1721 PyObject* retval = NULL;
1722 DBT key, data;
1723 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00001724 static char* kwnames[] = { "txn", "flags", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001725
1726 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Oi:consume", kwnames,
1727 &txnobj, &flags))
1728 return NULL;
1729
1730 CHECK_DB_NOT_CLOSED(self);
1731 type = _DB_get_type(self);
1732 if (type == -1)
1733 return NULL;
1734 if (type != DB_QUEUE) {
Barry Warsaw9a0d7792002-12-30 20:53:52 +00001735 PyErr_SetString(PyExc_TypeError,
1736 "Consume methods only allowed for Queue DB's");
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001737 return NULL;
1738 }
1739 if (!checkTxnObj(txnobj, &txn))
1740 return NULL;
1741
1742 CLEAR_DBT(key);
1743 CLEAR_DBT(data);
1744 if (CHECK_DBFLAG(self, DB_THREAD)) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00001745 /* Tell Berkeley DB to malloc the return value (thread safe) */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001746 data.flags = DB_DBT_MALLOC;
1747 key.flags = DB_DBT_MALLOC;
1748 }
1749
1750 MYDB_BEGIN_ALLOW_THREADS;
1751 err = self->db->get(self->db, txn, &key, &data, flags|consume_flag);
1752 MYDB_END_ALLOW_THREADS;
1753
Gregory P. Smithe9477062005-06-04 06:46:59 +00001754 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001755 && self->moduleFlags.getReturnsNone) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001756 err = 0;
1757 Py_INCREF(Py_None);
1758 retval = Py_None;
1759 }
1760 else if (!err) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00001761 retval = BuildValue_SS(key.data, key.size, data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001762 FREE_DBT(key);
1763 FREE_DBT(data);
1764 }
1765
1766 RETURN_IF_ERR();
1767 return retval;
1768}
1769
1770static PyObject*
1771DB_consume(DBObject* self, PyObject* args, PyObject* kwargs, int consume_flag)
1772{
1773 return _DB_consume(self, args, kwargs, DB_CONSUME);
1774}
1775
1776static PyObject*
Barry Warsaw9a0d7792002-12-30 20:53:52 +00001777DB_consume_wait(DBObject* self, PyObject* args, PyObject* kwargs,
1778 int consume_flag)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001779{
1780 return _DB_consume(self, args, kwargs, DB_CONSUME_WAIT);
1781}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001782
1783
1784static PyObject*
1785DB_cursor(DBObject* self, PyObject* args, PyObject* kwargs)
1786{
1787 int err, flags=0;
1788 DBC* dbc;
1789 PyObject* txnobj = NULL;
1790 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00001791 static char* kwnames[] = { "txn", "flags", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001792
1793 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Oi:cursor", kwnames,
1794 &txnobj, &flags))
1795 return NULL;
1796 CHECK_DB_NOT_CLOSED(self);
1797 if (!checkTxnObj(txnobj, &txn))
1798 return NULL;
1799
1800 MYDB_BEGIN_ALLOW_THREADS;
1801 err = self->db->cursor(self->db, txn, &dbc, flags);
1802 MYDB_END_ALLOW_THREADS;
1803 RETURN_IF_ERR();
Jesus Ceaef9764f2008-05-13 18:45:46 +00001804 return (PyObject*) newDBCursorObject(dbc, (DBTxnObject *)txnobj, self);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001805}
1806
1807
1808static PyObject*
1809DB_delete(DBObject* self, PyObject* args, PyObject* kwargs)
1810{
1811 PyObject* txnobj = NULL;
1812 int flags = 0;
1813 PyObject* keyobj;
1814 DBT key;
1815 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00001816 static char* kwnames[] = { "key", "txn", "flags", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001817
1818 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|Oi:delete", kwnames,
1819 &keyobj, &txnobj, &flags))
1820 return NULL;
1821 CHECK_DB_NOT_CLOSED(self);
1822 if (!make_key_dbt(self, keyobj, &key, NULL))
1823 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00001824 if (!checkTxnObj(txnobj, &txn)) {
1825 FREE_DBT(key);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001826 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00001827 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001828
Gregory P. Smithdc5af702004-06-27 23:32:34 +00001829 if (-1 == _DB_delete(self, txn, &key, 0)) {
1830 FREE_DBT(key);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001831 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00001832 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001833
1834 FREE_DBT(key);
1835 RETURN_NONE();
1836}
1837
1838
Jesus Cea6557aac2010-03-22 14:22:26 +00001839#if (DBVER >= 47)
1840/*
1841** This function is available since Berkeley DB 4.4,
1842** but 4.6 version is so buggy that we only support
1843** it from BDB 4.7 and newer.
1844*/
1845static PyObject*
1846DB_compact(DBObject* self, PyObject* args, PyObject* kwargs)
1847{
1848 PyObject* txnobj = NULL;
1849 PyObject *startobj = NULL, *stopobj = NULL;
1850 int flags = 0;
1851 DB_TXN *txn = NULL;
1852 DBT *start_p = NULL, *stop_p = NULL;
1853 DBT start, stop;
1854 int err;
1855 DB_COMPACT c_data = { 0 };
1856 static char* kwnames[] = { "txn", "start", "stop", "flags",
1857 "compact_fillpercent", "compact_pages",
1858 "compact_timeout", NULL };
1859
1860
1861 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OOOiiiI:compact", kwnames,
1862 &txnobj, &startobj, &stopobj, &flags,
1863 &c_data.compact_fillpercent,
1864 &c_data.compact_pages,
1865 &c_data.compact_timeout))
1866 return NULL;
1867
1868 CHECK_DB_NOT_CLOSED(self);
1869 if (!checkTxnObj(txnobj, &txn)) {
1870 return NULL;
1871 }
1872
1873 if (startobj && make_key_dbt(self, startobj, &start, NULL)) {
1874 start_p = &start;
1875 }
1876 if (stopobj && make_key_dbt(self, stopobj, &stop, NULL)) {
1877 stop_p = &stop;
1878 }
1879
1880 MYDB_BEGIN_ALLOW_THREADS;
1881 err = self->db->compact(self->db, txn, start_p, stop_p, &c_data,
1882 flags, NULL);
1883 MYDB_END_ALLOW_THREADS;
1884
1885 if (startobj)
1886 FREE_DBT(start);
1887 if (stopobj)
1888 FREE_DBT(stop);
1889
1890 RETURN_IF_ERR();
1891
1892 return PyLong_FromUnsignedLong(c_data.compact_pages_truncated);
1893}
1894#endif
1895
1896
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001897static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00001898DB_fd(DBObject* self)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001899{
1900 int err, the_fd;
1901
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001902 CHECK_DB_NOT_CLOSED(self);
1903
1904 MYDB_BEGIN_ALLOW_THREADS;
1905 err = self->db->fd(self->db, &the_fd);
1906 MYDB_END_ALLOW_THREADS;
1907 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00001908 return NUMBER_FromLong(the_fd);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001909}
1910
1911
Jesus Cea6557aac2010-03-22 14:22:26 +00001912#if (DBVER >= 46)
1913static PyObject*
1914DB_exists(DBObject* self, PyObject* args, PyObject* kwargs)
1915{
1916 int err, flags=0;
1917 PyObject* txnobj = NULL;
1918 PyObject* keyobj;
1919 DBT key;
1920 DB_TXN *txn;
1921
1922 static char* kwnames[] = {"key", "txn", "flags", NULL};
1923
1924 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|Oi:exists", kwnames,
1925 &keyobj, &txnobj, &flags))
1926 return NULL;
1927
1928 CHECK_DB_NOT_CLOSED(self);
1929 if (!make_key_dbt(self, keyobj, &key, NULL))
1930 return NULL;
1931 if (!checkTxnObj(txnobj, &txn)) {
1932 FREE_DBT(key);
1933 return NULL;
1934 }
1935
1936 MYDB_BEGIN_ALLOW_THREADS;
1937 err = self->db->exists(self->db, txn, &key, flags);
1938 MYDB_END_ALLOW_THREADS;
1939
1940 FREE_DBT(key);
1941
1942 if (!err) {
1943 Py_INCREF(Py_True);
1944 return Py_True;
1945 }
1946 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)) {
1947 Py_INCREF(Py_False);
1948 return Py_False;
1949 }
1950
1951 /*
1952 ** If we reach there, there was an error. The
1953 ** "return" should be unreachable.
1954 */
1955 RETURN_IF_ERR();
1956 assert(0); /* This coude SHOULD be unreachable */
1957 return NULL;
1958}
1959#endif
1960
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001961static PyObject*
1962DB_get(DBObject* self, PyObject* args, PyObject* kwargs)
1963{
1964 int err, flags=0;
1965 PyObject* txnobj = NULL;
1966 PyObject* keyobj;
1967 PyObject* dfltobj = NULL;
1968 PyObject* retval = NULL;
1969 int dlen = -1;
1970 int doff = -1;
1971 DBT key, data;
1972 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00001973 static char* kwnames[] = {"key", "default", "txn", "flags", "dlen",
Jeremy Hyltonaf68c872005-12-10 18:50:16 +00001974 "doff", NULL};
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001975
1976 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|OOiii:get", kwnames,
Barry Warsaw9a0d7792002-12-30 20:53:52 +00001977 &keyobj, &dfltobj, &txnobj, &flags, &dlen,
1978 &doff))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001979 return NULL;
1980
1981 CHECK_DB_NOT_CLOSED(self);
1982 if (!make_key_dbt(self, keyobj, &key, &flags))
1983 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00001984 if (!checkTxnObj(txnobj, &txn)) {
1985 FREE_DBT(key);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001986 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00001987 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001988
1989 CLEAR_DBT(data);
1990 if (CHECK_DBFLAG(self, DB_THREAD)) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00001991 /* Tell Berkeley DB to malloc the return value (thread safe) */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001992 data.flags = DB_DBT_MALLOC;
1993 }
Gregory P. Smithdc5af702004-06-27 23:32:34 +00001994 if (!add_partial_dbt(&data, dlen, doff)) {
1995 FREE_DBT(key);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001996 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00001997 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001998
1999 MYDB_BEGIN_ALLOW_THREADS;
2000 err = self->db->get(self->db, txn, &key, &data, flags);
2001 MYDB_END_ALLOW_THREADS;
2002
Gregory P. Smithe9477062005-06-04 06:46:59 +00002003 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY) && (dfltobj != NULL)) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002004 err = 0;
2005 Py_INCREF(dfltobj);
2006 retval = dfltobj;
2007 }
Gregory P. Smithe9477062005-06-04 06:46:59 +00002008 else if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002009 && self->moduleFlags.getReturnsNone) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002010 err = 0;
2011 Py_INCREF(Py_None);
2012 retval = Py_None;
2013 }
2014 else if (!err) {
2015 if (flags & DB_SET_RECNO) /* return both key and data */
Jesus Ceaef9764f2008-05-13 18:45:46 +00002016 retval = BuildValue_SS(key.data, key.size, data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002017 else /* return just the data */
Jesus Ceaef9764f2008-05-13 18:45:46 +00002018 retval = Build_PyString(data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002019 FREE_DBT(data);
2020 }
Gregory P. Smithdc5af702004-06-27 23:32:34 +00002021 FREE_DBT(key);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002022
2023 RETURN_IF_ERR();
2024 return retval;
2025}
2026
Gregory P. Smith19699a92004-06-28 04:06:49 +00002027static PyObject*
2028DB_pget(DBObject* self, PyObject* args, PyObject* kwargs)
2029{
2030 int err, flags=0;
2031 PyObject* txnobj = NULL;
2032 PyObject* keyobj;
2033 PyObject* dfltobj = NULL;
2034 PyObject* retval = NULL;
2035 int dlen = -1;
2036 int doff = -1;
2037 DBT key, pkey, data;
2038 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002039 static char* kwnames[] = {"key", "default", "txn", "flags", "dlen",
Jeremy Hyltonaf68c872005-12-10 18:50:16 +00002040 "doff", NULL};
Gregory P. Smith19699a92004-06-28 04:06:49 +00002041
2042 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|OOiii:pget", kwnames,
2043 &keyobj, &dfltobj, &txnobj, &flags, &dlen,
2044 &doff))
2045 return NULL;
2046
2047 CHECK_DB_NOT_CLOSED(self);
2048 if (!make_key_dbt(self, keyobj, &key, &flags))
2049 return NULL;
2050 if (!checkTxnObj(txnobj, &txn)) {
2051 FREE_DBT(key);
2052 return NULL;
2053 }
2054
2055 CLEAR_DBT(data);
2056 if (CHECK_DBFLAG(self, DB_THREAD)) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00002057 /* Tell Berkeley DB to malloc the return value (thread safe) */
Gregory P. Smith19699a92004-06-28 04:06:49 +00002058 data.flags = DB_DBT_MALLOC;
2059 }
2060 if (!add_partial_dbt(&data, dlen, doff)) {
2061 FREE_DBT(key);
2062 return NULL;
2063 }
2064
2065 CLEAR_DBT(pkey);
2066 pkey.flags = DB_DBT_MALLOC;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002067
Gregory P. Smith19699a92004-06-28 04:06:49 +00002068 MYDB_BEGIN_ALLOW_THREADS;
2069 err = self->db->pget(self->db, txn, &key, &pkey, &data, flags);
2070 MYDB_END_ALLOW_THREADS;
2071
Gregory P. Smithe9477062005-06-04 06:46:59 +00002072 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY) && (dfltobj != NULL)) {
Gregory P. Smith19699a92004-06-28 04:06:49 +00002073 err = 0;
2074 Py_INCREF(dfltobj);
2075 retval = dfltobj;
2076 }
Gregory P. Smithe9477062005-06-04 06:46:59 +00002077 else if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002078 && self->moduleFlags.getReturnsNone) {
Gregory P. Smith19699a92004-06-28 04:06:49 +00002079 err = 0;
2080 Py_INCREF(Py_None);
2081 retval = Py_None;
2082 }
2083 else if (!err) {
2084 PyObject *pkeyObj;
2085 PyObject *dataObj;
Jesus Ceaef9764f2008-05-13 18:45:46 +00002086 dataObj = Build_PyString(data.data, data.size);
Gregory P. Smith19699a92004-06-28 04:06:49 +00002087
2088 if (self->primaryDBType == DB_RECNO ||
2089 self->primaryDBType == DB_QUEUE)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002090 pkeyObj = NUMBER_FromLong(*(int *)pkey.data);
Gregory P. Smith19699a92004-06-28 04:06:49 +00002091 else
Jesus Ceaef9764f2008-05-13 18:45:46 +00002092 pkeyObj = Build_PyString(pkey.data, pkey.size);
Gregory P. Smith19699a92004-06-28 04:06:49 +00002093
2094 if (flags & DB_SET_RECNO) /* return key , pkey and data */
2095 {
2096 PyObject *keyObj;
2097 int type = _DB_get_type(self);
2098 if (type == DB_RECNO || type == DB_QUEUE)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002099 keyObj = NUMBER_FromLong(*(int *)key.data);
Gregory P. Smith19699a92004-06-28 04:06:49 +00002100 else
Jesus Ceaef9764f2008-05-13 18:45:46 +00002101 keyObj = Build_PyString(key.data, key.size);
Gregory P. Smith4e414d82006-01-24 19:55:02 +00002102 retval = PyTuple_Pack(3, keyObj, pkeyObj, dataObj);
Thomas Woutersb3153832006-03-08 01:47:19 +00002103 Py_DECREF(keyObj);
Gregory P. Smith19699a92004-06-28 04:06:49 +00002104 }
2105 else /* return just the pkey and data */
2106 {
Gregory P. Smith4e414d82006-01-24 19:55:02 +00002107 retval = PyTuple_Pack(2, pkeyObj, dataObj);
Gregory P. Smith19699a92004-06-28 04:06:49 +00002108 }
Thomas Woutersb3153832006-03-08 01:47:19 +00002109 Py_DECREF(dataObj);
2110 Py_DECREF(pkeyObj);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002111 FREE_DBT(pkey);
Gregory P. Smith19699a92004-06-28 04:06:49 +00002112 FREE_DBT(data);
2113 }
2114 FREE_DBT(key);
2115
2116 RETURN_IF_ERR();
2117 return retval;
2118}
2119
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002120
2121/* Return size of entry */
2122static PyObject*
2123DB_get_size(DBObject* self, PyObject* args, PyObject* kwargs)
2124{
2125 int err, flags=0;
2126 PyObject* txnobj = NULL;
2127 PyObject* keyobj;
2128 PyObject* retval = NULL;
2129 DBT key, data;
2130 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002131 static char* kwnames[] = { "key", "txn", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002132
2133 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O:get_size", kwnames,
2134 &keyobj, &txnobj))
2135 return NULL;
2136 CHECK_DB_NOT_CLOSED(self);
2137 if (!make_key_dbt(self, keyobj, &key, &flags))
2138 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00002139 if (!checkTxnObj(txnobj, &txn)) {
2140 FREE_DBT(key);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002141 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00002142 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002143 CLEAR_DBT(data);
2144
Gregory P. Smith8b7e9172004-12-13 09:51:23 +00002145 /* We don't allocate any memory, forcing a DB_BUFFER_SMALL error and
2146 thus getting the record size. */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002147 data.flags = DB_DBT_USERMEM;
2148 data.ulen = 0;
2149 MYDB_BEGIN_ALLOW_THREADS;
2150 err = self->db->get(self->db, txn, &key, &data, flags);
2151 MYDB_END_ALLOW_THREADS;
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07002152 if ((err == DB_BUFFER_SMALL) || (err == 0)) {
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002153 retval = NUMBER_FromLong((long)data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002154 err = 0;
2155 }
2156
2157 FREE_DBT(key);
2158 FREE_DBT(data);
2159 RETURN_IF_ERR();
2160 return retval;
2161}
2162
2163
2164static PyObject*
2165DB_get_both(DBObject* self, PyObject* args, PyObject* kwargs)
2166{
2167 int err, flags=0;
2168 PyObject* txnobj = NULL;
2169 PyObject* keyobj;
2170 PyObject* dataobj;
2171 PyObject* retval = NULL;
2172 DBT key, data;
Neal Norwitz994ebed2007-06-03 20:32:50 +00002173 void *orig_data;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002174 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002175 static char* kwnames[] = { "key", "data", "txn", "flags", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002176
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002177 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|Oi:get_both", kwnames,
2178 &keyobj, &dataobj, &txnobj, &flags))
2179 return NULL;
2180
2181 CHECK_DB_NOT_CLOSED(self);
2182 if (!make_key_dbt(self, keyobj, &key, NULL))
2183 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00002184 if ( !make_dbt(dataobj, &data) ||
2185 !checkTxnObj(txnobj, &txn) )
2186 {
2187 FREE_DBT(key);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002188 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00002189 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002190
2191 flags |= DB_GET_BOTH;
Neal Norwitz994ebed2007-06-03 20:32:50 +00002192 orig_data = data.data;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002193
2194 if (CHECK_DBFLAG(self, DB_THREAD)) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00002195 /* Tell Berkeley DB to malloc the return value (thread safe) */
Neal Norwitz994ebed2007-06-03 20:32:50 +00002196 /* XXX(nnorwitz): At least 4.4.20 and 4.5.20 require this flag. */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002197 data.flags = DB_DBT_MALLOC;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002198 }
2199
2200 MYDB_BEGIN_ALLOW_THREADS;
2201 err = self->db->get(self->db, txn, &key, &data, flags);
2202 MYDB_END_ALLOW_THREADS;
2203
Gregory P. Smithe9477062005-06-04 06:46:59 +00002204 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002205 && self->moduleFlags.getReturnsNone) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002206 err = 0;
2207 Py_INCREF(Py_None);
2208 retval = Py_None;
2209 }
2210 else if (!err) {
Neal Norwitz994ebed2007-06-03 20:32:50 +00002211 /* XXX(nnorwitz): can we do: retval = dataobj; Py_INCREF(retval); */
Jesus Ceaef9764f2008-05-13 18:45:46 +00002212 retval = Build_PyString(data.data, data.size);
Neal Norwitz994ebed2007-06-03 20:32:50 +00002213
2214 /* Even though the flags require DB_DBT_MALLOC, data is not always
2215 allocated. 4.4: allocated, 4.5: *not* allocated. :-( */
2216 if (data.data != orig_data)
2217 FREE_DBT(data);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002218 }
2219
2220 FREE_DBT(key);
2221 RETURN_IF_ERR();
2222 return retval;
2223}
2224
2225
2226static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002227DB_get_byteswapped(DBObject* self)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002228{
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002229 int err = 0;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002230 int retval = -1;
2231
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002232 CHECK_DB_NOT_CLOSED(self);
2233
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002234 MYDB_BEGIN_ALLOW_THREADS;
2235 err = self->db->get_byteswapped(self->db, &retval);
2236 MYDB_END_ALLOW_THREADS;
2237 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002238 return NUMBER_FromLong(retval);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002239}
2240
2241
2242static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002243DB_get_type(DBObject* self)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002244{
2245 int type;
2246
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002247 CHECK_DB_NOT_CLOSED(self);
2248
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002249 type = _DB_get_type(self);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002250 if (type == -1)
2251 return NULL;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002252 return NUMBER_FromLong(type);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002253}
2254
2255
2256static PyObject*
2257DB_join(DBObject* self, PyObject* args)
2258{
2259 int err, flags=0;
Zackery Spytz041a4ee2018-07-22 10:53:56 -06002260 Py_ssize_t length, x;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002261 PyObject* cursorsObj;
2262 DBC** cursors;
2263 DBC* dbc;
2264
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002265 if (!PyArg_ParseTuple(args,"O|i:join", &cursorsObj, &flags))
2266 return NULL;
2267
2268 CHECK_DB_NOT_CLOSED(self);
2269
2270 if (!PySequence_Check(cursorsObj)) {
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002271 PyErr_SetString(PyExc_TypeError,
2272 "Sequence of DBCursor objects expected");
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002273 return NULL;
2274 }
2275
2276 length = PyObject_Length(cursorsObj);
Zackery Spytz041a4ee2018-07-22 10:53:56 -06002277 if (length == -1) {
2278 return NULL;
2279 }
2280 if (length >= PY_SSIZE_T_MAX / sizeof(DBC*)) {
2281 return PyErr_NoMemory();
2282 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002283 cursors = malloc((length+1) * sizeof(DBC*));
Neal Norwitz5aa96892006-08-13 18:11:43 +00002284 if (!cursors) {
Jesus Cea6557aac2010-03-22 14:22:26 +00002285 PyErr_NoMemory();
2286 return NULL;
Neal Norwitz5aa96892006-08-13 18:11:43 +00002287 }
2288
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002289 cursors[length] = NULL;
2290 for (x=0; x<length; x++) {
2291 PyObject* item = PySequence_GetItem(cursorsObj, x);
Thomas Woutersb3153832006-03-08 01:47:19 +00002292 if (item == NULL) {
2293 free(cursors);
2294 return NULL;
2295 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002296 if (!DBCursorObject_Check(item)) {
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002297 PyErr_SetString(PyExc_TypeError,
2298 "Sequence of DBCursor objects expected");
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002299 free(cursors);
Zackery Spytz032e85f2018-08-24 22:22:21 -06002300 Py_DECREF(item);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002301 return NULL;
2302 }
2303 cursors[x] = ((DBCursorObject*)item)->dbc;
Thomas Woutersb2820ae2006-03-12 00:01:38 +00002304 Py_DECREF(item);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002305 }
2306
2307 MYDB_BEGIN_ALLOW_THREADS;
2308 err = self->db->join(self->db, cursors, &dbc, flags);
2309 MYDB_END_ALLOW_THREADS;
2310 free(cursors);
2311 RETURN_IF_ERR();
2312
Gregory P. Smith7441e652003-11-03 21:35:31 +00002313 /* FIXME: this is a buggy interface. The returned cursor
2314 contains internal references to the passed in cursors
2315 but does not hold python references to them or prevent
2316 them from being closed prematurely. This can cause
2317 python to crash when things are done in the wrong order. */
Jesus Ceaef9764f2008-05-13 18:45:46 +00002318 return (PyObject*) newDBCursorObject(dbc, NULL, self);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002319}
2320
2321
2322static PyObject*
2323DB_key_range(DBObject* self, PyObject* args, PyObject* kwargs)
2324{
2325 int err, flags=0;
2326 PyObject* txnobj = NULL;
2327 PyObject* keyobj;
2328 DBT key;
2329 DB_TXN *txn = NULL;
2330 DB_KEY_RANGE range;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002331 static char* kwnames[] = { "key", "txn", "flags", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002332
2333 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|Oi:key_range", kwnames,
2334 &keyobj, &txnobj, &flags))
2335 return NULL;
2336 CHECK_DB_NOT_CLOSED(self);
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002337 if (!make_dbt(keyobj, &key))
2338 /* BTree only, don't need to allow for an int key */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002339 return NULL;
2340 if (!checkTxnObj(txnobj, &txn))
2341 return NULL;
2342
2343 MYDB_BEGIN_ALLOW_THREADS;
2344 err = self->db->key_range(self->db, txn, &key, &range, flags);
2345 MYDB_END_ALLOW_THREADS;
2346
2347 RETURN_IF_ERR();
2348 return Py_BuildValue("ddd", range.less, range.equal, range.greater);
2349}
2350
2351
2352static PyObject*
2353DB_open(DBObject* self, PyObject* args, PyObject* kwargs)
2354{
2355 int err, type = DB_UNKNOWN, flags=0, mode=0660;
2356 char* filename = NULL;
2357 char* dbname = NULL;
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002358 PyObject *txnobj = NULL;
2359 DB_TXN *txn = NULL;
2360 /* with dbname */
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002361 static char* kwnames[] = {
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002362 "filename", "dbname", "dbtype", "flags", "mode", "txn", NULL};
2363 /* without dbname */
Tim Peters85b10522006-02-28 18:33:35 +00002364 static char* kwnames_basic[] = {
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002365 "filename", "dbtype", "flags", "mode", "txn", NULL};
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002366
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002367 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "z|ziiiO:open", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002368 &filename, &dbname, &type, &flags, &mode,
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002369 &txnobj))
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002370 {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002371 PyErr_Clear();
2372 type = DB_UNKNOWN; flags = 0; mode = 0660;
2373 filename = NULL; dbname = NULL;
2374 if (!PyArg_ParseTupleAndKeywords(args, kwargs,"z|iiiO:open",
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002375 kwnames_basic,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002376 &filename, &type, &flags, &mode,
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002377 &txnobj))
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002378 return NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002379 }
2380
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002381 if (!checkTxnObj(txnobj, &txn)) return NULL;
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002382
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002383 if (NULL == self->db) {
Thomas Woutersb3153832006-03-08 01:47:19 +00002384 PyObject *t = Py_BuildValue("(is)", 0,
2385 "Cannot call open() twice for DB object");
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002386 if (t) {
2387 PyErr_SetObject(DBError, t);
2388 Py_DECREF(t);
2389 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002390 return NULL;
2391 }
2392
Jesus Ceaef9764f2008-05-13 18:45:46 +00002393 if (txn) { /* Can't use 'txnobj' because could be 'txnobj==Py_None' */
2394 INSERT_IN_DOUBLE_LINKED_LIST_TXN(((DBTxnObject *)txnobj)->children_dbs,self);
2395 self->txn=(DBTxnObject *)txnobj;
2396 } else {
2397 self->txn=NULL;
2398 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00002399
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002400 MYDB_BEGIN_ALLOW_THREADS;
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002401 err = self->db->open(self->db, txn, filename, dbname, type, flags, mode);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002402 MYDB_END_ALLOW_THREADS;
Jesus Cea6557aac2010-03-22 14:22:26 +00002403
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002404 if (makeDBError(err)) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00002405 PyObject *dummy;
2406
Jesus Cea5cd5f122008-09-23 18:54:08 +00002407 dummy=DB_close_internal(self, 0, 0);
Jesus Ceaef9764f2008-05-13 18:45:46 +00002408 Py_XDECREF(dummy);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002409 return NULL;
2410 }
2411
Gregory P. Smithec10a4a2007-11-05 02:32:26 +00002412 self->db->get_flags(self->db, &self->setflags);
2413
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002414 self->flags = flags;
Jesus Ceaef9764f2008-05-13 18:45:46 +00002415
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002416 RETURN_NONE();
2417}
2418
2419
2420static PyObject*
2421DB_put(DBObject* self, PyObject* args, PyObject* kwargs)
2422{
2423 int flags=0;
2424 PyObject* txnobj = NULL;
2425 int dlen = -1;
2426 int doff = -1;
2427 PyObject* keyobj, *dataobj, *retval;
2428 DBT key, data;
2429 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002430 static char* kwnames[] = { "key", "data", "txn", "flags", "dlen",
Jeremy Hyltonaf68c872005-12-10 18:50:16 +00002431 "doff", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002432
2433 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|Oiii:put", kwnames,
2434 &keyobj, &dataobj, &txnobj, &flags, &dlen, &doff))
2435 return NULL;
2436
2437 CHECK_DB_NOT_CLOSED(self);
Gregory P. Smithdc5af702004-06-27 23:32:34 +00002438 if (!make_key_dbt(self, keyobj, &key, NULL))
2439 return NULL;
2440 if ( !make_dbt(dataobj, &data) ||
2441 !add_partial_dbt(&data, dlen, doff) ||
2442 !checkTxnObj(txnobj, &txn) )
2443 {
2444 FREE_DBT(key);
2445 return NULL;
2446 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002447
2448 if (-1 == _DB_put(self, txn, &key, &data, flags)) {
2449 FREE_DBT(key);
2450 return NULL;
2451 }
2452
2453 if (flags & DB_APPEND)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002454 retval = NUMBER_FromLong(*((db_recno_t*)key.data));
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002455 else {
2456 retval = Py_None;
2457 Py_INCREF(retval);
2458 }
2459 FREE_DBT(key);
2460 return retval;
2461}
2462
2463
2464
2465static PyObject*
2466DB_remove(DBObject* self, PyObject* args, PyObject* kwargs)
2467{
2468 char* filename;
2469 char* database = NULL;
2470 int err, flags=0;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002471 static char* kwnames[] = { "filename", "dbname", "flags", NULL};
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002472
2473 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|zi:remove", kwnames,
2474 &filename, &database, &flags))
2475 return NULL;
2476 CHECK_DB_NOT_CLOSED(self);
2477
Jesus Cea4907d272008-08-31 14:00:51 +00002478 EXTRACT_FROM_DOUBLE_LINKED_LIST_MAYBE_NULL(self);
2479
2480 MYDB_BEGIN_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002481 err = self->db->remove(self->db, filename, database, flags);
Jesus Cea4907d272008-08-31 14:00:51 +00002482 MYDB_END_ALLOW_THREADS;
2483
Gregory P. Smithf655dff2003-05-15 00:13:18 +00002484 self->db = NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002485 RETURN_IF_ERR();
2486 RETURN_NONE();
2487}
2488
2489
2490
2491static PyObject*
2492DB_rename(DBObject* self, PyObject* args)
2493{
2494 char* filename;
2495 char* database;
2496 char* newname;
2497 int err, flags=0;
2498
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002499 if (!PyArg_ParseTuple(args, "sss|i:rename", &filename, &database, &newname,
2500 &flags))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002501 return NULL;
2502 CHECK_DB_NOT_CLOSED(self);
2503
2504 MYDB_BEGIN_ALLOW_THREADS;
2505 err = self->db->rename(self->db, filename, database, newname, flags);
2506 MYDB_END_ALLOW_THREADS;
2507 RETURN_IF_ERR();
2508 RETURN_NONE();
2509}
2510
2511
2512static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002513DB_get_private(DBObject* self)
2514{
2515 /* We can give out the private field even if db is closed */
Jesus Cea4907d272008-08-31 14:00:51 +00002516 Py_INCREF(self->private_obj);
2517 return self->private_obj;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002518}
2519
2520static PyObject*
Jesus Cea4907d272008-08-31 14:00:51 +00002521DB_set_private(DBObject* self, PyObject* private_obj)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002522{
2523 /* We can set the private field even if db is closed */
Jesus Cea4907d272008-08-31 14:00:51 +00002524 Py_INCREF(private_obj);
Serhiy Storchaka763a61c2016-04-10 18:05:12 +03002525 Py_SETREF(self->private_obj, private_obj);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002526 RETURN_NONE();
2527}
2528
Jesus Cea6557aac2010-03-22 14:22:26 +00002529#if (DBVER >= 46)
2530static PyObject*
2531DB_set_priority(DBObject* self, PyObject* args)
2532{
2533 int err, priority;
2534
2535 if (!PyArg_ParseTuple(args,"i:set_priority", &priority))
2536 return NULL;
2537 CHECK_DB_NOT_CLOSED(self);
2538
2539 MYDB_BEGIN_ALLOW_THREADS;
2540 err = self->db->set_priority(self->db, priority);
2541 MYDB_END_ALLOW_THREADS;
2542 RETURN_IF_ERR();
2543 RETURN_NONE();
2544}
2545
2546static PyObject*
2547DB_get_priority(DBObject* self)
2548{
2549 int err = 0;
2550 DB_CACHE_PRIORITY priority;
2551
2552 CHECK_DB_NOT_CLOSED(self);
2553
2554 MYDB_BEGIN_ALLOW_THREADS;
2555 err = self->db->get_priority(self->db, &priority);
2556 MYDB_END_ALLOW_THREADS;
2557 RETURN_IF_ERR();
2558 return NUMBER_FromLong(priority);
2559}
2560#endif
2561
2562static PyObject*
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07002563DB_get_dbname(DBObject* self)
2564{
2565 int err;
2566 const char *filename, *dbname;
2567
2568 CHECK_DB_NOT_CLOSED(self);
2569
2570 MYDB_BEGIN_ALLOW_THREADS;
2571 err = self->db->get_dbname(self->db, &filename, &dbname);
2572 MYDB_END_ALLOW_THREADS;
2573 RETURN_IF_ERR();
2574 /* If "dbname==NULL", it is correctly converted to "None" */
2575 return Py_BuildValue("(ss)", filename, dbname);
2576}
2577
2578static PyObject*
2579DB_get_open_flags(DBObject* self)
2580{
2581 int err;
2582 unsigned int flags;
2583
2584 CHECK_DB_NOT_CLOSED(self);
2585
2586 MYDB_BEGIN_ALLOW_THREADS;
2587 err = self->db->get_open_flags(self->db, &flags);
2588 MYDB_END_ALLOW_THREADS;
2589 RETURN_IF_ERR();
2590 return NUMBER_FromLong(flags);
2591}
2592
2593static PyObject*
Jesus Cea6557aac2010-03-22 14:22:26 +00002594DB_set_q_extentsize(DBObject* self, PyObject* args)
2595{
2596 int err;
2597 u_int32_t extentsize;
2598
2599 if (!PyArg_ParseTuple(args,"i:set_q_extentsize", &extentsize))
2600 return NULL;
2601 CHECK_DB_NOT_CLOSED(self);
2602
2603 MYDB_BEGIN_ALLOW_THREADS;
2604 err = self->db->set_q_extentsize(self->db, extentsize);
2605 MYDB_END_ALLOW_THREADS;
2606 RETURN_IF_ERR();
2607 RETURN_NONE();
2608}
2609
Jesus Cea6557aac2010-03-22 14:22:26 +00002610static PyObject*
2611DB_get_q_extentsize(DBObject* self)
2612{
2613 int err = 0;
2614 u_int32_t extentsize;
2615
2616 CHECK_DB_NOT_CLOSED(self);
2617
2618 MYDB_BEGIN_ALLOW_THREADS;
2619 err = self->db->get_q_extentsize(self->db, &extentsize);
2620 MYDB_END_ALLOW_THREADS;
2621 RETURN_IF_ERR();
2622 return NUMBER_FromLong(extentsize);
2623}
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002624
2625static PyObject*
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002626DB_set_bt_minkey(DBObject* self, PyObject* args)
2627{
2628 int err, minkey;
2629
Jesus Cea6557aac2010-03-22 14:22:26 +00002630 if (!PyArg_ParseTuple(args,"i:set_bt_minkey", &minkey))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002631 return NULL;
2632 CHECK_DB_NOT_CLOSED(self);
2633
2634 MYDB_BEGIN_ALLOW_THREADS;
2635 err = self->db->set_bt_minkey(self->db, minkey);
2636 MYDB_END_ALLOW_THREADS;
2637 RETURN_IF_ERR();
2638 RETURN_NONE();
2639}
2640
Jesus Cea6557aac2010-03-22 14:22:26 +00002641static PyObject*
2642DB_get_bt_minkey(DBObject* self)
2643{
2644 int err;
2645 u_int32_t bt_minkey;
2646
2647 CHECK_DB_NOT_CLOSED(self);
2648
2649 MYDB_BEGIN_ALLOW_THREADS;
2650 err = self->db->get_bt_minkey(self->db, &bt_minkey);
2651 MYDB_END_ALLOW_THREADS;
2652 RETURN_IF_ERR();
2653 return NUMBER_FromLong(bt_minkey);
2654}
Jesus Cea6557aac2010-03-22 14:22:26 +00002655
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002656static int
Georg Brandlef1701f2006-03-07 14:57:48 +00002657_default_cmp(const DBT *leftKey,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002658 const DBT *rightKey)
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002659{
2660 int res;
2661 int lsize = leftKey->size, rsize = rightKey->size;
2662
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002663 res = memcmp(leftKey->data, rightKey->data,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002664 lsize < rsize ? lsize : rsize);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002665
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002666 if (res == 0) {
2667 if (lsize < rsize) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002668 res = -1;
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002669 }
2670 else if (lsize > rsize) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002671 res = 1;
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002672 }
2673 }
2674 return res;
2675}
2676
2677static int
Jesus Ceaef9764f2008-05-13 18:45:46 +00002678_db_compareCallback(DB* db,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002679 const DBT *leftKey,
2680 const DBT *rightKey)
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002681{
2682 int res = 0;
2683 PyObject *args;
Thomas Woutersb2820ae2006-03-12 00:01:38 +00002684 PyObject *result = NULL;
Georg Brandlef1701f2006-03-07 14:57:48 +00002685 DBObject *self = (DBObject *)db->app_private;
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002686
2687 if (self == NULL || self->btCompareCallback == NULL) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002688 MYDB_BEGIN_BLOCK_THREADS;
2689 PyErr_SetString(PyExc_TypeError,
2690 (self == 0
2691 ? "DB_bt_compare db is NULL."
2692 : "DB_bt_compare callback is NULL."));
2693 /* we're in a callback within the DB code, we can't raise */
2694 PyErr_Print();
2695 res = _default_cmp(leftKey, rightKey);
2696 MYDB_END_BLOCK_THREADS;
Georg Brandlef1701f2006-03-07 14:57:48 +00002697 } else {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002698 MYDB_BEGIN_BLOCK_THREADS;
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002699
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002700 args = BuildValue_SS(leftKey->data, leftKey->size, rightKey->data, rightKey->size);
2701 if (args != NULL) {
2702 result = PyEval_CallObject(self->btCompareCallback, args);
2703 }
2704 if (args == NULL || result == NULL) {
2705 /* we're in a callback within the DB code, we can't raise */
2706 PyErr_Print();
2707 res = _default_cmp(leftKey, rightKey);
2708 } else if (NUMBER_Check(result)) {
2709 res = NUMBER_AsLong(result);
2710 } else {
2711 PyErr_SetString(PyExc_TypeError,
2712 "DB_bt_compare callback MUST return an int.");
2713 /* we're in a callback within the DB code, we can't raise */
2714 PyErr_Print();
2715 res = _default_cmp(leftKey, rightKey);
2716 }
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002717
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002718 Py_XDECREF(args);
2719 Py_XDECREF(result);
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002720
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002721 MYDB_END_BLOCK_THREADS;
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002722 }
2723 return res;
2724}
2725
2726static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002727DB_set_bt_compare(DBObject* self, PyObject* comparator)
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002728{
2729 int err;
Thomas Woutersb3153832006-03-08 01:47:19 +00002730 PyObject *tuple, *result;
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002731
Georg Brandlef1701f2006-03-07 14:57:48 +00002732 CHECK_DB_NOT_CLOSED(self);
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002733
Georg Brandlef1701f2006-03-07 14:57:48 +00002734 if (!PyCallable_Check(comparator)) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002735 makeTypeError("Callable", comparator);
2736 return NULL;
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002737 }
2738
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002739 /*
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002740 * Perform a test call of the comparator function with two empty
2741 * string objects here. verify that it returns an int (0).
2742 * err if not.
2743 */
Thomas Woutersb3153832006-03-08 01:47:19 +00002744 tuple = Py_BuildValue("(ss)", "", "");
Georg Brandlef1701f2006-03-07 14:57:48 +00002745 result = PyEval_CallObject(comparator, tuple);
2746 Py_DECREF(tuple);
Thomas Woutersb3153832006-03-08 01:47:19 +00002747 if (result == NULL)
2748 return NULL;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002749 if (!NUMBER_Check(result)) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002750 Py_DECREF(result);
2751 PyErr_SetString(PyExc_TypeError,
2752 "callback MUST return an int");
2753 return NULL;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002754 } else if (NUMBER_AsLong(result) != 0) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002755 Py_DECREF(result);
2756 PyErr_SetString(PyExc_TypeError,
2757 "callback failed to return 0 on two empty strings");
2758 return NULL;
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002759 }
Thomas Woutersb3153832006-03-08 01:47:19 +00002760 Py_DECREF(result);
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002761
2762 /* We don't accept multiple set_bt_compare operations, in order to
2763 * simplify the code. This would have no real use, as one cannot
2764 * change the function once the db is opened anyway */
2765 if (self->btCompareCallback != NULL) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002766 PyErr_SetString(PyExc_RuntimeError, "set_bt_compare() cannot be called more than once");
2767 return NULL;
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002768 }
2769
Georg Brandlef1701f2006-03-07 14:57:48 +00002770 Py_INCREF(comparator);
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002771 self->btCompareCallback = comparator;
2772
2773 /* This is to workaround a problem with un-initialized threads (see
2774 comment in DB_associate) */
2775#ifdef WITH_THREAD
2776 PyEval_InitThreads();
2777#endif
2778
Thomas Woutersb3153832006-03-08 01:47:19 +00002779 err = self->db->set_bt_compare(self->db, _db_compareCallback);
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002780
2781 if (err) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002782 /* restore the old state in case of error */
2783 Py_DECREF(comparator);
2784 self->btCompareCallback = NULL;
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002785 }
2786
Georg Brandlef1701f2006-03-07 14:57:48 +00002787 RETURN_IF_ERR();
2788 RETURN_NONE();
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002789}
2790
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07002791static int
2792_db_dupCompareCallback(DB* db,
2793 const DBT *leftKey,
2794 const DBT *rightKey)
2795{
2796 int res = 0;
2797 PyObject *args;
2798 PyObject *result = NULL;
2799 DBObject *self = (DBObject *)db->app_private;
2800
2801 if (self == NULL || self->dupCompareCallback == NULL) {
2802 MYDB_BEGIN_BLOCK_THREADS;
2803 PyErr_SetString(PyExc_TypeError,
2804 (self == 0
2805 ? "DB_dup_compare db is NULL."
2806 : "DB_dup_compare callback is NULL."));
2807 /* we're in a callback within the DB code, we can't raise */
2808 PyErr_Print();
2809 res = _default_cmp(leftKey, rightKey);
2810 MYDB_END_BLOCK_THREADS;
2811 } else {
2812 MYDB_BEGIN_BLOCK_THREADS;
2813
2814 args = BuildValue_SS(leftKey->data, leftKey->size, rightKey->data, rightKey->size);
2815 if (args != NULL) {
2816 result = PyEval_CallObject(self->dupCompareCallback, args);
2817 }
2818 if (args == NULL || result == NULL) {
2819 /* we're in a callback within the DB code, we can't raise */
2820 PyErr_Print();
2821 res = _default_cmp(leftKey, rightKey);
2822 } else if (NUMBER_Check(result)) {
2823 res = NUMBER_AsLong(result);
2824 } else {
2825 PyErr_SetString(PyExc_TypeError,
2826 "DB_dup_compare callback MUST return an int.");
2827 /* we're in a callback within the DB code, we can't raise */
2828 PyErr_Print();
2829 res = _default_cmp(leftKey, rightKey);
2830 }
2831
2832 Py_XDECREF(args);
2833 Py_XDECREF(result);
2834
2835 MYDB_END_BLOCK_THREADS;
2836 }
2837 return res;
2838}
2839
2840static PyObject*
2841DB_set_dup_compare(DBObject* self, PyObject* comparator)
2842{
2843 int err;
2844 PyObject *tuple, *result;
2845
2846 CHECK_DB_NOT_CLOSED(self);
2847
2848 if (!PyCallable_Check(comparator)) {
2849 makeTypeError("Callable", comparator);
2850 return NULL;
2851 }
2852
2853 /*
2854 * Perform a test call of the comparator function with two empty
2855 * string objects here. verify that it returns an int (0).
2856 * err if not.
2857 */
2858 tuple = Py_BuildValue("(ss)", "", "");
2859 result = PyEval_CallObject(comparator, tuple);
2860 Py_DECREF(tuple);
2861 if (result == NULL)
2862 return NULL;
2863 if (!NUMBER_Check(result)) {
2864 Py_DECREF(result);
2865 PyErr_SetString(PyExc_TypeError,
2866 "callback MUST return an int");
2867 return NULL;
2868 } else if (NUMBER_AsLong(result) != 0) {
2869 Py_DECREF(result);
2870 PyErr_SetString(PyExc_TypeError,
2871 "callback failed to return 0 on two empty strings");
2872 return NULL;
2873 }
2874 Py_DECREF(result);
2875
2876 /* We don't accept multiple set_dup_compare operations, in order to
2877 * simplify the code. This would have no real use, as one cannot
2878 * change the function once the db is opened anyway */
2879 if (self->dupCompareCallback != NULL) {
2880 PyErr_SetString(PyExc_RuntimeError, "set_dup_compare() cannot be called more than once");
2881 return NULL;
2882 }
2883
2884 Py_INCREF(comparator);
2885 self->dupCompareCallback = comparator;
2886
2887 /* This is to workaround a problem with un-initialized threads (see
2888 comment in DB_associate) */
2889#ifdef WITH_THREAD
2890 PyEval_InitThreads();
2891#endif
2892
2893 err = self->db->set_dup_compare(self->db, _db_dupCompareCallback);
2894
2895 if (err) {
2896 /* restore the old state in case of error */
2897 Py_DECREF(comparator);
2898 self->dupCompareCallback = NULL;
2899 }
2900
2901 RETURN_IF_ERR();
2902 RETURN_NONE();
2903}
2904
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002905
2906static PyObject*
2907DB_set_cachesize(DBObject* self, PyObject* args)
2908{
2909 int err;
2910 int gbytes = 0, bytes = 0, ncache = 0;
2911
2912 if (!PyArg_ParseTuple(args,"ii|i:set_cachesize",
2913 &gbytes,&bytes,&ncache))
2914 return NULL;
2915 CHECK_DB_NOT_CLOSED(self);
2916
2917 MYDB_BEGIN_ALLOW_THREADS;
2918 err = self->db->set_cachesize(self->db, gbytes, bytes, ncache);
2919 MYDB_END_ALLOW_THREADS;
2920 RETURN_IF_ERR();
2921 RETURN_NONE();
2922}
2923
Jesus Cea6557aac2010-03-22 14:22:26 +00002924static PyObject*
2925DB_get_cachesize(DBObject* self)
2926{
2927 int err;
2928 u_int32_t gbytes, bytes;
2929 int ncache;
2930
2931 CHECK_DB_NOT_CLOSED(self);
2932
2933 MYDB_BEGIN_ALLOW_THREADS;
2934 err = self->db->get_cachesize(self->db, &gbytes, &bytes, &ncache);
2935 MYDB_END_ALLOW_THREADS;
2936
2937 RETURN_IF_ERR();
2938
2939 return Py_BuildValue("(iii)", gbytes, bytes, ncache);
2940}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002941
2942static PyObject*
2943DB_set_flags(DBObject* self, PyObject* args)
2944{
2945 int err, flags;
2946
2947 if (!PyArg_ParseTuple(args,"i:set_flags", &flags))
2948 return NULL;
2949 CHECK_DB_NOT_CLOSED(self);
2950
2951 MYDB_BEGIN_ALLOW_THREADS;
2952 err = self->db->set_flags(self->db, flags);
2953 MYDB_END_ALLOW_THREADS;
2954 RETURN_IF_ERR();
2955
2956 self->setflags |= flags;
2957 RETURN_NONE();
2958}
2959
Jesus Cea6557aac2010-03-22 14:22:26 +00002960static PyObject*
2961DB_get_flags(DBObject* self)
2962{
2963 int err;
2964 u_int32_t flags;
2965
2966 CHECK_DB_NOT_CLOSED(self);
2967
2968 MYDB_BEGIN_ALLOW_THREADS;
2969 err = self->db->get_flags(self->db, &flags);
2970 MYDB_END_ALLOW_THREADS;
2971 RETURN_IF_ERR();
2972 return NUMBER_FromLong(flags);
2973}
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07002974
2975static PyObject*
2976DB_get_transactional(DBObject* self)
2977{
2978 int err;
2979
2980 CHECK_DB_NOT_CLOSED(self);
2981
2982 MYDB_BEGIN_ALLOW_THREADS;
2983 err = self->db->get_transactional(self->db);
2984 MYDB_END_ALLOW_THREADS;
2985
2986 if(err == 0) {
2987 Py_INCREF(Py_False);
2988 return Py_False;
2989 } else if(err == 1) {
2990 Py_INCREF(Py_True);
2991 return Py_True;
2992 }
2993
2994 /*
2995 ** If we reach there, there was an error. The
2996 ** "return" should be unreachable.
2997 */
2998 RETURN_IF_ERR();
2999 assert(0); /* This code SHOULD be unreachable */
3000 return NULL;
3001}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003002
3003static PyObject*
3004DB_set_h_ffactor(DBObject* self, PyObject* args)
3005{
3006 int err, ffactor;
3007
3008 if (!PyArg_ParseTuple(args,"i:set_h_ffactor", &ffactor))
3009 return NULL;
3010 CHECK_DB_NOT_CLOSED(self);
3011
3012 MYDB_BEGIN_ALLOW_THREADS;
3013 err = self->db->set_h_ffactor(self->db, ffactor);
3014 MYDB_END_ALLOW_THREADS;
3015 RETURN_IF_ERR();
3016 RETURN_NONE();
3017}
3018
Jesus Cea6557aac2010-03-22 14:22:26 +00003019static PyObject*
3020DB_get_h_ffactor(DBObject* self)
3021{
3022 int err;
3023 u_int32_t ffactor;
3024
3025 CHECK_DB_NOT_CLOSED(self);
3026
3027 MYDB_BEGIN_ALLOW_THREADS;
3028 err = self->db->get_h_ffactor(self->db, &ffactor);
3029 MYDB_END_ALLOW_THREADS;
3030 RETURN_IF_ERR();
3031 return NUMBER_FromLong(ffactor);
3032}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003033
3034static PyObject*
3035DB_set_h_nelem(DBObject* self, PyObject* args)
3036{
3037 int err, nelem;
3038
3039 if (!PyArg_ParseTuple(args,"i:set_h_nelem", &nelem))
3040 return NULL;
3041 CHECK_DB_NOT_CLOSED(self);
3042
3043 MYDB_BEGIN_ALLOW_THREADS;
3044 err = self->db->set_h_nelem(self->db, nelem);
3045 MYDB_END_ALLOW_THREADS;
3046 RETURN_IF_ERR();
3047 RETURN_NONE();
3048}
3049
Jesus Cea6557aac2010-03-22 14:22:26 +00003050static PyObject*
3051DB_get_h_nelem(DBObject* self)
3052{
3053 int err;
3054 u_int32_t nelem;
3055
3056 CHECK_DB_NOT_CLOSED(self);
3057
3058 MYDB_BEGIN_ALLOW_THREADS;
3059 err = self->db->get_h_nelem(self->db, &nelem);
3060 MYDB_END_ALLOW_THREADS;
3061 RETURN_IF_ERR();
3062 return NUMBER_FromLong(nelem);
3063}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003064
3065static PyObject*
3066DB_set_lorder(DBObject* self, PyObject* args)
3067{
3068 int err, lorder;
3069
3070 if (!PyArg_ParseTuple(args,"i:set_lorder", &lorder))
3071 return NULL;
3072 CHECK_DB_NOT_CLOSED(self);
3073
3074 MYDB_BEGIN_ALLOW_THREADS;
3075 err = self->db->set_lorder(self->db, lorder);
3076 MYDB_END_ALLOW_THREADS;
3077 RETURN_IF_ERR();
3078 RETURN_NONE();
3079}
3080
Jesus Cea6557aac2010-03-22 14:22:26 +00003081static PyObject*
3082DB_get_lorder(DBObject* self)
3083{
3084 int err;
3085 int lorder;
3086
3087 CHECK_DB_NOT_CLOSED(self);
3088
3089 MYDB_BEGIN_ALLOW_THREADS;
3090 err = self->db->get_lorder(self->db, &lorder);
3091 MYDB_END_ALLOW_THREADS;
3092 RETURN_IF_ERR();
3093 return NUMBER_FromLong(lorder);
3094}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003095
3096static PyObject*
3097DB_set_pagesize(DBObject* self, PyObject* args)
3098{
3099 int err, pagesize;
3100
3101 if (!PyArg_ParseTuple(args,"i:set_pagesize", &pagesize))
3102 return NULL;
3103 CHECK_DB_NOT_CLOSED(self);
3104
3105 MYDB_BEGIN_ALLOW_THREADS;
3106 err = self->db->set_pagesize(self->db, pagesize);
3107 MYDB_END_ALLOW_THREADS;
3108 RETURN_IF_ERR();
3109 RETURN_NONE();
3110}
3111
Jesus Cea6557aac2010-03-22 14:22:26 +00003112static PyObject*
3113DB_get_pagesize(DBObject* self)
3114{
3115 int err;
3116 u_int32_t pagesize;
3117
3118 CHECK_DB_NOT_CLOSED(self);
3119
3120 MYDB_BEGIN_ALLOW_THREADS;
3121 err = self->db->get_pagesize(self->db, &pagesize);
3122 MYDB_END_ALLOW_THREADS;
3123 RETURN_IF_ERR();
3124 return NUMBER_FromLong(pagesize);
3125}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003126
3127static PyObject*
3128DB_set_re_delim(DBObject* self, PyObject* args)
3129{
3130 int err;
3131 char delim;
3132
3133 if (!PyArg_ParseTuple(args,"b:set_re_delim", &delim)) {
3134 PyErr_Clear();
3135 if (!PyArg_ParseTuple(args,"c:set_re_delim", &delim))
3136 return NULL;
3137 }
3138
3139 CHECK_DB_NOT_CLOSED(self);
3140
3141 MYDB_BEGIN_ALLOW_THREADS;
3142 err = self->db->set_re_delim(self->db, delim);
3143 MYDB_END_ALLOW_THREADS;
3144 RETURN_IF_ERR();
3145 RETURN_NONE();
3146}
3147
Jesus Cea6557aac2010-03-22 14:22:26 +00003148static PyObject*
3149DB_get_re_delim(DBObject* self)
3150{
3151 int err, re_delim;
3152
3153 CHECK_DB_NOT_CLOSED(self);
3154
3155 MYDB_BEGIN_ALLOW_THREADS;
3156 err = self->db->get_re_delim(self->db, &re_delim);
3157 MYDB_END_ALLOW_THREADS;
3158 RETURN_IF_ERR();
3159 return NUMBER_FromLong(re_delim);
3160}
Jesus Cea6557aac2010-03-22 14:22:26 +00003161
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003162static PyObject*
3163DB_set_re_len(DBObject* self, PyObject* args)
3164{
3165 int err, len;
3166
3167 if (!PyArg_ParseTuple(args,"i:set_re_len", &len))
3168 return NULL;
3169 CHECK_DB_NOT_CLOSED(self);
3170
3171 MYDB_BEGIN_ALLOW_THREADS;
3172 err = self->db->set_re_len(self->db, len);
3173 MYDB_END_ALLOW_THREADS;
3174 RETURN_IF_ERR();
3175 RETURN_NONE();
3176}
3177
Jesus Cea6557aac2010-03-22 14:22:26 +00003178static PyObject*
3179DB_get_re_len(DBObject* self)
3180{
3181 int err;
3182 u_int32_t re_len;
3183
3184 CHECK_DB_NOT_CLOSED(self);
3185
3186 MYDB_BEGIN_ALLOW_THREADS;
3187 err = self->db->get_re_len(self->db, &re_len);
3188 MYDB_END_ALLOW_THREADS;
3189 RETURN_IF_ERR();
3190 return NUMBER_FromLong(re_len);
3191}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003192
3193static PyObject*
3194DB_set_re_pad(DBObject* self, PyObject* args)
3195{
3196 int err;
3197 char pad;
3198
3199 if (!PyArg_ParseTuple(args,"b:set_re_pad", &pad)) {
3200 PyErr_Clear();
3201 if (!PyArg_ParseTuple(args,"c:set_re_pad", &pad))
3202 return NULL;
3203 }
3204 CHECK_DB_NOT_CLOSED(self);
3205
3206 MYDB_BEGIN_ALLOW_THREADS;
3207 err = self->db->set_re_pad(self->db, pad);
3208 MYDB_END_ALLOW_THREADS;
3209 RETURN_IF_ERR();
3210 RETURN_NONE();
3211}
3212
Jesus Cea6557aac2010-03-22 14:22:26 +00003213static PyObject*
3214DB_get_re_pad(DBObject* self)
3215{
3216 int err, re_pad;
3217
3218 CHECK_DB_NOT_CLOSED(self);
3219
3220 MYDB_BEGIN_ALLOW_THREADS;
3221 err = self->db->get_re_pad(self->db, &re_pad);
3222 MYDB_END_ALLOW_THREADS;
3223 RETURN_IF_ERR();
3224 return NUMBER_FromLong(re_pad);
3225}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003226
3227static PyObject*
3228DB_set_re_source(DBObject* self, PyObject* args)
3229{
3230 int err;
Jesus Cea6557aac2010-03-22 14:22:26 +00003231 char *source;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003232
Jesus Cea6557aac2010-03-22 14:22:26 +00003233 if (!PyArg_ParseTuple(args,"s:set_re_source", &source))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003234 return NULL;
3235 CHECK_DB_NOT_CLOSED(self);
3236
3237 MYDB_BEGIN_ALLOW_THREADS;
Jesus Cea6557aac2010-03-22 14:22:26 +00003238 err = self->db->set_re_source(self->db, source);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003239 MYDB_END_ALLOW_THREADS;
3240 RETURN_IF_ERR();
3241 RETURN_NONE();
3242}
3243
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003244static PyObject*
Jesus Cea6557aac2010-03-22 14:22:26 +00003245DB_get_re_source(DBObject* self)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003246{
3247 int err;
Jesus Cea6557aac2010-03-22 14:22:26 +00003248 const char *source;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003249
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003250 CHECK_DB_NOT_CLOSED(self);
3251
3252 MYDB_BEGIN_ALLOW_THREADS;
Jesus Cea6557aac2010-03-22 14:22:26 +00003253 err = self->db->get_re_source(self->db, &source);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003254 MYDB_END_ALLOW_THREADS;
3255 RETURN_IF_ERR();
Jesus Cea6557aac2010-03-22 14:22:26 +00003256 return PyBytes_FromString(source);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003257}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003258
3259static PyObject*
Gregory P. Smith8b7e9172004-12-13 09:51:23 +00003260DB_stat(DBObject* self, PyObject* args, PyObject* kwargs)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003261{
3262 int err, flags = 0, type;
3263 void* sp;
3264 PyObject* d;
Gregory P. Smith8b7e9172004-12-13 09:51:23 +00003265 PyObject* txnobj = NULL;
3266 DB_TXN *txn = NULL;
Gregory P. Smith2fa06792006-09-19 17:35:04 +00003267 static char* kwnames[] = { "flags", "txn", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003268
Gregory P. Smith8b7e9172004-12-13 09:51:23 +00003269 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|iO:stat", kwnames,
3270 &flags, &txnobj))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003271 return NULL;
Gregory P. Smith8b7e9172004-12-13 09:51:23 +00003272 if (!checkTxnObj(txnobj, &txn))
3273 return NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003274 CHECK_DB_NOT_CLOSED(self);
3275
3276 MYDB_BEGIN_ALLOW_THREADS;
Gregory P. Smith8b7e9172004-12-13 09:51:23 +00003277 err = self->db->stat(self->db, txn, &sp, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003278 MYDB_END_ALLOW_THREADS;
3279 RETURN_IF_ERR();
3280
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003281 /* Turn the stat structure into a dictionary */
3282 type = _DB_get_type(self);
3283 if ((type == -1) || ((d = PyDict_New()) == NULL)) {
3284 free(sp);
3285 return NULL;
3286 }
3287
3288#define MAKE_HASH_ENTRY(name) _addIntToDict(d, #name, ((DB_HASH_STAT*)sp)->hash_##name)
3289#define MAKE_BT_ENTRY(name) _addIntToDict(d, #name, ((DB_BTREE_STAT*)sp)->bt_##name)
3290#define MAKE_QUEUE_ENTRY(name) _addIntToDict(d, #name, ((DB_QUEUE_STAT*)sp)->qs_##name)
3291
3292 switch (type) {
3293 case DB_HASH:
3294 MAKE_HASH_ENTRY(magic);
3295 MAKE_HASH_ENTRY(version);
3296 MAKE_HASH_ENTRY(nkeys);
3297 MAKE_HASH_ENTRY(ndata);
Jesus Ceaef9764f2008-05-13 18:45:46 +00003298#if (DBVER >= 46)
3299 MAKE_HASH_ENTRY(pagecnt);
3300#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003301 MAKE_HASH_ENTRY(pagesize);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003302 MAKE_HASH_ENTRY(ffactor);
3303 MAKE_HASH_ENTRY(buckets);
3304 MAKE_HASH_ENTRY(free);
3305 MAKE_HASH_ENTRY(bfree);
3306 MAKE_HASH_ENTRY(bigpages);
3307 MAKE_HASH_ENTRY(big_bfree);
3308 MAKE_HASH_ENTRY(overflows);
3309 MAKE_HASH_ENTRY(ovfl_free);
3310 MAKE_HASH_ENTRY(dup);
3311 MAKE_HASH_ENTRY(dup_free);
3312 break;
3313
3314 case DB_BTREE:
3315 case DB_RECNO:
3316 MAKE_BT_ENTRY(magic);
3317 MAKE_BT_ENTRY(version);
3318 MAKE_BT_ENTRY(nkeys);
3319 MAKE_BT_ENTRY(ndata);
Jesus Ceaef9764f2008-05-13 18:45:46 +00003320#if (DBVER >= 46)
3321 MAKE_BT_ENTRY(pagecnt);
3322#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003323 MAKE_BT_ENTRY(pagesize);
3324 MAKE_BT_ENTRY(minkey);
3325 MAKE_BT_ENTRY(re_len);
3326 MAKE_BT_ENTRY(re_pad);
3327 MAKE_BT_ENTRY(levels);
3328 MAKE_BT_ENTRY(int_pg);
3329 MAKE_BT_ENTRY(leaf_pg);
3330 MAKE_BT_ENTRY(dup_pg);
3331 MAKE_BT_ENTRY(over_pg);
Jesus Ceaef9764f2008-05-13 18:45:46 +00003332 MAKE_BT_ENTRY(empty_pg);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003333 MAKE_BT_ENTRY(free);
3334 MAKE_BT_ENTRY(int_pgfree);
3335 MAKE_BT_ENTRY(leaf_pgfree);
3336 MAKE_BT_ENTRY(dup_pgfree);
3337 MAKE_BT_ENTRY(over_pgfree);
3338 break;
3339
3340 case DB_QUEUE:
3341 MAKE_QUEUE_ENTRY(magic);
3342 MAKE_QUEUE_ENTRY(version);
3343 MAKE_QUEUE_ENTRY(nkeys);
3344 MAKE_QUEUE_ENTRY(ndata);
3345 MAKE_QUEUE_ENTRY(pagesize);
Jesus Ceaef9764f2008-05-13 18:45:46 +00003346 MAKE_QUEUE_ENTRY(extentsize);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003347 MAKE_QUEUE_ENTRY(pages);
3348 MAKE_QUEUE_ENTRY(re_len);
3349 MAKE_QUEUE_ENTRY(re_pad);
3350 MAKE_QUEUE_ENTRY(pgfree);
3351#if (DBVER == 31)
3352 MAKE_QUEUE_ENTRY(start);
3353#endif
3354 MAKE_QUEUE_ENTRY(first_recno);
3355 MAKE_QUEUE_ENTRY(cur_recno);
3356 break;
3357
3358 default:
3359 PyErr_SetString(PyExc_TypeError, "Unknown DB type, unable to stat");
3360 Py_DECREF(d);
3361 d = NULL;
3362 }
3363
3364#undef MAKE_HASH_ENTRY
3365#undef MAKE_BT_ENTRY
3366#undef MAKE_QUEUE_ENTRY
3367
3368 free(sp);
3369 return d;
3370}
3371
Jesus Cea6557aac2010-03-22 14:22:26 +00003372static PyObject*
3373DB_stat_print(DBObject* self, PyObject* args, PyObject *kwargs)
3374{
3375 int err;
3376 int flags=0;
3377 static char* kwnames[] = { "flags", NULL };
3378
3379 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:stat_print",
3380 kwnames, &flags))
3381 {
3382 return NULL;
3383 }
3384 CHECK_DB_NOT_CLOSED(self);
3385 MYDB_BEGIN_ALLOW_THREADS;
3386 err = self->db->stat_print(self->db, flags);
3387 MYDB_END_ALLOW_THREADS;
3388 RETURN_IF_ERR();
3389 RETURN_NONE();
3390}
Jesus Cea6557aac2010-03-22 14:22:26 +00003391
3392
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003393static PyObject*
3394DB_sync(DBObject* self, PyObject* args)
3395{
3396 int err;
3397 int flags = 0;
3398
3399 if (!PyArg_ParseTuple(args,"|i:sync", &flags ))
3400 return NULL;
3401 CHECK_DB_NOT_CLOSED(self);
3402
3403 MYDB_BEGIN_ALLOW_THREADS;
3404 err = self->db->sync(self->db, flags);
3405 MYDB_END_ALLOW_THREADS;
3406 RETURN_IF_ERR();
3407 RETURN_NONE();
3408}
3409
3410
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003411static PyObject*
3412DB_truncate(DBObject* self, PyObject* args, PyObject* kwargs)
3413{
3414 int err, flags=0;
3415 u_int32_t count=0;
3416 PyObject* txnobj = NULL;
3417 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003418 static char* kwnames[] = { "txn", "flags", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003419
3420 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Oi:cursor", kwnames,
3421 &txnobj, &flags))
3422 return NULL;
3423 CHECK_DB_NOT_CLOSED(self);
3424 if (!checkTxnObj(txnobj, &txn))
3425 return NULL;
3426
3427 MYDB_BEGIN_ALLOW_THREADS;
3428 err = self->db->truncate(self->db, txn, &count, flags);
3429 MYDB_END_ALLOW_THREADS;
3430 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00003431 return NUMBER_FromLong(count);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003432}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003433
3434
3435static PyObject*
3436DB_upgrade(DBObject* self, PyObject* args)
3437{
3438 int err, flags=0;
3439 char *filename;
3440
3441 if (!PyArg_ParseTuple(args,"s|i:upgrade", &filename, &flags))
3442 return NULL;
3443 CHECK_DB_NOT_CLOSED(self);
3444
3445 MYDB_BEGIN_ALLOW_THREADS;
3446 err = self->db->upgrade(self->db, filename, flags);
3447 MYDB_END_ALLOW_THREADS;
3448 RETURN_IF_ERR();
3449 RETURN_NONE();
3450}
3451
3452
3453static PyObject*
3454DB_verify(DBObject* self, PyObject* args, PyObject* kwargs)
3455{
3456 int err, flags=0;
3457 char* fileName;
3458 char* dbName=NULL;
3459 char* outFileName=NULL;
3460 FILE* outFile=NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003461 static char* kwnames[] = { "filename", "dbname", "outfile", "flags",
Jeremy Hyltonaf68c872005-12-10 18:50:16 +00003462 NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003463
3464 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|zzi:verify", kwnames,
3465 &fileName, &dbName, &outFileName, &flags))
3466 return NULL;
3467
3468 CHECK_DB_NOT_CLOSED(self);
3469 if (outFileName)
3470 outFile = fopen(outFileName, "w");
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003471 /* XXX(nnorwitz): it should probably be an exception if outFile
3472 can't be opened. */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003473
Jesus Ceaef9764f2008-05-13 18:45:46 +00003474 { /* DB.verify acts as a DB handle destructor (like close) */
3475 PyObject *error;
3476
Jesus Cea5cd5f122008-09-23 18:54:08 +00003477 error=DB_close_internal(self, 0, 1);
Jesus Cea6557aac2010-03-22 14:22:26 +00003478 if (error) {
Serhiy Storchakaaffac002015-07-24 08:05:45 +03003479 if (outFile)
3480 fclose(outFile);
3481 return error;
Jesus Ceaef9764f2008-05-13 18:45:46 +00003482 }
Serhiy Storchakaaffac002015-07-24 08:05:45 +03003483 }
Gregory P. Smith41631e82003-09-21 00:08:14 +00003484
Jesus Cea5cd5f122008-09-23 18:54:08 +00003485 MYDB_BEGIN_ALLOW_THREADS;
3486 err = self->db->verify(self->db, fileName, dbName, outFile, flags);
3487 MYDB_END_ALLOW_THREADS;
3488
3489 self->db = NULL; /* Implicit close; related objects already released */
3490
3491 if (outFile)
3492 fclose(outFile);
3493
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003494 RETURN_IF_ERR();
3495 RETURN_NONE();
3496}
3497
3498
3499static PyObject*
3500DB_set_get_returns_none(DBObject* self, PyObject* args)
3501{
3502 int flags=0;
Gregory P. Smith455d46f2003-07-09 04:45:59 +00003503 int oldValue=0;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003504
3505 if (!PyArg_ParseTuple(args,"i:set_get_returns_none", &flags))
3506 return NULL;
3507 CHECK_DB_NOT_CLOSED(self);
3508
Gregory P. Smith455d46f2003-07-09 04:45:59 +00003509 if (self->moduleFlags.getReturnsNone)
3510 ++oldValue;
3511 if (self->moduleFlags.cursorSetReturnsNone)
3512 ++oldValue;
3513 self->moduleFlags.getReturnsNone = (flags >= 1);
3514 self->moduleFlags.cursorSetReturnsNone = (flags >= 2);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00003515 return NUMBER_FromLong(oldValue);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003516}
3517
Barry Warsaw9a0d7792002-12-30 20:53:52 +00003518static PyObject*
3519DB_set_encrypt(DBObject* self, PyObject* args, PyObject* kwargs)
3520{
3521 int err;
3522 u_int32_t flags=0;
3523 char *passwd = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003524 static char* kwnames[] = { "passwd", "flags", NULL };
Barry Warsaw9a0d7792002-12-30 20:53:52 +00003525
3526 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|i:set_encrypt", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003527 &passwd, &flags)) {
3528 return NULL;
Barry Warsaw9a0d7792002-12-30 20:53:52 +00003529 }
3530
3531 MYDB_BEGIN_ALLOW_THREADS;
3532 err = self->db->set_encrypt(self->db, passwd, flags);
3533 MYDB_END_ALLOW_THREADS;
3534
3535 RETURN_IF_ERR();
3536 RETURN_NONE();
3537}
Jesus Cea6557aac2010-03-22 14:22:26 +00003538
Jesus Cea6557aac2010-03-22 14:22:26 +00003539static PyObject*
3540DB_get_encrypt_flags(DBObject* self)
3541{
3542 int err;
3543 u_int32_t flags;
3544
3545 MYDB_BEGIN_ALLOW_THREADS;
3546 err = self->db->get_encrypt_flags(self->db, &flags);
3547 MYDB_END_ALLOW_THREADS;
3548
3549 RETURN_IF_ERR();
3550
3551 return NUMBER_FromLong(flags);
3552}
Jesus Cea6557aac2010-03-22 14:22:26 +00003553
Barry Warsaw9a0d7792002-12-30 20:53:52 +00003554
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003555
3556/*-------------------------------------------------------------- */
3557/* Mapping and Dictionary-like access routines */
3558
Martin v. Löwis70ee3cc2006-06-12 04:26:31 +00003559Py_ssize_t DB_length(PyObject* _self)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003560{
3561 int err;
Gregory P. Smith3c228b12006-06-05 23:59:37 +00003562 Py_ssize_t size = 0;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003563 void* sp;
Martin v. Löwis70ee3cc2006-06-12 04:26:31 +00003564 DBObject* self = (DBObject*)_self;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003565
3566 if (self->db == NULL) {
Thomas Woutersb3153832006-03-08 01:47:19 +00003567 PyObject *t = Py_BuildValue("(is)", 0, "DB object has been closed");
Jesus Ceac5a11fa2008-07-23 11:38:42 +00003568 if (t) {
3569 PyErr_SetObject(DBError, t);
3570 Py_DECREF(t);
3571 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003572 return -1;
3573 }
3574
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003575 MYDB_BEGIN_ALLOW_THREADS;
Jesus Cea6557aac2010-03-22 14:22:26 +00003576 err = self->db->stat(self->db, /*txnid*/ NULL, &sp, 0);
Jesus Cea6557aac2010-03-22 14:22:26 +00003577 MYDB_END_ALLOW_THREADS;
Gregory P. Smith3c228b12006-06-05 23:59:37 +00003578
3579 /* All the stat structures have matching fields upto the ndata field,
3580 so we can use any of them for the type cast */
3581 size = ((DB_BTREE_STAT*)sp)->bt_ndata;
3582
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003583 if (err)
3584 return -1;
3585
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003586 free(sp);
3587 return size;
3588}
3589
3590
3591PyObject* DB_subscript(DBObject* self, PyObject* keyobj)
3592{
3593 int err;
3594 PyObject* retval;
3595 DBT key;
3596 DBT data;
3597
3598 CHECK_DB_NOT_CLOSED(self);
3599 if (!make_key_dbt(self, keyobj, &key, NULL))
3600 return NULL;
3601
3602 CLEAR_DBT(data);
3603 if (CHECK_DBFLAG(self, DB_THREAD)) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00003604 /* Tell Berkeley DB to malloc the return value (thread safe) */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003605 data.flags = DB_DBT_MALLOC;
3606 }
3607 MYDB_BEGIN_ALLOW_THREADS;
3608 err = self->db->get(self->db, NULL, &key, &data, 0);
3609 MYDB_END_ALLOW_THREADS;
3610 if (err == DB_NOTFOUND || err == DB_KEYEMPTY) {
3611 PyErr_SetObject(PyExc_KeyError, keyobj);
3612 retval = NULL;
3613 }
3614 else if (makeDBError(err)) {
3615 retval = NULL;
3616 }
3617 else {
Jesus Ceaef9764f2008-05-13 18:45:46 +00003618 retval = Build_PyString(data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003619 FREE_DBT(data);
3620 }
3621
3622 FREE_DBT(key);
3623 return retval;
3624}
3625
3626
3627static int
3628DB_ass_sub(DBObject* self, PyObject* keyobj, PyObject* dataobj)
3629{
3630 DBT key, data;
3631 int retval;
3632 int flags = 0;
3633
3634 if (self->db == NULL) {
Thomas Woutersb3153832006-03-08 01:47:19 +00003635 PyObject *t = Py_BuildValue("(is)", 0, "DB object has been closed");
Jesus Ceac5a11fa2008-07-23 11:38:42 +00003636 if (t) {
3637 PyErr_SetObject(DBError, t);
3638 Py_DECREF(t);
3639 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003640 return -1;
3641 }
3642
3643 if (!make_key_dbt(self, keyobj, &key, NULL))
3644 return -1;
3645
3646 if (dataobj != NULL) {
3647 if (!make_dbt(dataobj, &data))
3648 retval = -1;
3649 else {
3650 if (self->setflags & (DB_DUP|DB_DUPSORT))
Barry Warsaw9a0d7792002-12-30 20:53:52 +00003651 /* dictionaries shouldn't have duplicate keys */
3652 flags = DB_NOOVERWRITE;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003653 retval = _DB_put(self, NULL, &key, &data, flags);
3654
3655 if ((retval == -1) && (self->setflags & (DB_DUP|DB_DUPSORT))) {
Barry Warsaw9a0d7792002-12-30 20:53:52 +00003656 /* try deleting any old record that matches and then PUT it
3657 * again... */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003658 _DB_delete(self, NULL, &key, 0);
3659 PyErr_Clear();
3660 retval = _DB_put(self, NULL, &key, &data, flags);
3661 }
3662 }
3663 }
3664 else {
3665 /* dataobj == NULL, so delete the key */
3666 retval = _DB_delete(self, NULL, &key, 0);
3667 }
3668 FREE_DBT(key);
3669 return retval;
3670}
3671
3672
3673static PyObject*
Jesus Cea6557aac2010-03-22 14:22:26 +00003674_DB_has_key(DBObject* self, PyObject* keyobj, PyObject* txnobj)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003675{
3676 int err;
Jesus Cea6557aac2010-03-22 14:22:26 +00003677 DBT key;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003678 DB_TXN *txn = NULL;
Jesus Cea4907d272008-08-31 14:00:51 +00003679
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003680 CHECK_DB_NOT_CLOSED(self);
3681 if (!make_key_dbt(self, keyobj, &key, NULL))
3682 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00003683 if (!checkTxnObj(txnobj, &txn)) {
3684 FREE_DBT(key);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003685 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00003686 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003687
Jesus Cea6557aac2010-03-22 14:22:26 +00003688#if (DBVER < 46)
Gregory P. Smith8b7e9172004-12-13 09:51:23 +00003689 /* This causes DB_BUFFER_SMALL to be returned when the db has the key because
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003690 it has a record but can't allocate a buffer for the data. This saves
3691 having to deal with data we won't be using.
3692 */
Jesus Cea6557aac2010-03-22 14:22:26 +00003693 {
3694 DBT data ;
3695 CLEAR_DBT(data);
3696 data.flags = DB_DBT_USERMEM;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003697
Jesus Cea6557aac2010-03-22 14:22:26 +00003698 MYDB_BEGIN_ALLOW_THREADS;
3699 err = self->db->get(self->db, txn, &key, &data, 0);
3700 MYDB_END_ALLOW_THREADS;
3701 }
3702#else
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003703 MYDB_BEGIN_ALLOW_THREADS;
Jesus Cea6557aac2010-03-22 14:22:26 +00003704 err = self->db->exists(self->db, txn, &key, 0);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003705 MYDB_END_ALLOW_THREADS;
Jesus Cea6557aac2010-03-22 14:22:26 +00003706#endif
3707
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003708 FREE_DBT(key);
Gregory P. Smithe9477062005-06-04 06:46:59 +00003709
Jesus Cea6557aac2010-03-22 14:22:26 +00003710 /*
3711 ** DB_BUFFER_SMALL is only used if we use "get".
3712 ** We can drop it when we only use "exists",
Martin Panter8d496ad2016-06-02 10:35:44 +00003713 ** when we drop support for Berkeley DB < 4.6.
Jesus Cea6557aac2010-03-22 14:22:26 +00003714 */
Gregory P. Smithe9477062005-06-04 06:46:59 +00003715 if (err == DB_BUFFER_SMALL || err == 0) {
Jesus Cea6557aac2010-03-22 14:22:26 +00003716 Py_INCREF(Py_True);
3717 return Py_True;
Gregory P. Smithe9477062005-06-04 06:46:59 +00003718 } else if (err == DB_NOTFOUND || err == DB_KEYEMPTY) {
Jesus Cea6557aac2010-03-22 14:22:26 +00003719 Py_INCREF(Py_False);
3720 return Py_False;
Gregory P. Smithe9477062005-06-04 06:46:59 +00003721 }
3722
3723 makeDBError(err);
3724 return NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003725}
3726
Jesus Cea6557aac2010-03-22 14:22:26 +00003727static PyObject*
3728DB_has_key(DBObject* self, PyObject* args, PyObject* kwargs)
3729{
3730 PyObject* keyobj;
3731 PyObject* txnobj = NULL;
3732 static char* kwnames[] = {"key","txn", NULL};
3733
3734 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O:has_key", kwnames,
3735 &keyobj, &txnobj))
3736 return NULL;
3737
3738 return _DB_has_key(self, keyobj, txnobj);
3739}
3740
3741
3742static int DB_contains(DBObject* self, PyObject* keyobj)
3743{
3744 PyObject* result;
3745 int result2 = 0;
3746
3747 result = _DB_has_key(self, keyobj, NULL) ;
3748 if (result == NULL) {
3749 return -1; /* Propague exception */
3750 }
3751 if (result != Py_False) {
3752 result2 = 1;
3753 }
3754
3755 Py_DECREF(result);
3756 return result2;
3757}
3758
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003759
3760#define _KEYS_LIST 1
3761#define _VALUES_LIST 2
3762#define _ITEMS_LIST 3
3763
3764static PyObject*
3765_DB_make_list(DBObject* self, DB_TXN* txn, int type)
3766{
3767 int err, dbtype;
3768 DBT key;
3769 DBT data;
3770 DBC *cursor;
3771 PyObject* list;
3772 PyObject* item = NULL;
3773
3774 CHECK_DB_NOT_CLOSED(self);
3775 CLEAR_DBT(key);
3776 CLEAR_DBT(data);
3777
3778 dbtype = _DB_get_type(self);
3779 if (dbtype == -1)
3780 return NULL;
3781
3782 list = PyList_New(0);
Thomas Woutersb3153832006-03-08 01:47:19 +00003783 if (list == NULL)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003784 return NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003785
3786 /* get a cursor */
3787 MYDB_BEGIN_ALLOW_THREADS;
Gregory P. Smith442c9fc2004-09-04 01:36:59 +00003788 err = self->db->cursor(self->db, txn, &cursor, 0);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003789 MYDB_END_ALLOW_THREADS;
Thomas Woutersb3153832006-03-08 01:47:19 +00003790 if (makeDBError(err)) {
3791 Py_DECREF(list);
3792 return NULL;
3793 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003794
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003795 while (1) { /* use the cursor to traverse the DB, collecting items */
3796 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00003797 err = _DBC_get(cursor, &key, &data, DB_NEXT);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003798 MYDB_END_ALLOW_THREADS;
3799
3800 if (err) {
3801 /* for any error, break out of the loop */
3802 break;
3803 }
3804
3805 switch (type) {
3806 case _KEYS_LIST:
3807 switch(dbtype) {
3808 case DB_BTREE:
3809 case DB_HASH:
3810 default:
Jesus Ceaef9764f2008-05-13 18:45:46 +00003811 item = Build_PyString(key.data, key.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003812 break;
3813 case DB_RECNO:
3814 case DB_QUEUE:
Jesus Ceac5a11fa2008-07-23 11:38:42 +00003815 item = NUMBER_FromLong(*((db_recno_t*)key.data));
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003816 break;
3817 }
3818 break;
3819
3820 case _VALUES_LIST:
Jesus Ceaef9764f2008-05-13 18:45:46 +00003821 item = Build_PyString(data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003822 break;
3823
3824 case _ITEMS_LIST:
3825 switch(dbtype) {
3826 case DB_BTREE:
3827 case DB_HASH:
3828 default:
Jesus Ceaef9764f2008-05-13 18:45:46 +00003829 item = BuildValue_SS(key.data, key.size, data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003830 break;
3831 case DB_RECNO:
3832 case DB_QUEUE:
Jesus Ceaef9764f2008-05-13 18:45:46 +00003833 item = BuildValue_IS(*((db_recno_t*)key.data), data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003834 break;
3835 }
3836 break;
Thomas Woutersb3153832006-03-08 01:47:19 +00003837 default:
3838 PyErr_Format(PyExc_ValueError, "Unknown key type 0x%x", type);
3839 item = NULL;
3840 break;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003841 }
3842 if (item == NULL) {
3843 Py_DECREF(list);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003844 list = NULL;
3845 goto done;
3846 }
Jesus Ceac5a11fa2008-07-23 11:38:42 +00003847 if (PyList_Append(list, item)) {
3848 Py_DECREF(list);
3849 Py_DECREF(item);
3850 list = NULL;
3851 goto done;
3852 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003853 Py_DECREF(item);
3854 }
3855
Gregory P. Smithe9477062005-06-04 06:46:59 +00003856 /* DB_NOTFOUND || DB_KEYEMPTY is okay, it means we got to the end */
3857 if (err != DB_NOTFOUND && err != DB_KEYEMPTY && makeDBError(err)) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003858 Py_DECREF(list);
3859 list = NULL;
3860 }
3861
3862 done:
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003863 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00003864 _DBC_close(cursor);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003865 MYDB_END_ALLOW_THREADS;
3866 return list;
3867}
3868
3869
3870static PyObject*
3871DB_keys(DBObject* self, PyObject* args)
3872{
3873 PyObject* txnobj = NULL;
3874 DB_TXN *txn = NULL;
3875
Georg Brandl96a8c392006-05-29 21:04:52 +00003876 if (!PyArg_UnpackTuple(args, "keys", 0, 1, &txnobj))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003877 return NULL;
3878 if (!checkTxnObj(txnobj, &txn))
3879 return NULL;
3880 return _DB_make_list(self, txn, _KEYS_LIST);
3881}
3882
3883
3884static PyObject*
3885DB_items(DBObject* self, PyObject* args)
3886{
3887 PyObject* txnobj = NULL;
3888 DB_TXN *txn = NULL;
3889
Georg Brandl96a8c392006-05-29 21:04:52 +00003890 if (!PyArg_UnpackTuple(args, "items", 0, 1, &txnobj))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003891 return NULL;
3892 if (!checkTxnObj(txnobj, &txn))
3893 return NULL;
3894 return _DB_make_list(self, txn, _ITEMS_LIST);
3895}
3896
3897
3898static PyObject*
3899DB_values(DBObject* self, PyObject* args)
3900{
3901 PyObject* txnobj = NULL;
3902 DB_TXN *txn = NULL;
3903
Georg Brandl96a8c392006-05-29 21:04:52 +00003904 if (!PyArg_UnpackTuple(args, "values", 0, 1, &txnobj))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003905 return NULL;
3906 if (!checkTxnObj(txnobj, &txn))
3907 return NULL;
3908 return _DB_make_list(self, txn, _VALUES_LIST);
3909}
3910
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003911/* --------------------------------------------------------------------- */
Jesus Cea6557aac2010-03-22 14:22:26 +00003912/* DBLogCursor methods */
3913
3914
3915static PyObject*
3916DBLogCursor_close_internal(DBLogCursorObject* self)
3917{
3918 int err = 0;
3919
3920 if (self->logc != NULL) {
3921 EXTRACT_FROM_DOUBLE_LINKED_LIST(self);
3922
3923 MYDB_BEGIN_ALLOW_THREADS;
3924 err = self->logc->close(self->logc, 0);
3925 MYDB_END_ALLOW_THREADS;
3926 self->logc = NULL;
3927 }
3928 RETURN_IF_ERR();
3929 RETURN_NONE();
3930}
3931
3932static PyObject*
3933DBLogCursor_close(DBLogCursorObject* self)
3934{
3935 return DBLogCursor_close_internal(self);
3936}
3937
3938
3939static PyObject*
3940_DBLogCursor_get(DBLogCursorObject* self, int flag, DB_LSN *lsn2)
3941{
3942 int err;
3943 DBT data;
3944 DB_LSN lsn = {0, 0};
3945 PyObject *dummy, *retval;
3946
3947 CLEAR_DBT(data);
3948 data.flags = DB_DBT_MALLOC; /* Berkeley DB must do the malloc */
3949
3950 CHECK_LOGCURSOR_NOT_CLOSED(self);
3951
3952 if (lsn2)
3953 lsn = *lsn2;
3954
3955 MYDB_BEGIN_ALLOW_THREADS;
3956 err = self->logc->get(self->logc, &lsn, &data, flag);
3957 MYDB_END_ALLOW_THREADS;
3958
3959 if (err == DB_NOTFOUND) {
3960 Py_INCREF(Py_None);
3961 retval = Py_None;
3962 }
3963 else if (makeDBError(err)) {
3964 retval = NULL;
3965 }
3966 else {
3967 retval = dummy = BuildValue_S(data.data, data.size);
3968 if (dummy) {
3969 retval = Py_BuildValue("(ii)O", lsn.file, lsn.offset, dummy);
3970 Py_DECREF(dummy);
3971 }
3972 }
3973
3974 FREE_DBT(data);
3975 return retval;
3976}
3977
3978static PyObject*
3979DBLogCursor_current(DBLogCursorObject* self)
3980{
3981 return _DBLogCursor_get(self, DB_CURRENT, NULL);
3982}
3983
3984static PyObject*
3985DBLogCursor_first(DBLogCursorObject* self)
3986{
3987 return _DBLogCursor_get(self, DB_FIRST, NULL);
3988}
3989
3990static PyObject*
3991DBLogCursor_last(DBLogCursorObject* self)
3992{
3993 return _DBLogCursor_get(self, DB_LAST, NULL);
3994}
3995
3996static PyObject*
3997DBLogCursor_next(DBLogCursorObject* self)
3998{
3999 return _DBLogCursor_get(self, DB_NEXT, NULL);
4000}
4001
4002static PyObject*
4003DBLogCursor_prev(DBLogCursorObject* self)
4004{
4005 return _DBLogCursor_get(self, DB_PREV, NULL);
4006}
4007
4008static PyObject*
4009DBLogCursor_set(DBLogCursorObject* self, PyObject* args)
4010{
4011 DB_LSN lsn;
4012
4013 if (!PyArg_ParseTuple(args, "(ii):set", &lsn.file, &lsn.offset))
4014 return NULL;
4015
4016 return _DBLogCursor_get(self, DB_SET, &lsn);
4017}
4018
4019
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07004020/* --------------------------------------------------------------------- */
4021/* DBSite methods */
4022
4023
4024#if (DBVER >= 52)
4025static PyObject*
4026DBSite_close_internal(DBSiteObject* self)
4027{
4028 int err = 0;
4029
4030 if (self->site != NULL) {
4031 EXTRACT_FROM_DOUBLE_LINKED_LIST(self);
4032
4033 MYDB_BEGIN_ALLOW_THREADS;
4034 err = self->site->close(self->site);
4035 MYDB_END_ALLOW_THREADS;
4036 self->site = NULL;
4037 }
4038 RETURN_IF_ERR();
4039 RETURN_NONE();
4040}
4041
4042static PyObject*
4043DBSite_close(DBSiteObject* self)
4044{
4045 return DBSite_close_internal(self);
4046}
4047
4048static PyObject*
4049DBSite_remove(DBSiteObject* self)
4050{
4051 int err = 0;
4052
4053 CHECK_SITE_NOT_CLOSED(self);
4054
4055 MYDB_BEGIN_ALLOW_THREADS;
4056 err = self->site->remove(self->site);
4057 MYDB_END_ALLOW_THREADS;
4058
4059 RETURN_IF_ERR();
4060 RETURN_NONE();
4061}
4062
4063static PyObject*
4064DBSite_get_eid(DBSiteObject* self)
4065{
4066 int err = 0;
4067 int eid;
4068
4069 CHECK_SITE_NOT_CLOSED(self);
4070
4071 MYDB_BEGIN_ALLOW_THREADS;
4072 err = self->site->get_eid(self->site, &eid);
4073 MYDB_END_ALLOW_THREADS;
4074
4075 RETURN_IF_ERR();
4076 return NUMBER_FromLong(eid);
4077}
4078
4079static PyObject*
4080DBSite_get_address(DBSiteObject* self)
4081{
4082 int err = 0;
4083 const char *host;
4084 u_int port;
4085
4086 CHECK_SITE_NOT_CLOSED(self);
4087
4088 MYDB_BEGIN_ALLOW_THREADS;
4089 err = self->site->get_address(self->site, &host, &port);
4090 MYDB_END_ALLOW_THREADS;
4091
4092 RETURN_IF_ERR();
4093
4094 return Py_BuildValue("(sI)", host, port);
4095}
4096
4097static PyObject*
4098DBSite_get_config(DBSiteObject* self, PyObject* args, PyObject* kwargs)
4099{
4100 int err = 0;
4101 u_int32_t which, value;
4102 static char* kwnames[] = { "which", NULL };
4103
4104 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i:get_config", kwnames,
4105 &which))
4106 return NULL;
4107
4108 CHECK_SITE_NOT_CLOSED(self);
4109
4110 MYDB_BEGIN_ALLOW_THREADS;
4111 err = self->site->get_config(self->site, which, &value);
4112 MYDB_END_ALLOW_THREADS;
4113
4114 RETURN_IF_ERR();
4115
4116 if (value) {
4117 Py_INCREF(Py_True);
4118 return Py_True;
4119 } else {
4120 Py_INCREF(Py_False);
4121 return Py_False;
4122 }
4123}
4124
4125static PyObject*
4126DBSite_set_config(DBSiteObject* self, PyObject* args, PyObject* kwargs)
4127{
4128 int err = 0;
4129 u_int32_t which, value;
4130 PyObject *valueO;
4131 static char* kwnames[] = { "which", "value", NULL };
4132
4133 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "iO:set_config", kwnames,
4134 &which, &valueO))
4135 return NULL;
4136
4137 CHECK_SITE_NOT_CLOSED(self);
4138
4139 value = PyObject_IsTrue(valueO);
4140
4141 MYDB_BEGIN_ALLOW_THREADS;
4142 err = self->site->set_config(self->site, which, value);
4143 MYDB_END_ALLOW_THREADS;
4144
4145 RETURN_IF_ERR();
4146 RETURN_NONE();
4147}
4148#endif
4149
Jesus Cea6557aac2010-03-22 14:22:26 +00004150
4151/* --------------------------------------------------------------------- */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004152/* DBCursor methods */
4153
4154
4155static PyObject*
Jesus Ceaef9764f2008-05-13 18:45:46 +00004156DBC_close_internal(DBCursorObject* self)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004157{
4158 int err = 0;
4159
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004160 if (self->dbc != NULL) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00004161 EXTRACT_FROM_DOUBLE_LINKED_LIST(self);
4162 if (self->txn) {
4163 EXTRACT_FROM_DOUBLE_LINKED_LIST_TXN(self);
4164 self->txn=NULL;
4165 }
4166
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004167 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004168 err = _DBC_close(self->dbc);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004169 MYDB_END_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004170 self->dbc = NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004171 }
4172 RETURN_IF_ERR();
4173 RETURN_NONE();
4174}
4175
Jesus Ceaef9764f2008-05-13 18:45:46 +00004176static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00004177DBC_close(DBCursorObject* self)
Jesus Ceaef9764f2008-05-13 18:45:46 +00004178{
Jesus Ceaef9764f2008-05-13 18:45:46 +00004179 return DBC_close_internal(self);
4180}
4181
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004182
4183static PyObject*
4184DBC_count(DBCursorObject* self, PyObject* args)
4185{
4186 int err = 0;
4187 db_recno_t count;
4188 int flags = 0;
4189
4190 if (!PyArg_ParseTuple(args, "|i:count", &flags))
4191 return NULL;
4192
4193 CHECK_CURSOR_NOT_CLOSED(self);
4194
4195 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004196 err = _DBC_count(self->dbc, &count, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004197 MYDB_END_ALLOW_THREADS;
4198 RETURN_IF_ERR();
4199
Jesus Ceac5a11fa2008-07-23 11:38:42 +00004200 return NUMBER_FromLong(count);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004201}
4202
4203
4204static PyObject*
4205DBC_current(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4206{
4207 return _DBCursor_get(self,DB_CURRENT,args,kwargs,"|iii:current");
4208}
4209
4210
4211static PyObject*
4212DBC_delete(DBCursorObject* self, PyObject* args)
4213{
4214 int err, flags=0;
4215
4216 if (!PyArg_ParseTuple(args, "|i:delete", &flags))
4217 return NULL;
4218
4219 CHECK_CURSOR_NOT_CLOSED(self);
4220
4221 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004222 err = _DBC_del(self->dbc, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004223 MYDB_END_ALLOW_THREADS;
4224 RETURN_IF_ERR();
4225
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004226 RETURN_NONE();
4227}
4228
4229
4230static PyObject*
4231DBC_dup(DBCursorObject* self, PyObject* args)
4232{
4233 int err, flags =0;
4234 DBC* dbc = NULL;
4235
4236 if (!PyArg_ParseTuple(args, "|i:dup", &flags))
4237 return NULL;
4238
4239 CHECK_CURSOR_NOT_CLOSED(self);
4240
4241 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004242 err = _DBC_dup(self->dbc, &dbc, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004243 MYDB_END_ALLOW_THREADS;
4244 RETURN_IF_ERR();
4245
Jesus Ceaef9764f2008-05-13 18:45:46 +00004246 return (PyObject*) newDBCursorObject(dbc, self->txn, self->mydb);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004247}
4248
4249static PyObject*
4250DBC_first(DBCursorObject* self, PyObject* args, PyObject* kwargs)
4251{
4252 return _DBCursor_get(self,DB_FIRST,args,kwargs,"|iii:first");
4253}
4254
4255
4256static PyObject*
4257DBC_get(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4258{
Martin v. Löwisb2c7aff2002-11-23 11:26:07 +00004259 int err, flags=0;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004260 PyObject* keyobj = NULL;
4261 PyObject* dataobj = NULL;
4262 PyObject* retval = NULL;
4263 int dlen = -1;
4264 int doff = -1;
4265 DBT key, data;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00004266 static char* kwnames[] = { "key","data", "flags", "dlen", "doff",
Jeremy Hyltonaf68c872005-12-10 18:50:16 +00004267 NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004268
4269 CLEAR_DBT(key);
4270 CLEAR_DBT(data);
4271 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|ii:get", &kwnames[2],
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004272 &flags, &dlen, &doff))
Barry Warsaw9a0d7792002-12-30 20:53:52 +00004273 {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004274 PyErr_Clear();
Barry Warsaw9a0d7792002-12-30 20:53:52 +00004275 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Oi|ii:get",
Jesus Cea4907d272008-08-31 14:00:51 +00004276 &kwnames[1],
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004277 &keyobj, &flags, &dlen, &doff))
Barry Warsaw9a0d7792002-12-30 20:53:52 +00004278 {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004279 PyErr_Clear();
Barry Warsaw9a0d7792002-12-30 20:53:52 +00004280 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OOi|ii:get",
4281 kwnames, &keyobj, &dataobj,
4282 &flags, &dlen, &doff))
4283 {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004284 return NULL;
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004285 }
4286 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004287 }
4288
4289 CHECK_CURSOR_NOT_CLOSED(self);
4290
4291 if (keyobj && !make_key_dbt(self->mydb, keyobj, &key, NULL))
4292 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004293 if ( (dataobj && !make_dbt(dataobj, &data)) ||
4294 (!add_partial_dbt(&data, dlen, doff)) )
4295 {
Jesus Ceaef9764f2008-05-13 18:45:46 +00004296 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004297 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004298 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004299
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004300 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004301 err = _DBC_get(self->dbc, &key, &data, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004302 MYDB_END_ALLOW_THREADS;
4303
Gregory P. Smithe9477062005-06-04 06:46:59 +00004304 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004305 && self->mydb->moduleFlags.getReturnsNone) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004306 Py_INCREF(Py_None);
4307 retval = Py_None;
4308 }
4309 else if (makeDBError(err)) {
4310 retval = NULL;
4311 }
4312 else {
4313 switch (_DB_get_type(self->mydb)) {
4314 case -1:
4315 retval = NULL;
4316 break;
4317 case DB_BTREE:
4318 case DB_HASH:
4319 default:
Jesus Ceaef9764f2008-05-13 18:45:46 +00004320 retval = BuildValue_SS(key.data, key.size, data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004321 break;
4322 case DB_RECNO:
4323 case DB_QUEUE:
Jesus Ceaef9764f2008-05-13 18:45:46 +00004324 retval = BuildValue_IS(*((db_recno_t*)key.data), data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004325 break;
4326 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004327 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00004328 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004329 return retval;
4330}
4331
Gregory P. Smith19699a92004-06-28 04:06:49 +00004332static PyObject*
4333DBC_pget(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4334{
4335 int err, flags=0;
4336 PyObject* keyobj = NULL;
4337 PyObject* dataobj = NULL;
4338 PyObject* retval = NULL;
4339 int dlen = -1;
4340 int doff = -1;
4341 DBT key, pkey, data;
Gregory P. Smith372b5832006-06-05 18:48:21 +00004342 static char* kwnames_keyOnly[] = { "key", "flags", "dlen", "doff", NULL };
4343 static char* kwnames[] = { "key", "data", "flags", "dlen", "doff", NULL };
Gregory P. Smith19699a92004-06-28 04:06:49 +00004344
4345 CLEAR_DBT(key);
4346 CLEAR_DBT(data);
4347 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|ii:pget", &kwnames[2],
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004348 &flags, &dlen, &doff))
Gregory P. Smith19699a92004-06-28 04:06:49 +00004349 {
4350 PyErr_Clear();
4351 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Oi|ii:pget",
Jesus Cea6557aac2010-03-22 14:22:26 +00004352 kwnames_keyOnly,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004353 &keyobj, &flags, &dlen, &doff))
Gregory P. Smith19699a92004-06-28 04:06:49 +00004354 {
4355 PyErr_Clear();
4356 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OOi|ii:pget",
4357 kwnames, &keyobj, &dataobj,
4358 &flags, &dlen, &doff))
4359 {
4360 return NULL;
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004361 }
4362 }
Gregory P. Smith19699a92004-06-28 04:06:49 +00004363 }
4364
4365 CHECK_CURSOR_NOT_CLOSED(self);
4366
4367 if (keyobj && !make_key_dbt(self->mydb, keyobj, &key, NULL))
4368 return NULL;
4369 if ( (dataobj && !make_dbt(dataobj, &data)) ||
4370 (!add_partial_dbt(&data, dlen, doff)) ) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00004371 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Gregory P. Smith19699a92004-06-28 04:06:49 +00004372 return NULL;
4373 }
4374
Gregory P. Smith19699a92004-06-28 04:06:49 +00004375 CLEAR_DBT(pkey);
4376 pkey.flags = DB_DBT_MALLOC;
4377
4378 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004379 err = _DBC_pget(self->dbc, &key, &pkey, &data, flags);
Gregory P. Smith19699a92004-06-28 04:06:49 +00004380 MYDB_END_ALLOW_THREADS;
4381
Gregory P. Smithe9477062005-06-04 06:46:59 +00004382 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004383 && self->mydb->moduleFlags.getReturnsNone) {
Gregory P. Smith19699a92004-06-28 04:06:49 +00004384 Py_INCREF(Py_None);
4385 retval = Py_None;
4386 }
4387 else if (makeDBError(err)) {
4388 retval = NULL;
4389 }
4390 else {
4391 PyObject *pkeyObj;
4392 PyObject *dataObj;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004393 dataObj = Build_PyString(data.data, data.size);
Gregory P. Smith19699a92004-06-28 04:06:49 +00004394
4395 if (self->mydb->primaryDBType == DB_RECNO ||
4396 self->mydb->primaryDBType == DB_QUEUE)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00004397 pkeyObj = NUMBER_FromLong(*(int *)pkey.data);
Gregory P. Smith19699a92004-06-28 04:06:49 +00004398 else
Jesus Ceaef9764f2008-05-13 18:45:46 +00004399 pkeyObj = Build_PyString(pkey.data, pkey.size);
Gregory P. Smith19699a92004-06-28 04:06:49 +00004400
Gregory P. Smith4e414d82006-01-24 19:55:02 +00004401 if (key.data && key.size) /* return key, pkey and data */
Gregory P. Smith19699a92004-06-28 04:06:49 +00004402 {
4403 PyObject *keyObj;
4404 int type = _DB_get_type(self->mydb);
4405 if (type == DB_RECNO || type == DB_QUEUE)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00004406 keyObj = NUMBER_FromLong(*(int *)key.data);
Gregory P. Smith19699a92004-06-28 04:06:49 +00004407 else
Jesus Ceaef9764f2008-05-13 18:45:46 +00004408 keyObj = Build_PyString(key.data, key.size);
Gregory P. Smith4e414d82006-01-24 19:55:02 +00004409 retval = PyTuple_Pack(3, keyObj, pkeyObj, dataObj);
Thomas Woutersb3153832006-03-08 01:47:19 +00004410 Py_DECREF(keyObj);
Jesus Ceaef9764f2008-05-13 18:45:46 +00004411 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Gregory P. Smith19699a92004-06-28 04:06:49 +00004412 }
4413 else /* return just the pkey and data */
4414 {
Gregory P. Smith4e414d82006-01-24 19:55:02 +00004415 retval = PyTuple_Pack(2, pkeyObj, dataObj);
Gregory P. Smith19699a92004-06-28 04:06:49 +00004416 }
Thomas Woutersb3153832006-03-08 01:47:19 +00004417 Py_DECREF(dataObj);
4418 Py_DECREF(pkeyObj);
Gregory P. Smith19699a92004-06-28 04:06:49 +00004419 FREE_DBT(pkey);
Gregory P. Smith19699a92004-06-28 04:06:49 +00004420 }
4421 /* the only time REALLOC should be set is if we used an integer
4422 * key that make_key_dbt malloc'd for us. always free these. */
Jesus Ceaef9764f2008-05-13 18:45:46 +00004423 if (key.flags & DB_DBT_REALLOC) { /* 'make_key_dbt' could do a 'malloc' */
Gregory P. Smith19699a92004-06-28 04:06:49 +00004424 FREE_DBT(key);
4425 }
4426 return retval;
4427}
4428
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004429
4430static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00004431DBC_get_recno(DBCursorObject* self)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004432{
4433 int err;
4434 db_recno_t recno;
4435 DBT key;
4436 DBT data;
4437
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004438 CHECK_CURSOR_NOT_CLOSED(self);
4439
4440 CLEAR_DBT(key);
4441 CLEAR_DBT(data);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004442
4443 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004444 err = _DBC_get(self->dbc, &key, &data, DB_GET_RECNO);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004445 MYDB_END_ALLOW_THREADS;
4446 RETURN_IF_ERR();
4447
4448 recno = *((db_recno_t*)data.data);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00004449 return NUMBER_FromLong(recno);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004450}
4451
4452
4453static PyObject*
4454DBC_last(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4455{
4456 return _DBCursor_get(self,DB_LAST,args,kwargs,"|iii:last");
4457}
4458
4459
4460static PyObject*
4461DBC_next(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4462{
4463 return _DBCursor_get(self,DB_NEXT,args,kwargs,"|iii:next");
4464}
4465
4466
4467static PyObject*
4468DBC_prev(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4469{
4470 return _DBCursor_get(self,DB_PREV,args,kwargs,"|iii:prev");
4471}
4472
4473
4474static PyObject*
4475DBC_put(DBCursorObject* self, PyObject* args, PyObject* kwargs)
4476{
4477 int err, flags = 0;
4478 PyObject* keyobj, *dataobj;
4479 DBT key, data;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00004480 static char* kwnames[] = { "key", "data", "flags", "dlen", "doff",
Jeremy Hyltonaf68c872005-12-10 18:50:16 +00004481 NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004482 int dlen = -1;
4483 int doff = -1;
4484
4485 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|iii:put", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004486 &keyobj, &dataobj, &flags, &dlen, &doff))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004487 return NULL;
4488
4489 CHECK_CURSOR_NOT_CLOSED(self);
4490
4491 if (!make_key_dbt(self->mydb, keyobj, &key, NULL))
4492 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004493 if (!make_dbt(dataobj, &data) ||
4494 !add_partial_dbt(&data, dlen, doff) )
4495 {
Jesus Ceaef9764f2008-05-13 18:45:46 +00004496 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004497 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004498 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004499
4500 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004501 err = _DBC_put(self->dbc, &key, &data, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004502 MYDB_END_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004503 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004504 RETURN_IF_ERR();
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004505 RETURN_NONE();
4506}
4507
4508
4509static PyObject*
4510DBC_set(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4511{
4512 int err, flags = 0;
4513 DBT key, data;
4514 PyObject* retval, *keyobj;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00004515 static char* kwnames[] = { "key", "flags", "dlen", "doff", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004516 int dlen = -1;
4517 int doff = -1;
4518
4519 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|iii:set", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004520 &keyobj, &flags, &dlen, &doff))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004521 return NULL;
4522
4523 CHECK_CURSOR_NOT_CLOSED(self);
4524
4525 if (!make_key_dbt(self->mydb, keyobj, &key, NULL))
4526 return NULL;
4527
4528 CLEAR_DBT(data);
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004529 if (!add_partial_dbt(&data, dlen, doff)) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00004530 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004531 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004532 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004533
4534 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004535 err = _DBC_get(self->dbc, &key, &data, flags|DB_SET);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004536 MYDB_END_ALLOW_THREADS;
Gregory P. Smithe9477062005-06-04 06:46:59 +00004537 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004538 && self->mydb->moduleFlags.cursorSetReturnsNone) {
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004539 Py_INCREF(Py_None);
4540 retval = Py_None;
4541 }
4542 else if (makeDBError(err)) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004543 retval = NULL;
4544 }
4545 else {
4546 switch (_DB_get_type(self->mydb)) {
4547 case -1:
4548 retval = NULL;
4549 break;
4550 case DB_BTREE:
4551 case DB_HASH:
4552 default:
Jesus Ceaef9764f2008-05-13 18:45:46 +00004553 retval = BuildValue_SS(key.data, key.size, data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004554 break;
4555 case DB_RECNO:
4556 case DB_QUEUE:
Jesus Ceaef9764f2008-05-13 18:45:46 +00004557 retval = BuildValue_IS(*((db_recno_t*)key.data), data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004558 break;
4559 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00004560 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004561 }
Gregory P. Smith19699a92004-06-28 04:06:49 +00004562 /* the only time REALLOC should be set is if we used an integer
4563 * key that make_key_dbt malloc'd for us. always free these. */
4564 if (key.flags & DB_DBT_REALLOC) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00004565 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Gregory P. Smith19699a92004-06-28 04:06:49 +00004566 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004567
4568 return retval;
4569}
4570
4571
4572static PyObject*
4573DBC_set_range(DBCursorObject* self, PyObject* args, PyObject* kwargs)
4574{
4575 int err, flags = 0;
4576 DBT key, data;
4577 PyObject* retval, *keyobj;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00004578 static char* kwnames[] = { "key", "flags", "dlen", "doff", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004579 int dlen = -1;
4580 int doff = -1;
4581
4582 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|iii:set_range", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004583 &keyobj, &flags, &dlen, &doff))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004584 return NULL;
4585
4586 CHECK_CURSOR_NOT_CLOSED(self);
4587
4588 if (!make_key_dbt(self->mydb, keyobj, &key, NULL))
4589 return NULL;
4590
4591 CLEAR_DBT(data);
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004592 if (!add_partial_dbt(&data, dlen, doff)) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00004593 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004594 return NULL;
4595 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004596 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004597 err = _DBC_get(self->dbc, &key, &data, flags|DB_SET_RANGE);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004598 MYDB_END_ALLOW_THREADS;
Gregory P. Smithe9477062005-06-04 06:46:59 +00004599 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004600 && self->mydb->moduleFlags.cursorSetReturnsNone) {
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004601 Py_INCREF(Py_None);
4602 retval = Py_None;
4603 }
4604 else if (makeDBError(err)) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004605 retval = NULL;
4606 }
4607 else {
4608 switch (_DB_get_type(self->mydb)) {
4609 case -1:
4610 retval = NULL;
4611 break;
4612 case DB_BTREE:
4613 case DB_HASH:
4614 default:
Jesus Ceaef9764f2008-05-13 18:45:46 +00004615 retval = BuildValue_SS(key.data, key.size, data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004616 break;
4617 case DB_RECNO:
4618 case DB_QUEUE:
Jesus Ceaef9764f2008-05-13 18:45:46 +00004619 retval = BuildValue_IS(*((db_recno_t*)key.data), data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004620 break;
4621 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00004622 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004623 }
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004624 /* the only time REALLOC should be set is if we used an integer
Gregory P. Smith19699a92004-06-28 04:06:49 +00004625 * key that make_key_dbt malloc'd for us. always free these. */
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004626 if (key.flags & DB_DBT_REALLOC) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00004627 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004628 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004629
4630 return retval;
4631}
4632
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004633static PyObject*
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004634_DBC_get_set_both(DBCursorObject* self, PyObject* keyobj, PyObject* dataobj,
4635 int flags, unsigned int returnsNone)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004636{
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004637 int err;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004638 DBT key, data;
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004639 PyObject* retval;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004640
Gregory P. Smith7441e652003-11-03 21:35:31 +00004641 /* the caller did this: CHECK_CURSOR_NOT_CLOSED(self); */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004642 if (!make_key_dbt(self->mydb, keyobj, &key, NULL))
4643 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004644 if (!make_dbt(dataobj, &data)) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00004645 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004646 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004647 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004648
4649 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004650 err = _DBC_get(self->dbc, &key, &data, flags|DB_GET_BOTH);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004651 MYDB_END_ALLOW_THREADS;
Gregory P. Smithe9477062005-06-04 06:46:59 +00004652 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY) && returnsNone) {
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004653 Py_INCREF(Py_None);
4654 retval = Py_None;
4655 }
4656 else if (makeDBError(err)) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004657 retval = NULL;
4658 }
4659 else {
4660 switch (_DB_get_type(self->mydb)) {
4661 case -1:
4662 retval = NULL;
4663 break;
4664 case DB_BTREE:
4665 case DB_HASH:
4666 default:
Jesus Ceaef9764f2008-05-13 18:45:46 +00004667 retval = BuildValue_SS(key.data, key.size, data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004668 break;
4669 case DB_RECNO:
4670 case DB_QUEUE:
Jesus Ceaef9764f2008-05-13 18:45:46 +00004671 retval = BuildValue_IS(*((db_recno_t*)key.data), data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004672 break;
4673 }
4674 }
4675
Jesus Ceaef9764f2008-05-13 18:45:46 +00004676 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004677 return retval;
4678}
4679
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004680static PyObject*
4681DBC_get_both(DBCursorObject* self, PyObject* args)
4682{
4683 int flags=0;
4684 PyObject *keyobj, *dataobj;
4685
4686 if (!PyArg_ParseTuple(args, "OO|i:get_both", &keyobj, &dataobj, &flags))
4687 return NULL;
4688
Gregory P. Smith7441e652003-11-03 21:35:31 +00004689 /* if the cursor is closed, self->mydb may be invalid */
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004690 CHECK_CURSOR_NOT_CLOSED(self);
4691
4692 return _DBC_get_set_both(self, keyobj, dataobj, flags,
4693 self->mydb->moduleFlags.getReturnsNone);
4694}
4695
Gregory P. Smithbe0db8b2003-10-01 06:48:51 +00004696/* Return size of entry */
4697static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00004698DBC_get_current_size(DBCursorObject* self)
Gregory P. Smithbe0db8b2003-10-01 06:48:51 +00004699{
4700 int err, flags=DB_CURRENT;
4701 PyObject* retval = NULL;
4702 DBT key, data;
4703
Gregory P. Smithbe0db8b2003-10-01 06:48:51 +00004704 CHECK_CURSOR_NOT_CLOSED(self);
4705 CLEAR_DBT(key);
4706 CLEAR_DBT(data);
4707
Gregory P. Smith8b7e9172004-12-13 09:51:23 +00004708 /* We don't allocate any memory, forcing a DB_BUFFER_SMALL error and thus
Gregory P. Smithbe0db8b2003-10-01 06:48:51 +00004709 getting the record size. */
4710 data.flags = DB_DBT_USERMEM;
4711 data.ulen = 0;
4712 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004713 err = _DBC_get(self->dbc, &key, &data, flags);
Gregory P. Smithbe0db8b2003-10-01 06:48:51 +00004714 MYDB_END_ALLOW_THREADS;
Gregory P. Smith8b7e9172004-12-13 09:51:23 +00004715 if (err == DB_BUFFER_SMALL || !err) {
4716 /* DB_BUFFER_SMALL means positive size, !err means zero length value */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00004717 retval = NUMBER_FromLong((long)data.size);
Gregory P. Smithbe0db8b2003-10-01 06:48:51 +00004718 err = 0;
4719 }
4720
Gregory P. Smithbe0db8b2003-10-01 06:48:51 +00004721 RETURN_IF_ERR();
4722 return retval;
4723}
4724
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004725static PyObject*
4726DBC_set_both(DBCursorObject* self, PyObject* args)
4727{
4728 int flags=0;
4729 PyObject *keyobj, *dataobj;
4730
4731 if (!PyArg_ParseTuple(args, "OO|i:set_both", &keyobj, &dataobj, &flags))
4732 return NULL;
4733
Gregory P. Smith7441e652003-11-03 21:35:31 +00004734 /* if the cursor is closed, self->mydb may be invalid */
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004735 CHECK_CURSOR_NOT_CLOSED(self);
4736
4737 return _DBC_get_set_both(self, keyobj, dataobj, flags,
4738 self->mydb->moduleFlags.cursorSetReturnsNone);
4739}
4740
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004741
4742static PyObject*
4743DBC_set_recno(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4744{
4745 int err, irecno, flags=0;
4746 db_recno_t recno;
4747 DBT key, data;
4748 PyObject* retval;
4749 int dlen = -1;
4750 int doff = -1;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00004751 static char* kwnames[] = { "recno","flags", "dlen", "doff", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004752
4753 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|iii:set_recno", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004754 &irecno, &flags, &dlen, &doff))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004755 return NULL;
4756
4757 CHECK_CURSOR_NOT_CLOSED(self);
4758
4759 CLEAR_DBT(key);
4760 recno = (db_recno_t) irecno;
Barry Warsaw9a0d7792002-12-30 20:53:52 +00004761 /* use allocated space so DB will be able to realloc room for the real
4762 * key */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004763 key.data = malloc(sizeof(db_recno_t));
4764 if (key.data == NULL) {
4765 PyErr_SetString(PyExc_MemoryError, "Key memory allocation failed");
4766 return NULL;
4767 }
4768 key.size = sizeof(db_recno_t);
4769 key.ulen = key.size;
4770 memcpy(key.data, &recno, sizeof(db_recno_t));
4771 key.flags = DB_DBT_REALLOC;
4772
4773 CLEAR_DBT(data);
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004774 if (!add_partial_dbt(&data, dlen, doff)) {
4775 FREE_DBT(key);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004776 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004777 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004778
4779 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004780 err = _DBC_get(self->dbc, &key, &data, flags|DB_SET_RECNO);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004781 MYDB_END_ALLOW_THREADS;
Gregory P. Smithe9477062005-06-04 06:46:59 +00004782 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004783 && self->mydb->moduleFlags.cursorSetReturnsNone) {
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004784 Py_INCREF(Py_None);
4785 retval = Py_None;
4786 }
4787 else if (makeDBError(err)) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004788 retval = NULL;
4789 }
4790 else { /* Can only be used for BTrees, so no need to return int key */
Jesus Ceaef9764f2008-05-13 18:45:46 +00004791 retval = BuildValue_SS(key.data, key.size, data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004792 }
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004793 FREE_DBT(key);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004794
4795 return retval;
4796}
4797
4798
4799static PyObject*
4800DBC_consume(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4801{
4802 return _DBCursor_get(self,DB_CONSUME,args,kwargs,"|iii:consume");
4803}
4804
4805
4806static PyObject*
4807DBC_next_dup(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4808{
4809 return _DBCursor_get(self,DB_NEXT_DUP,args,kwargs,"|iii:next_dup");
4810}
4811
4812
4813static PyObject*
4814DBC_next_nodup(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4815{
4816 return _DBCursor_get(self,DB_NEXT_NODUP,args,kwargs,"|iii:next_nodup");
4817}
4818
Jesus Cea6557aac2010-03-22 14:22:26 +00004819#if (DBVER >= 46)
4820static PyObject*
4821DBC_prev_dup(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4822{
4823 return _DBCursor_get(self,DB_PREV_DUP,args,kwargs,"|iii:prev_dup");
4824}
4825#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004826
4827static PyObject*
4828DBC_prev_nodup(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4829{
4830 return _DBCursor_get(self,DB_PREV_NODUP,args,kwargs,"|iii:prev_nodup");
4831}
4832
4833
4834static PyObject*
4835DBC_join_item(DBCursorObject* self, PyObject* args)
4836{
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004837 int err, flags=0;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004838 DBT key, data;
4839 PyObject* retval;
4840
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004841 if (!PyArg_ParseTuple(args, "|i:join_item", &flags))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004842 return NULL;
4843
4844 CHECK_CURSOR_NOT_CLOSED(self);
4845
4846 CLEAR_DBT(key);
4847 CLEAR_DBT(data);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004848
4849 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004850 err = _DBC_get(self->dbc, &key, &data, flags | DB_JOIN_ITEM);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004851 MYDB_END_ALLOW_THREADS;
Gregory P. Smithe9477062005-06-04 06:46:59 +00004852 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004853 && self->mydb->moduleFlags.getReturnsNone) {
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004854 Py_INCREF(Py_None);
4855 retval = Py_None;
4856 }
4857 else if (makeDBError(err)) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004858 retval = NULL;
4859 }
4860 else {
Jesus Ceaef9764f2008-05-13 18:45:46 +00004861 retval = BuildValue_S(key.data, key.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004862 }
4863
4864 return retval;
4865}
4866
4867
Jesus Cea6557aac2010-03-22 14:22:26 +00004868#if (DBVER >= 46)
4869static PyObject*
4870DBC_set_priority(DBCursorObject* self, PyObject* args, PyObject* kwargs)
4871{
4872 int err, priority;
4873 static char* kwnames[] = { "priority", NULL };
4874
4875 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i:set_priority", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004876 &priority))
Jesus Cea6557aac2010-03-22 14:22:26 +00004877 return NULL;
4878
4879 CHECK_CURSOR_NOT_CLOSED(self);
4880
4881 MYDB_BEGIN_ALLOW_THREADS;
4882 err = self->dbc->set_priority(self->dbc, priority);
4883 MYDB_END_ALLOW_THREADS;
4884 RETURN_IF_ERR();
4885 RETURN_NONE();
4886}
4887
4888
4889static PyObject*
4890DBC_get_priority(DBCursorObject* self)
4891{
4892 int err;
4893 DB_CACHE_PRIORITY priority;
4894
4895 CHECK_CURSOR_NOT_CLOSED(self);
4896
4897 MYDB_BEGIN_ALLOW_THREADS;
4898 err = self->dbc->get_priority(self->dbc, &priority);
4899 MYDB_END_ALLOW_THREADS;
4900 RETURN_IF_ERR();
4901 return NUMBER_FromLong(priority);
4902}
4903#endif
4904
4905
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004906
4907/* --------------------------------------------------------------------- */
4908/* DBEnv methods */
4909
4910
4911static PyObject*
Jesus Ceaef9764f2008-05-13 18:45:46 +00004912DBEnv_close_internal(DBEnvObject* self, int flags)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004913{
Jesus Ceaef9764f2008-05-13 18:45:46 +00004914 PyObject *dummy;
4915 int err;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004916
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004917 if (!self->closed) { /* Don't close more than once */
Jesus Ceaef9764f2008-05-13 18:45:46 +00004918 while(self->children_txns) {
Jesus Cea6557aac2010-03-22 14:22:26 +00004919 dummy = DBTxn_abort_discard_internal(self->children_txns, 0);
4920 Py_XDECREF(dummy);
Jesus Ceaef9764f2008-05-13 18:45:46 +00004921 }
4922 while(self->children_dbs) {
Jesus Cea6557aac2010-03-22 14:22:26 +00004923 dummy = DB_close_internal(self->children_dbs, 0, 0);
4924 Py_XDECREF(dummy);
4925 }
4926 while(self->children_logcursors) {
4927 dummy = DBLogCursor_close_internal(self->children_logcursors);
4928 Py_XDECREF(dummy);
Jesus Ceaef9764f2008-05-13 18:45:46 +00004929 }
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07004930#if (DBVER >= 52)
4931 while(self->children_sites) {
4932 dummy = DBSite_close_internal(self->children_sites);
4933 Py_XDECREF(dummy);
4934 }
4935#endif
Jesus Ceaac25fab2008-09-03 17:50:32 +00004936 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00004937
Jesus Ceaac25fab2008-09-03 17:50:32 +00004938 self->closed = 1;
4939 if (self->db_env) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004940 MYDB_BEGIN_ALLOW_THREADS;
4941 err = self->db_env->close(self->db_env, flags);
4942 MYDB_END_ALLOW_THREADS;
4943 /* after calling DBEnv->close, regardless of error, this DBEnv
Jesus Ceaef9764f2008-05-13 18:45:46 +00004944 * may not be accessed again (Berkeley DB docs). */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004945 self->db_env = NULL;
4946 RETURN_IF_ERR();
4947 }
4948 RETURN_NONE();
4949}
4950
Jesus Ceaef9764f2008-05-13 18:45:46 +00004951static PyObject*
4952DBEnv_close(DBEnvObject* self, PyObject* args)
4953{
4954 int flags = 0;
4955
4956 if (!PyArg_ParseTuple(args, "|i:close", &flags))
4957 return NULL;
Jesus Cea5cd5f122008-09-23 18:54:08 +00004958 return DBEnv_close_internal(self, flags);
Jesus Ceaef9764f2008-05-13 18:45:46 +00004959}
4960
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004961
4962static PyObject*
4963DBEnv_open(DBEnvObject* self, PyObject* args)
4964{
4965 int err, flags=0, mode=0660;
4966 char *db_home;
4967
4968 if (!PyArg_ParseTuple(args, "z|ii:open", &db_home, &flags, &mode))
4969 return NULL;
4970
4971 CHECK_ENV_NOT_CLOSED(self);
4972
4973 MYDB_BEGIN_ALLOW_THREADS;
4974 err = self->db_env->open(self->db_env, db_home, flags, mode);
4975 MYDB_END_ALLOW_THREADS;
4976 RETURN_IF_ERR();
4977 self->closed = 0;
4978 self->flags = flags;
4979 RETURN_NONE();
4980}
4981
4982
4983static PyObject*
Jesus Cea6557aac2010-03-22 14:22:26 +00004984DBEnv_memp_stat(DBEnvObject* self, PyObject* args, PyObject *kwargs)
4985{
4986 int err;
4987 DB_MPOOL_STAT *gsp;
4988 DB_MPOOL_FSTAT **fsp, **fsp2;
4989 PyObject* d = NULL, *d2, *d3, *r;
4990 u_int32_t flags = 0;
4991 static char* kwnames[] = { "flags", NULL };
4992
4993 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:memp_stat",
4994 kwnames, &flags))
4995 return NULL;
4996
4997 CHECK_ENV_NOT_CLOSED(self);
4998
4999 MYDB_BEGIN_ALLOW_THREADS;
5000 err = self->db_env->memp_stat(self->db_env, &gsp, &fsp, flags);
5001 MYDB_END_ALLOW_THREADS;
5002 RETURN_IF_ERR();
5003
5004 /* Turn the stat structure into a dictionary */
5005 d = PyDict_New();
5006 if (d == NULL) {
5007 if (gsp)
5008 free(gsp);
5009 return NULL;
5010 }
5011
5012#define MAKE_ENTRY(name) _addIntToDict(d, #name, gsp->st_##name)
5013
5014 MAKE_ENTRY(gbytes);
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07005015 MAKE_ENTRY(bytes);
Jesus Cea6557aac2010-03-22 14:22:26 +00005016 MAKE_ENTRY(ncache);
5017#if (DBVER >= 46)
5018 MAKE_ENTRY(max_ncache);
5019#endif
5020 MAKE_ENTRY(regsize);
Jesus Cea6557aac2010-03-22 14:22:26 +00005021 MAKE_ENTRY(mmapsize);
5022 MAKE_ENTRY(maxopenfd);
5023 MAKE_ENTRY(maxwrite);
5024 MAKE_ENTRY(maxwrite_sleep);
Jesus Cea6557aac2010-03-22 14:22:26 +00005025 MAKE_ENTRY(map);
5026 MAKE_ENTRY(cache_hit);
5027 MAKE_ENTRY(cache_miss);
5028 MAKE_ENTRY(page_create);
5029 MAKE_ENTRY(page_in);
5030 MAKE_ENTRY(page_out);
5031 MAKE_ENTRY(ro_evict);
5032 MAKE_ENTRY(rw_evict);
5033 MAKE_ENTRY(page_trickle);
5034 MAKE_ENTRY(pages);
5035 MAKE_ENTRY(page_clean);
5036 MAKE_ENTRY(page_dirty);
5037 MAKE_ENTRY(hash_buckets);
5038 MAKE_ENTRY(hash_searches);
5039 MAKE_ENTRY(hash_longest);
5040 MAKE_ENTRY(hash_examined);
5041 MAKE_ENTRY(hash_nowait);
5042 MAKE_ENTRY(hash_wait);
5043#if (DBVER >= 45)
5044 MAKE_ENTRY(hash_max_nowait);
5045#endif
5046 MAKE_ENTRY(hash_max_wait);
5047 MAKE_ENTRY(region_wait);
5048 MAKE_ENTRY(region_nowait);
5049#if (DBVER >= 45)
5050 MAKE_ENTRY(mvcc_frozen);
5051 MAKE_ENTRY(mvcc_thawed);
5052 MAKE_ENTRY(mvcc_freed);
5053#endif
5054 MAKE_ENTRY(alloc);
5055 MAKE_ENTRY(alloc_buckets);
5056 MAKE_ENTRY(alloc_max_buckets);
5057 MAKE_ENTRY(alloc_pages);
5058 MAKE_ENTRY(alloc_max_pages);
5059#if (DBVER >= 45)
5060 MAKE_ENTRY(io_wait);
5061#endif
5062#if (DBVER >= 48)
5063 MAKE_ENTRY(sync_interrupted);
5064#endif
5065
5066#undef MAKE_ENTRY
5067 free(gsp);
5068
5069 d2 = PyDict_New();
5070 if (d2 == NULL) {
5071 Py_DECREF(d);
5072 if (fsp)
5073 free(fsp);
5074 return NULL;
5075 }
5076#define MAKE_ENTRY(name) _addIntToDict(d3, #name, (*fsp2)->st_##name)
5077 for(fsp2=fsp;*fsp2; fsp2++) {
5078 d3 = PyDict_New();
5079 if (d3 == NULL) {
5080 Py_DECREF(d);
5081 Py_DECREF(d2);
5082 if (fsp)
5083 free(fsp);
5084 return NULL;
5085 }
5086 MAKE_ENTRY(pagesize);
5087 MAKE_ENTRY(cache_hit);
5088 MAKE_ENTRY(cache_miss);
5089 MAKE_ENTRY(map);
5090 MAKE_ENTRY(page_create);
5091 MAKE_ENTRY(page_in);
5092 MAKE_ENTRY(page_out);
5093 if(PyDict_SetItemString(d2, (*fsp2)->file_name, d3)) {
5094 Py_DECREF(d);
5095 Py_DECREF(d2);
5096 Py_DECREF(d3);
5097 if (fsp)
5098 free(fsp);
5099 return NULL;
5100 }
5101 Py_DECREF(d3);
5102 }
5103
5104#undef MAKE_ENTRY
5105 free(fsp);
5106
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07005107 r = PyTuple_Pack(2, d, d2);
Jesus Cea6557aac2010-03-22 14:22:26 +00005108 Py_DECREF(d);
5109 Py_DECREF(d2);
5110 return r;
5111}
5112
Jesus Cea6557aac2010-03-22 14:22:26 +00005113static PyObject*
5114DBEnv_memp_stat_print(DBEnvObject* self, PyObject* args, PyObject *kwargs)
5115{
5116 int err;
5117 int flags=0;
5118 static char* kwnames[] = { "flags", NULL };
5119
5120 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:memp_stat_print",
5121 kwnames, &flags))
5122 {
5123 return NULL;
5124 }
5125 CHECK_ENV_NOT_CLOSED(self);
5126 MYDB_BEGIN_ALLOW_THREADS;
5127 err = self->db_env->memp_stat_print(self->db_env, flags);
5128 MYDB_END_ALLOW_THREADS;
5129 RETURN_IF_ERR();
5130 RETURN_NONE();
5131}
Jesus Cea6557aac2010-03-22 14:22:26 +00005132
5133
5134static PyObject*
5135DBEnv_memp_trickle(DBEnvObject* self, PyObject* args)
5136{
5137 int err, percent, nwrotep;
5138
5139 if (!PyArg_ParseTuple(args, "i:memp_trickle", &percent))
5140 return NULL;
5141 CHECK_ENV_NOT_CLOSED(self);
5142 MYDB_BEGIN_ALLOW_THREADS;
5143 err = self->db_env->memp_trickle(self->db_env, percent, &nwrotep);
5144 MYDB_END_ALLOW_THREADS;
5145 RETURN_IF_ERR();
5146 return NUMBER_FromLong(nwrotep);
5147}
5148
5149static PyObject*
5150DBEnv_memp_sync(DBEnvObject* self, PyObject* args)
5151{
5152 int err;
5153 DB_LSN lsn = {0, 0};
5154 DB_LSN *lsn_p = NULL;
5155
5156 if (!PyArg_ParseTuple(args, "|(ii):memp_sync", &lsn.file, &lsn.offset))
5157 return NULL;
5158 if ((lsn.file!=0) || (lsn.offset!=0)) {
5159 lsn_p = &lsn;
5160 }
5161 CHECK_ENV_NOT_CLOSED(self);
5162 MYDB_BEGIN_ALLOW_THREADS;
5163 err = self->db_env->memp_sync(self->db_env, lsn_p);
5164 MYDB_END_ALLOW_THREADS;
5165 RETURN_IF_ERR();
5166 RETURN_NONE();
5167}
5168
5169static PyObject*
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005170DBEnv_remove(DBEnvObject* self, PyObject* args)
5171{
5172 int err, flags=0;
5173 char *db_home;
5174
5175 if (!PyArg_ParseTuple(args, "s|i:remove", &db_home, &flags))
5176 return NULL;
5177 CHECK_ENV_NOT_CLOSED(self);
5178 MYDB_BEGIN_ALLOW_THREADS;
5179 err = self->db_env->remove(self->db_env, db_home, flags);
5180 MYDB_END_ALLOW_THREADS;
5181 RETURN_IF_ERR();
5182 RETURN_NONE();
5183}
5184
Barry Warsaw9a0d7792002-12-30 20:53:52 +00005185static PyObject*
5186DBEnv_dbremove(DBEnvObject* self, PyObject* args, PyObject* kwargs)
5187{
5188 int err;
5189 u_int32_t flags=0;
5190 char *file = NULL;
5191 char *database = NULL;
5192 PyObject *txnobj = NULL;
5193 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00005194 static char* kwnames[] = { "file", "database", "txn", "flags",
Jeremy Hyltonaf68c872005-12-10 18:50:16 +00005195 NULL };
Barry Warsaw9a0d7792002-12-30 20:53:52 +00005196
Gregory P. Smith641cddf2006-07-28 01:35:25 +00005197 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|zOi:dbremove", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00005198 &file, &database, &txnobj, &flags)) {
5199 return NULL;
Barry Warsaw9a0d7792002-12-30 20:53:52 +00005200 }
5201 if (!checkTxnObj(txnobj, &txn)) {
5202 return NULL;
5203 }
5204 CHECK_ENV_NOT_CLOSED(self);
5205 MYDB_BEGIN_ALLOW_THREADS;
5206 err = self->db_env->dbremove(self->db_env, txn, file, database, flags);
5207 MYDB_END_ALLOW_THREADS;
5208 RETURN_IF_ERR();
5209 RETURN_NONE();
5210}
5211
5212static PyObject*
5213DBEnv_dbrename(DBEnvObject* self, PyObject* args, PyObject* kwargs)
5214{
5215 int err;
5216 u_int32_t flags=0;
5217 char *file = NULL;
5218 char *database = NULL;
5219 char *newname = NULL;
5220 PyObject *txnobj = NULL;
5221 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00005222 static char* kwnames[] = { "file", "database", "newname", "txn",
Jeremy Hyltonaf68c872005-12-10 18:50:16 +00005223 "flags", NULL };
Barry Warsaw9a0d7792002-12-30 20:53:52 +00005224
Gregory P. Smith641cddf2006-07-28 01:35:25 +00005225 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "szs|Oi:dbrename", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00005226 &file, &database, &newname, &txnobj, &flags)) {
5227 return NULL;
Barry Warsaw9a0d7792002-12-30 20:53:52 +00005228 }
5229 if (!checkTxnObj(txnobj, &txn)) {
5230 return NULL;
5231 }
5232 CHECK_ENV_NOT_CLOSED(self);
5233 MYDB_BEGIN_ALLOW_THREADS;
5234 err = self->db_env->dbrename(self->db_env, txn, file, database, newname,
5235 flags);
5236 MYDB_END_ALLOW_THREADS;
5237 RETURN_IF_ERR();
5238 RETURN_NONE();
5239}
5240
Jesus Cea6557aac2010-03-22 14:22:26 +00005241
5242
Barry Warsaw9a0d7792002-12-30 20:53:52 +00005243static PyObject*
5244DBEnv_set_encrypt(DBEnvObject* self, PyObject* args, PyObject* kwargs)
5245{
5246 int err;
5247 u_int32_t flags=0;
5248 char *passwd = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00005249 static char* kwnames[] = { "passwd", "flags", NULL };
Barry Warsaw9a0d7792002-12-30 20:53:52 +00005250
5251 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|i:set_encrypt", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00005252 &passwd, &flags)) {
5253 return NULL;
Barry Warsaw9a0d7792002-12-30 20:53:52 +00005254 }
5255
5256 MYDB_BEGIN_ALLOW_THREADS;
5257 err = self->db_env->set_encrypt(self->db_env, passwd, flags);
5258 MYDB_END_ALLOW_THREADS;
5259
5260 RETURN_IF_ERR();
5261 RETURN_NONE();
5262}
Jesus Cea6557aac2010-03-22 14:22:26 +00005263
Jesus Cea6557aac2010-03-22 14:22:26 +00005264static PyObject*
5265DBEnv_get_encrypt_flags(DBEnvObject* self)
5266{
5267 int err;
5268 u_int32_t flags;
5269
5270 CHECK_ENV_NOT_CLOSED(self);
5271
5272 MYDB_BEGIN_ALLOW_THREADS;
5273 err = self->db_env->get_encrypt_flags(self->db_env, &flags);
5274 MYDB_END_ALLOW_THREADS;
5275
5276 RETURN_IF_ERR();
5277
5278 return NUMBER_FromLong(flags);
5279}
5280
5281static PyObject*
5282DBEnv_get_timeout(DBEnvObject* self, PyObject* args, PyObject* kwargs)
5283{
5284 int err;
5285 int flag;
5286 u_int32_t timeout;
5287 static char* kwnames[] = {"flag", NULL };
5288
5289 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i:get_timeout", kwnames,
5290 &flag)) {
5291 return NULL;
5292 }
5293 CHECK_ENV_NOT_CLOSED(self);
5294
5295 MYDB_BEGIN_ALLOW_THREADS;
5296 err = self->db_env->get_timeout(self->db_env, &timeout, flag);
5297 MYDB_END_ALLOW_THREADS;
5298 RETURN_IF_ERR();
5299 return NUMBER_FromLong(timeout);
5300}
Jesus Cea6557aac2010-03-22 14:22:26 +00005301
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005302
Gregory P. Smithfe11d3e2003-03-27 17:23:29 +00005303static PyObject*
5304DBEnv_set_timeout(DBEnvObject* self, PyObject* args, PyObject* kwargs)
5305{
5306 int err;
5307 u_int32_t flags=0;
5308 u_int32_t timeout = 0;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00005309 static char* kwnames[] = { "timeout", "flags", NULL };
Gregory P. Smithfe11d3e2003-03-27 17:23:29 +00005310
5311 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ii:set_timeout", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00005312 &timeout, &flags)) {
5313 return NULL;
Gregory P. Smithfe11d3e2003-03-27 17:23:29 +00005314 }
5315
5316 MYDB_BEGIN_ALLOW_THREADS;
5317 err = self->db_env->set_timeout(self->db_env, (db_timeout_t)timeout, flags);
5318 MYDB_END_ALLOW_THREADS;
5319
5320 RETURN_IF_ERR();
5321 RETURN_NONE();
5322}
Gregory P. Smithfe11d3e2003-03-27 17:23:29 +00005323
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005324static PyObject*
Gregory P. Smith6676f6e2003-08-28 21:50:30 +00005325DBEnv_set_shm_key(DBEnvObject* self, PyObject* args)
5326{
5327 int err;
5328 long shm_key = 0;
5329
5330 if (!PyArg_ParseTuple(args, "l:set_shm_key", &shm_key))
5331 return NULL;
5332 CHECK_ENV_NOT_CLOSED(self);
5333
5334 err = self->db_env->set_shm_key(self->db_env, shm_key);
5335 RETURN_IF_ERR();
5336 RETURN_NONE();
5337}
5338
Jesus Cea6557aac2010-03-22 14:22:26 +00005339static PyObject*
5340DBEnv_get_shm_key(DBEnvObject* self)
5341{
5342 int err;
5343 long shm_key;
5344
5345 CHECK_ENV_NOT_CLOSED(self);
5346
5347 MYDB_BEGIN_ALLOW_THREADS;
5348 err = self->db_env->get_shm_key(self->db_env, &shm_key);
5349 MYDB_END_ALLOW_THREADS;
5350
5351 RETURN_IF_ERR();
5352
5353 return NUMBER_FromLong(shm_key);
5354}
Jesus Cea6557aac2010-03-22 14:22:26 +00005355
5356#if (DBVER >= 46)
5357static PyObject*
5358DBEnv_set_cache_max(DBEnvObject* self, PyObject* args)
5359{
5360 int err, gbytes, bytes;
5361
5362 if (!PyArg_ParseTuple(args, "ii:set_cache_max",
5363 &gbytes, &bytes))
5364 return NULL;
5365 CHECK_ENV_NOT_CLOSED(self);
5366
5367 MYDB_BEGIN_ALLOW_THREADS;
5368 err = self->db_env->set_cache_max(self->db_env, gbytes, bytes);
5369 MYDB_END_ALLOW_THREADS;
5370 RETURN_IF_ERR();
5371 RETURN_NONE();
5372}
5373
5374static PyObject*
5375DBEnv_get_cache_max(DBEnvObject* self)
5376{
5377 int err;
5378 u_int32_t gbytes, bytes;
5379
5380 CHECK_ENV_NOT_CLOSED(self);
5381
5382 MYDB_BEGIN_ALLOW_THREADS;
5383 err = self->db_env->get_cache_max(self->db_env, &gbytes, &bytes);
5384 MYDB_END_ALLOW_THREADS;
5385
5386 RETURN_IF_ERR();
5387
5388 return Py_BuildValue("(ii)", gbytes, bytes);
5389}
5390#endif
5391
5392#if (DBVER >= 46)
5393static PyObject*
5394DBEnv_set_thread_count(DBEnvObject* self, PyObject* args)
5395{
5396 int err;
5397 u_int32_t count;
5398
5399 if (!PyArg_ParseTuple(args, "i:set_thread_count", &count))
5400 return NULL;
5401 CHECK_ENV_NOT_CLOSED(self);
5402
5403 MYDB_BEGIN_ALLOW_THREADS;
5404 err = self->db_env->set_thread_count(self->db_env, count);
5405 MYDB_END_ALLOW_THREADS;
5406 RETURN_IF_ERR();
5407 RETURN_NONE();
5408}
5409
5410static PyObject*
5411DBEnv_get_thread_count(DBEnvObject* self)
5412{
5413 int err;
5414 u_int32_t count;
5415
5416 CHECK_ENV_NOT_CLOSED(self);
5417
5418 MYDB_BEGIN_ALLOW_THREADS;
5419 err = self->db_env->get_thread_count(self->db_env, &count);
5420 MYDB_END_ALLOW_THREADS;
5421 RETURN_IF_ERR();
5422 return NUMBER_FromLong(count);
5423}
5424#endif
5425
Gregory P. Smith6676f6e2003-08-28 21:50:30 +00005426static PyObject*
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005427DBEnv_set_cachesize(DBEnvObject* self, PyObject* args)
5428{
5429 int err, gbytes=0, bytes=0, ncache=0;
5430
5431 if (!PyArg_ParseTuple(args, "ii|i:set_cachesize",
5432 &gbytes, &bytes, &ncache))
5433 return NULL;
5434 CHECK_ENV_NOT_CLOSED(self);
5435
5436 MYDB_BEGIN_ALLOW_THREADS;
5437 err = self->db_env->set_cachesize(self->db_env, gbytes, bytes, ncache);
5438 MYDB_END_ALLOW_THREADS;
5439 RETURN_IF_ERR();
5440 RETURN_NONE();
5441}
5442
Jesus Cea6557aac2010-03-22 14:22:26 +00005443static PyObject*
5444DBEnv_get_cachesize(DBEnvObject* self)
5445{
5446 int err;
5447 u_int32_t gbytes, bytes;
5448 int ncache;
5449
5450 CHECK_ENV_NOT_CLOSED(self);
5451
5452 MYDB_BEGIN_ALLOW_THREADS;
5453 err = self->db_env->get_cachesize(self->db_env, &gbytes, &bytes, &ncache);
5454 MYDB_END_ALLOW_THREADS;
5455
5456 RETURN_IF_ERR();
5457
5458 return Py_BuildValue("(iii)", gbytes, bytes, ncache);
5459}
Jesus Cea6557aac2010-03-22 14:22:26 +00005460
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005461
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005462static PyObject*
5463DBEnv_set_flags(DBEnvObject* self, PyObject* args)
5464{
5465 int err, flags=0, onoff=0;
5466
5467 if (!PyArg_ParseTuple(args, "ii:set_flags",
5468 &flags, &onoff))
5469 return NULL;
5470 CHECK_ENV_NOT_CLOSED(self);
5471
5472 MYDB_BEGIN_ALLOW_THREADS;
5473 err = self->db_env->set_flags(self->db_env, flags, onoff);
5474 MYDB_END_ALLOW_THREADS;
5475 RETURN_IF_ERR();
5476 RETURN_NONE();
5477}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005478
Jesus Cea6557aac2010-03-22 14:22:26 +00005479static PyObject*
5480DBEnv_get_flags(DBEnvObject* self)
5481{
5482 int err;
5483 u_int32_t flags;
5484
5485 CHECK_ENV_NOT_CLOSED(self);
5486
5487 MYDB_BEGIN_ALLOW_THREADS;
5488 err = self->db_env->get_flags(self->db_env, &flags);
5489 MYDB_END_ALLOW_THREADS;
5490 RETURN_IF_ERR();
5491 return NUMBER_FromLong(flags);
5492}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005493
Jesus Ceaca3939c2008-05-22 15:27:38 +00005494#if (DBVER >= 47)
5495static PyObject*
5496DBEnv_log_set_config(DBEnvObject* self, PyObject* args)
5497{
5498 int err, flags, onoff;
5499
5500 if (!PyArg_ParseTuple(args, "ii:log_set_config",
5501 &flags, &onoff))
5502 return NULL;
5503 CHECK_ENV_NOT_CLOSED(self);
5504
5505 MYDB_BEGIN_ALLOW_THREADS;
5506 err = self->db_env->log_set_config(self->db_env, flags, onoff);
5507 MYDB_END_ALLOW_THREADS;
5508 RETURN_IF_ERR();
5509 RETURN_NONE();
5510}
Jesus Cea6557aac2010-03-22 14:22:26 +00005511
5512static PyObject*
5513DBEnv_log_get_config(DBEnvObject* self, PyObject* args)
5514{
5515 int err, flag, onoff;
5516
5517 if (!PyArg_ParseTuple(args, "i:log_get_config", &flag))
5518 return NULL;
5519 CHECK_ENV_NOT_CLOSED(self);
5520
5521 MYDB_BEGIN_ALLOW_THREADS;
5522 err = self->db_env->log_get_config(self->db_env, flag, &onoff);
5523 MYDB_END_ALLOW_THREADS;
5524 RETURN_IF_ERR();
5525 return PyBool_FromLong(onoff);
5526}
Jesus Ceaca3939c2008-05-22 15:27:38 +00005527#endif /* DBVER >= 47 */
5528
Jesus Cea6557aac2010-03-22 14:22:26 +00005529#if (DBVER >= 44)
5530static PyObject*
5531DBEnv_mutex_set_max(DBEnvObject* self, PyObject* args)
5532{
5533 int err;
5534 int value;
5535
5536 if (!PyArg_ParseTuple(args, "i:mutex_set_max", &value))
5537 return NULL;
5538
5539 CHECK_ENV_NOT_CLOSED(self);
5540
5541 MYDB_BEGIN_ALLOW_THREADS;
5542 err = self->db_env->mutex_set_max(self->db_env, value);
5543 MYDB_END_ALLOW_THREADS;
5544
5545 RETURN_IF_ERR();
5546 RETURN_NONE();
5547}
5548
5549static PyObject*
5550DBEnv_mutex_get_max(DBEnvObject* self)
5551{
5552 int err;
5553 u_int32_t value;
5554
5555 CHECK_ENV_NOT_CLOSED(self);
5556
5557 MYDB_BEGIN_ALLOW_THREADS;
5558 err = self->db_env->mutex_get_max(self->db_env, &value);
5559 MYDB_END_ALLOW_THREADS;
5560
5561 RETURN_IF_ERR();
5562
5563 return NUMBER_FromLong(value);
5564}
5565
5566static PyObject*
5567DBEnv_mutex_set_align(DBEnvObject* self, PyObject* args)
5568{
5569 int err;
5570 int align;
5571
5572 if (!PyArg_ParseTuple(args, "i:mutex_set_align", &align))
5573 return NULL;
5574
5575 CHECK_ENV_NOT_CLOSED(self);
5576
5577 MYDB_BEGIN_ALLOW_THREADS;
5578 err = self->db_env->mutex_set_align(self->db_env, align);
5579 MYDB_END_ALLOW_THREADS;
5580
5581 RETURN_IF_ERR();
5582 RETURN_NONE();
5583}
5584
5585static PyObject*
5586DBEnv_mutex_get_align(DBEnvObject* self)
5587{
5588 int err;
5589 u_int32_t align;
5590
5591 CHECK_ENV_NOT_CLOSED(self);
5592
5593 MYDB_BEGIN_ALLOW_THREADS;
5594 err = self->db_env->mutex_get_align(self->db_env, &align);
5595 MYDB_END_ALLOW_THREADS;
5596
5597 RETURN_IF_ERR();
5598
5599 return NUMBER_FromLong(align);
5600}
5601
5602static PyObject*
5603DBEnv_mutex_set_increment(DBEnvObject* self, PyObject* args)
5604{
5605 int err;
5606 int increment;
5607
5608 if (!PyArg_ParseTuple(args, "i:mutex_set_increment", &increment))
5609 return NULL;
5610
5611 CHECK_ENV_NOT_CLOSED(self);
5612
5613 MYDB_BEGIN_ALLOW_THREADS;
5614 err = self->db_env->mutex_set_increment(self->db_env, increment);
5615 MYDB_END_ALLOW_THREADS;
5616
5617 RETURN_IF_ERR();
5618 RETURN_NONE();
5619}
5620
5621static PyObject*
5622DBEnv_mutex_get_increment(DBEnvObject* self)
5623{
5624 int err;
5625 u_int32_t increment;
5626
5627 CHECK_ENV_NOT_CLOSED(self);
5628
5629 MYDB_BEGIN_ALLOW_THREADS;
5630 err = self->db_env->mutex_get_increment(self->db_env, &increment);
5631 MYDB_END_ALLOW_THREADS;
5632
5633 RETURN_IF_ERR();
5634
5635 return NUMBER_FromLong(increment);
5636}
5637
5638static PyObject*
5639DBEnv_mutex_set_tas_spins(DBEnvObject* self, PyObject* args)
5640{
5641 int err;
5642 int tas_spins;
5643
5644 if (!PyArg_ParseTuple(args, "i:mutex_set_tas_spins", &tas_spins))
5645 return NULL;
5646
5647 CHECK_ENV_NOT_CLOSED(self);
5648
5649 MYDB_BEGIN_ALLOW_THREADS;
5650 err = self->db_env->mutex_set_tas_spins(self->db_env, tas_spins);
5651 MYDB_END_ALLOW_THREADS;
5652
5653 RETURN_IF_ERR();
5654 RETURN_NONE();
5655}
5656
5657static PyObject*
5658DBEnv_mutex_get_tas_spins(DBEnvObject* self)
5659{
5660 int err;
5661 u_int32_t tas_spins;
5662
5663 CHECK_ENV_NOT_CLOSED(self);
5664
5665 MYDB_BEGIN_ALLOW_THREADS;
5666 err = self->db_env->mutex_get_tas_spins(self->db_env, &tas_spins);
5667 MYDB_END_ALLOW_THREADS;
5668
5669 RETURN_IF_ERR();
5670
5671 return NUMBER_FromLong(tas_spins);
5672}
5673#endif
Jesus Ceaca3939c2008-05-22 15:27:38 +00005674
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005675static PyObject*
5676DBEnv_set_data_dir(DBEnvObject* self, PyObject* args)
5677{
5678 int err;
5679 char *dir;
5680
5681 if (!PyArg_ParseTuple(args, "s:set_data_dir", &dir))
5682 return NULL;
5683 CHECK_ENV_NOT_CLOSED(self);
5684
5685 MYDB_BEGIN_ALLOW_THREADS;
5686 err = self->db_env->set_data_dir(self->db_env, dir);
5687 MYDB_END_ALLOW_THREADS;
5688 RETURN_IF_ERR();
5689 RETURN_NONE();
5690}
5691
Jesus Cea6557aac2010-03-22 14:22:26 +00005692static PyObject*
5693DBEnv_get_data_dirs(DBEnvObject* self)
5694{
5695 int err;
5696 PyObject *tuple;
5697 PyObject *item;
5698 const char **dirpp;
5699 int size, i;
5700
5701 CHECK_ENV_NOT_CLOSED(self);
5702
5703 MYDB_BEGIN_ALLOW_THREADS;
5704 err = self->db_env->get_data_dirs(self->db_env, &dirpp);
5705 MYDB_END_ALLOW_THREADS;
5706
5707 RETURN_IF_ERR();
5708
5709 /*
5710 ** Calculate size. Python C API
5711 ** actually allows for tuple resizing,
5712 ** but this is simple enough.
5713 */
5714 for (size=0; *(dirpp+size) ; size++);
5715
5716 tuple = PyTuple_New(size);
5717 if (!tuple)
5718 return NULL;
5719
5720 for (i=0; i<size; i++) {
5721 item = PyBytes_FromString (*(dirpp+i));
5722 if (item == NULL) {
5723 Py_DECREF(tuple);
5724 tuple = NULL;
5725 break;
5726 }
5727 PyTuple_SET_ITEM(tuple, i, item);
5728 }
5729 return tuple;
5730}
Jesus Cea6557aac2010-03-22 14:22:26 +00005731
5732#if (DBVER >= 44)
5733static PyObject*
5734DBEnv_set_lg_filemode(DBEnvObject* self, PyObject* args)
5735{
5736 int err, filemode;
5737
5738 if (!PyArg_ParseTuple(args, "i:set_lg_filemode", &filemode))
5739 return NULL;
5740 CHECK_ENV_NOT_CLOSED(self);
5741
5742 MYDB_BEGIN_ALLOW_THREADS;
5743 err = self->db_env->set_lg_filemode(self->db_env, filemode);
5744 MYDB_END_ALLOW_THREADS;
5745 RETURN_IF_ERR();
5746 RETURN_NONE();
5747}
5748
5749static PyObject*
5750DBEnv_get_lg_filemode(DBEnvObject* self)
5751{
5752 int err, filemode;
5753
5754 CHECK_ENV_NOT_CLOSED(self);
5755
5756 MYDB_BEGIN_ALLOW_THREADS;
5757 err = self->db_env->get_lg_filemode(self->db_env, &filemode);
5758 MYDB_END_ALLOW_THREADS;
5759 RETURN_IF_ERR();
5760 return NUMBER_FromLong(filemode);
5761}
5762#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005763
5764static PyObject*
5765DBEnv_set_lg_bsize(DBEnvObject* self, PyObject* args)
5766{
5767 int err, lg_bsize;
5768
5769 if (!PyArg_ParseTuple(args, "i:set_lg_bsize", &lg_bsize))
5770 return NULL;
5771 CHECK_ENV_NOT_CLOSED(self);
5772
5773 MYDB_BEGIN_ALLOW_THREADS;
5774 err = self->db_env->set_lg_bsize(self->db_env, lg_bsize);
5775 MYDB_END_ALLOW_THREADS;
5776 RETURN_IF_ERR();
5777 RETURN_NONE();
5778}
5779
Jesus Cea6557aac2010-03-22 14:22:26 +00005780static PyObject*
5781DBEnv_get_lg_bsize(DBEnvObject* self)
5782{
5783 int err;
5784 u_int32_t lg_bsize;
5785
5786 CHECK_ENV_NOT_CLOSED(self);
5787
5788 MYDB_BEGIN_ALLOW_THREADS;
5789 err = self->db_env->get_lg_bsize(self->db_env, &lg_bsize);
5790 MYDB_END_ALLOW_THREADS;
5791 RETURN_IF_ERR();
5792 return NUMBER_FromLong(lg_bsize);
5793}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005794
5795static PyObject*
5796DBEnv_set_lg_dir(DBEnvObject* self, PyObject* args)
5797{
5798 int err;
5799 char *dir;
5800
5801 if (!PyArg_ParseTuple(args, "s:set_lg_dir", &dir))
5802 return NULL;
5803 CHECK_ENV_NOT_CLOSED(self);
5804
5805 MYDB_BEGIN_ALLOW_THREADS;
5806 err = self->db_env->set_lg_dir(self->db_env, dir);
5807 MYDB_END_ALLOW_THREADS;
5808 RETURN_IF_ERR();
5809 RETURN_NONE();
5810}
5811
Jesus Cea6557aac2010-03-22 14:22:26 +00005812static PyObject*
5813DBEnv_get_lg_dir(DBEnvObject* self)
5814{
5815 int err;
5816 const char *dirp;
5817
5818 CHECK_ENV_NOT_CLOSED(self);
5819
5820 MYDB_BEGIN_ALLOW_THREADS;
5821 err = self->db_env->get_lg_dir(self->db_env, &dirp);
5822 MYDB_END_ALLOW_THREADS;
5823 RETURN_IF_ERR();
5824 return PyBytes_FromString(dirp);
5825}
Jesus Cea6557aac2010-03-22 14:22:26 +00005826
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005827static PyObject*
5828DBEnv_set_lg_max(DBEnvObject* self, PyObject* args)
5829{
5830 int err, lg_max;
5831
5832 if (!PyArg_ParseTuple(args, "i:set_lg_max", &lg_max))
5833 return NULL;
5834 CHECK_ENV_NOT_CLOSED(self);
5835
5836 MYDB_BEGIN_ALLOW_THREADS;
5837 err = self->db_env->set_lg_max(self->db_env, lg_max);
5838 MYDB_END_ALLOW_THREADS;
5839 RETURN_IF_ERR();
5840 RETURN_NONE();
5841}
5842
Jesus Ceaef9764f2008-05-13 18:45:46 +00005843static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00005844DBEnv_get_lg_max(DBEnvObject* self)
Jesus Ceaef9764f2008-05-13 18:45:46 +00005845{
5846 int err;
5847 u_int32_t lg_max;
5848
Jesus Ceaef9764f2008-05-13 18:45:46 +00005849 CHECK_ENV_NOT_CLOSED(self);
5850
5851 MYDB_BEGIN_ALLOW_THREADS;
5852 err = self->db_env->get_lg_max(self->db_env, &lg_max);
5853 MYDB_END_ALLOW_THREADS;
5854 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00005855 return NUMBER_FromLong(lg_max);
Jesus Ceaef9764f2008-05-13 18:45:46 +00005856}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005857
5858static PyObject*
Gregory P. Smithe9477062005-06-04 06:46:59 +00005859DBEnv_set_lg_regionmax(DBEnvObject* self, PyObject* args)
5860{
5861 int err, lg_max;
5862
5863 if (!PyArg_ParseTuple(args, "i:set_lg_regionmax", &lg_max))
5864 return NULL;
5865 CHECK_ENV_NOT_CLOSED(self);
5866
5867 MYDB_BEGIN_ALLOW_THREADS;
5868 err = self->db_env->set_lg_regionmax(self->db_env, lg_max);
5869 MYDB_END_ALLOW_THREADS;
5870 RETURN_IF_ERR();
5871 RETURN_NONE();
5872}
5873
Jesus Cea6557aac2010-03-22 14:22:26 +00005874static PyObject*
5875DBEnv_get_lg_regionmax(DBEnvObject* self)
5876{
5877 int err;
5878 u_int32_t lg_regionmax;
5879
5880 CHECK_ENV_NOT_CLOSED(self);
5881
5882 MYDB_BEGIN_ALLOW_THREADS;
5883 err = self->db_env->get_lg_regionmax(self->db_env, &lg_regionmax);
5884 MYDB_END_ALLOW_THREADS;
5885 RETURN_IF_ERR();
5886 return NUMBER_FromLong(lg_regionmax);
5887}
Jesus Cea6557aac2010-03-22 14:22:26 +00005888
5889#if (DBVER >= 47)
5890static PyObject*
5891DBEnv_set_lk_partitions(DBEnvObject* self, PyObject* args)
5892{
5893 int err, lk_partitions;
5894
5895 if (!PyArg_ParseTuple(args, "i:set_lk_partitions", &lk_partitions))
5896 return NULL;
5897 CHECK_ENV_NOT_CLOSED(self);
5898
5899 MYDB_BEGIN_ALLOW_THREADS;
5900 err = self->db_env->set_lk_partitions(self->db_env, lk_partitions);
5901 MYDB_END_ALLOW_THREADS;
5902 RETURN_IF_ERR();
5903 RETURN_NONE();
5904}
5905
5906static PyObject*
5907DBEnv_get_lk_partitions(DBEnvObject* self)
5908{
5909 int err;
5910 u_int32_t lk_partitions;
5911
5912 CHECK_ENV_NOT_CLOSED(self);
5913
5914 MYDB_BEGIN_ALLOW_THREADS;
5915 err = self->db_env->get_lk_partitions(self->db_env, &lk_partitions);
5916 MYDB_END_ALLOW_THREADS;
5917 RETURN_IF_ERR();
5918 return NUMBER_FromLong(lk_partitions);
5919}
5920#endif
Gregory P. Smithe9477062005-06-04 06:46:59 +00005921
5922static PyObject*
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005923DBEnv_set_lk_detect(DBEnvObject* self, PyObject* args)
5924{
5925 int err, lk_detect;
5926
5927 if (!PyArg_ParseTuple(args, "i:set_lk_detect", &lk_detect))
5928 return NULL;
5929 CHECK_ENV_NOT_CLOSED(self);
5930
5931 MYDB_BEGIN_ALLOW_THREADS;
5932 err = self->db_env->set_lk_detect(self->db_env, lk_detect);
5933 MYDB_END_ALLOW_THREADS;
5934 RETURN_IF_ERR();
5935 RETURN_NONE();
5936}
5937
Jesus Cea6557aac2010-03-22 14:22:26 +00005938static PyObject*
5939DBEnv_get_lk_detect(DBEnvObject* self)
5940{
5941 int err;
5942 u_int32_t lk_detect;
5943
5944 CHECK_ENV_NOT_CLOSED(self);
5945
5946 MYDB_BEGIN_ALLOW_THREADS;
5947 err = self->db_env->get_lk_detect(self->db_env, &lk_detect);
5948 MYDB_END_ALLOW_THREADS;
5949 RETURN_IF_ERR();
5950 return NUMBER_FromLong(lk_detect);
5951}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005952
Gregory P. Smith8b96a352007-01-05 01:59:42 +00005953#if (DBVER < 45)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005954static PyObject*
5955DBEnv_set_lk_max(DBEnvObject* self, PyObject* args)
5956{
5957 int err, max;
5958
5959 if (!PyArg_ParseTuple(args, "i:set_lk_max", &max))
5960 return NULL;
5961 CHECK_ENV_NOT_CLOSED(self);
5962
5963 MYDB_BEGIN_ALLOW_THREADS;
5964 err = self->db_env->set_lk_max(self->db_env, max);
5965 MYDB_END_ALLOW_THREADS;
5966 RETURN_IF_ERR();
5967 RETURN_NONE();
5968}
Gregory P. Smith8b96a352007-01-05 01:59:42 +00005969#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005970
5971
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005972
5973static PyObject*
5974DBEnv_set_lk_max_locks(DBEnvObject* self, PyObject* args)
5975{
5976 int err, max;
5977
5978 if (!PyArg_ParseTuple(args, "i:set_lk_max_locks", &max))
5979 return NULL;
5980 CHECK_ENV_NOT_CLOSED(self);
5981
5982 MYDB_BEGIN_ALLOW_THREADS;
5983 err = self->db_env->set_lk_max_locks(self->db_env, max);
5984 MYDB_END_ALLOW_THREADS;
5985 RETURN_IF_ERR();
5986 RETURN_NONE();
5987}
5988
Jesus Cea6557aac2010-03-22 14:22:26 +00005989static PyObject*
5990DBEnv_get_lk_max_locks(DBEnvObject* self)
5991{
5992 int err;
5993 u_int32_t lk_max;
5994
5995 CHECK_ENV_NOT_CLOSED(self);
5996
5997 MYDB_BEGIN_ALLOW_THREADS;
5998 err = self->db_env->get_lk_max_locks(self->db_env, &lk_max);
5999 MYDB_END_ALLOW_THREADS;
6000 RETURN_IF_ERR();
6001 return NUMBER_FromLong(lk_max);
6002}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006003
6004static PyObject*
6005DBEnv_set_lk_max_lockers(DBEnvObject* self, PyObject* args)
6006{
6007 int err, max;
6008
6009 if (!PyArg_ParseTuple(args, "i:set_lk_max_lockers", &max))
6010 return NULL;
6011 CHECK_ENV_NOT_CLOSED(self);
6012
6013 MYDB_BEGIN_ALLOW_THREADS;
6014 err = self->db_env->set_lk_max_lockers(self->db_env, max);
6015 MYDB_END_ALLOW_THREADS;
6016 RETURN_IF_ERR();
6017 RETURN_NONE();
6018}
6019
Jesus Cea6557aac2010-03-22 14:22:26 +00006020static PyObject*
6021DBEnv_get_lk_max_lockers(DBEnvObject* self)
6022{
6023 int err;
6024 u_int32_t lk_max;
6025
6026 CHECK_ENV_NOT_CLOSED(self);
6027
6028 MYDB_BEGIN_ALLOW_THREADS;
6029 err = self->db_env->get_lk_max_lockers(self->db_env, &lk_max);
6030 MYDB_END_ALLOW_THREADS;
6031 RETURN_IF_ERR();
6032 return NUMBER_FromLong(lk_max);
6033}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006034
6035static PyObject*
6036DBEnv_set_lk_max_objects(DBEnvObject* self, PyObject* args)
6037{
6038 int err, max;
6039
6040 if (!PyArg_ParseTuple(args, "i:set_lk_max_objects", &max))
6041 return NULL;
6042 CHECK_ENV_NOT_CLOSED(self);
6043
6044 MYDB_BEGIN_ALLOW_THREADS;
6045 err = self->db_env->set_lk_max_objects(self->db_env, max);
6046 MYDB_END_ALLOW_THREADS;
6047 RETURN_IF_ERR();
6048 RETURN_NONE();
6049}
6050
Jesus Cea6557aac2010-03-22 14:22:26 +00006051static PyObject*
6052DBEnv_get_lk_max_objects(DBEnvObject* self)
6053{
6054 int err;
6055 u_int32_t lk_max;
6056
6057 CHECK_ENV_NOT_CLOSED(self);
6058
6059 MYDB_BEGIN_ALLOW_THREADS;
6060 err = self->db_env->get_lk_max_objects(self->db_env, &lk_max);
6061 MYDB_END_ALLOW_THREADS;
6062 RETURN_IF_ERR();
6063 return NUMBER_FromLong(lk_max);
6064}
Jesus Cea6557aac2010-03-22 14:22:26 +00006065
Jesus Cea6557aac2010-03-22 14:22:26 +00006066static PyObject*
6067DBEnv_get_mp_mmapsize(DBEnvObject* self)
6068{
6069 int err;
6070 size_t mmapsize;
6071
6072 CHECK_ENV_NOT_CLOSED(self);
6073
6074 MYDB_BEGIN_ALLOW_THREADS;
6075 err = self->db_env->get_mp_mmapsize(self->db_env, &mmapsize);
6076 MYDB_END_ALLOW_THREADS;
6077 RETURN_IF_ERR();
6078 return NUMBER_FromLong(mmapsize);
6079}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006080
6081static PyObject*
6082DBEnv_set_mp_mmapsize(DBEnvObject* self, PyObject* args)
6083{
6084 int err, mp_mmapsize;
6085
6086 if (!PyArg_ParseTuple(args, "i:set_mp_mmapsize", &mp_mmapsize))
6087 return NULL;
6088 CHECK_ENV_NOT_CLOSED(self);
6089
6090 MYDB_BEGIN_ALLOW_THREADS;
6091 err = self->db_env->set_mp_mmapsize(self->db_env, mp_mmapsize);
6092 MYDB_END_ALLOW_THREADS;
6093 RETURN_IF_ERR();
6094 RETURN_NONE();
6095}
6096
6097
6098static PyObject*
6099DBEnv_set_tmp_dir(DBEnvObject* self, PyObject* args)
6100{
6101 int err;
6102 char *dir;
6103
6104 if (!PyArg_ParseTuple(args, "s:set_tmp_dir", &dir))
6105 return NULL;
6106 CHECK_ENV_NOT_CLOSED(self);
6107
6108 MYDB_BEGIN_ALLOW_THREADS;
6109 err = self->db_env->set_tmp_dir(self->db_env, dir);
6110 MYDB_END_ALLOW_THREADS;
6111 RETURN_IF_ERR();
6112 RETURN_NONE();
6113}
6114
Jesus Cea6557aac2010-03-22 14:22:26 +00006115static PyObject*
6116DBEnv_get_tmp_dir(DBEnvObject* self)
6117{
6118 int err;
6119 const char *dirpp;
6120
6121 CHECK_ENV_NOT_CLOSED(self);
6122
6123 MYDB_BEGIN_ALLOW_THREADS;
6124 err = self->db_env->get_tmp_dir(self->db_env, &dirpp);
6125 MYDB_END_ALLOW_THREADS;
6126
6127 RETURN_IF_ERR();
6128
6129 return PyBytes_FromString(dirpp);
6130}
Jesus Cea6557aac2010-03-22 14:22:26 +00006131
Jesus Ceaef9764f2008-05-13 18:45:46 +00006132static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00006133DBEnv_txn_recover(DBEnvObject* self)
Jesus Ceaef9764f2008-05-13 18:45:46 +00006134{
6135 int flags = DB_FIRST;
6136 int err, i;
6137 PyObject *list, *tuple, *gid;
6138 DBTxnObject *txn;
6139#define PREPLIST_LEN 16
6140 DB_PREPLIST preplist[PREPLIST_LEN];
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07006141#if (DBVER < 48) || (DBVER >= 52)
Jesus Ceaef9764f2008-05-13 18:45:46 +00006142 long retp;
Matthias Klose54cc5392010-03-15 12:46:18 +00006143#else
6144 u_int32_t retp;
6145#endif
Jesus Ceaef9764f2008-05-13 18:45:46 +00006146
Jesus Ceaef9764f2008-05-13 18:45:46 +00006147 CHECK_ENV_NOT_CLOSED(self);
6148
6149 list=PyList_New(0);
6150 if (!list)
6151 return NULL;
6152 while (!0) {
6153 MYDB_BEGIN_ALLOW_THREADS
6154 err=self->db_env->txn_recover(self->db_env,
6155 preplist, PREPLIST_LEN, &retp, flags);
6156#undef PREPLIST_LEN
6157 MYDB_END_ALLOW_THREADS
6158 if (err) {
6159 Py_DECREF(list);
6160 RETURN_IF_ERR();
6161 }
6162 if (!retp) break;
6163 flags=DB_NEXT; /* Prepare for next loop pass */
6164 for (i=0; i<retp; i++) {
Christian Heimes593daf52008-05-26 12:51:38 +00006165 gid=PyBytes_FromStringAndSize((char *)(preplist[i].gid),
Matthias Klose54cc5392010-03-15 12:46:18 +00006166 DB_GID_SIZE);
Jesus Ceaef9764f2008-05-13 18:45:46 +00006167 if (!gid) {
6168 Py_DECREF(list);
6169 return NULL;
6170 }
Jesus Cea6557aac2010-03-22 14:22:26 +00006171 txn=newDBTxnObject(self, NULL, preplist[i].txn, 0);
Jesus Ceaef9764f2008-05-13 18:45:46 +00006172 if (!txn) {
6173 Py_DECREF(list);
6174 Py_DECREF(gid);
6175 return NULL;
6176 }
6177 txn->flag_prepare=1; /* Recover state */
6178 tuple=PyTuple_New(2);
6179 if (!tuple) {
6180 Py_DECREF(list);
6181 Py_DECREF(gid);
6182 Py_DECREF(txn);
6183 return NULL;
6184 }
6185 if (PyTuple_SetItem(tuple, 0, gid)) {
6186 Py_DECREF(list);
6187 Py_DECREF(gid);
6188 Py_DECREF(txn);
6189 Py_DECREF(tuple);
6190 return NULL;
6191 }
6192 if (PyTuple_SetItem(tuple, 1, (PyObject *)txn)) {
6193 Py_DECREF(list);
6194 Py_DECREF(txn);
6195 Py_DECREF(tuple); /* This delete the "gid" also */
6196 return NULL;
6197 }
6198 if (PyList_Append(list, tuple)) {
6199 Py_DECREF(list);
6200 Py_DECREF(tuple);/* This delete the "gid" and the "txn" also */
6201 return NULL;
6202 }
6203 Py_DECREF(tuple);
6204 }
6205 }
6206 return list;
6207}
Jesus Ceaef9764f2008-05-13 18:45:46 +00006208
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006209static PyObject*
6210DBEnv_txn_begin(DBEnvObject* self, PyObject* args, PyObject* kwargs)
6211{
6212 int flags = 0;
6213 PyObject* txnobj = NULL;
6214 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00006215 static char* kwnames[] = { "parent", "flags", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006216
6217 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Oi:txn_begin", kwnames,
6218 &txnobj, &flags))
6219 return NULL;
6220
6221 if (!checkTxnObj(txnobj, &txn))
6222 return NULL;
6223 CHECK_ENV_NOT_CLOSED(self);
6224
Jesus Ceaef9764f2008-05-13 18:45:46 +00006225 return (PyObject*)newDBTxnObject(self, (DBTxnObject *)txnobj, NULL, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006226}
6227
6228
6229static PyObject*
6230DBEnv_txn_checkpoint(DBEnvObject* self, PyObject* args)
6231{
6232 int err, kbyte=0, min=0, flags=0;
6233
6234 if (!PyArg_ParseTuple(args, "|iii:txn_checkpoint", &kbyte, &min, &flags))
6235 return NULL;
6236 CHECK_ENV_NOT_CLOSED(self);
6237
6238 MYDB_BEGIN_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006239 err = self->db_env->txn_checkpoint(self->db_env, kbyte, min, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006240 MYDB_END_ALLOW_THREADS;
6241 RETURN_IF_ERR();
6242 RETURN_NONE();
6243}
6244
Jesus Cea6557aac2010-03-22 14:22:26 +00006245static PyObject*
6246DBEnv_get_tx_max(DBEnvObject* self)
6247{
6248 int err;
6249 u_int32_t max;
6250
6251 CHECK_ENV_NOT_CLOSED(self);
6252
6253 MYDB_BEGIN_ALLOW_THREADS;
6254 err = self->db_env->get_tx_max(self->db_env, &max);
6255 MYDB_END_ALLOW_THREADS;
6256 RETURN_IF_ERR();
6257 return PyLong_FromUnsignedLong(max);
6258}
Jesus Cea6557aac2010-03-22 14:22:26 +00006259
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006260static PyObject*
6261DBEnv_set_tx_max(DBEnvObject* self, PyObject* args)
6262{
6263 int err, max;
6264
6265 if (!PyArg_ParseTuple(args, "i:set_tx_max", &max))
6266 return NULL;
6267 CHECK_ENV_NOT_CLOSED(self);
6268
Jesus Cea6557aac2010-03-22 14:22:26 +00006269 MYDB_BEGIN_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006270 err = self->db_env->set_tx_max(self->db_env, max);
Jesus Cea6557aac2010-03-22 14:22:26 +00006271 MYDB_END_ALLOW_THREADS;
Gregory P. Smith8a474042006-01-27 07:05:40 +00006272 RETURN_IF_ERR();
6273 RETURN_NONE();
6274}
6275
Jesus Cea6557aac2010-03-22 14:22:26 +00006276static PyObject*
6277DBEnv_get_tx_timestamp(DBEnvObject* self)
6278{
6279 int err;
6280 time_t timestamp;
6281
6282 CHECK_ENV_NOT_CLOSED(self);
6283
6284 MYDB_BEGIN_ALLOW_THREADS;
6285 err = self->db_env->get_tx_timestamp(self->db_env, &timestamp);
6286 MYDB_END_ALLOW_THREADS;
6287 RETURN_IF_ERR();
6288 return NUMBER_FromLong(timestamp);
6289}
Jesus Cea6557aac2010-03-22 14:22:26 +00006290
Gregory P. Smith8a474042006-01-27 07:05:40 +00006291static PyObject*
6292DBEnv_set_tx_timestamp(DBEnvObject* self, PyObject* args)
6293{
6294 int err;
Thomas Wouters9d63cca2006-03-01 01:01:55 +00006295 long stamp;
6296 time_t timestamp;
Gregory P. Smith8a474042006-01-27 07:05:40 +00006297
Thomas Wouters9d63cca2006-03-01 01:01:55 +00006298 if (!PyArg_ParseTuple(args, "l:set_tx_timestamp", &stamp))
Gregory P. Smith8a474042006-01-27 07:05:40 +00006299 return NULL;
6300 CHECK_ENV_NOT_CLOSED(self);
Thomas Wouters9d63cca2006-03-01 01:01:55 +00006301 timestamp = (time_t)stamp;
Jesus Cea6557aac2010-03-22 14:22:26 +00006302 MYDB_BEGIN_ALLOW_THREADS;
Thomas Wouters9d63cca2006-03-01 01:01:55 +00006303 err = self->db_env->set_tx_timestamp(self->db_env, &timestamp);
Jesus Cea6557aac2010-03-22 14:22:26 +00006304 MYDB_END_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006305 RETURN_IF_ERR();
6306 RETURN_NONE();
6307}
6308
6309
6310static PyObject*
6311DBEnv_lock_detect(DBEnvObject* self, PyObject* args)
6312{
6313 int err, atype, flags=0;
6314 int aborted = 0;
6315
6316 if (!PyArg_ParseTuple(args, "i|i:lock_detect", &atype, &flags))
6317 return NULL;
6318 CHECK_ENV_NOT_CLOSED(self);
6319
6320 MYDB_BEGIN_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006321 err = self->db_env->lock_detect(self->db_env, flags, atype, &aborted);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006322 MYDB_END_ALLOW_THREADS;
6323 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00006324 return NUMBER_FromLong(aborted);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006325}
6326
6327
6328static PyObject*
6329DBEnv_lock_get(DBEnvObject* self, PyObject* args)
6330{
6331 int flags=0;
6332 int locker, lock_mode;
6333 DBT obj;
6334 PyObject* objobj;
6335
6336 if (!PyArg_ParseTuple(args, "iOi|i:lock_get", &locker, &objobj, &lock_mode, &flags))
6337 return NULL;
6338
6339
6340 if (!make_dbt(objobj, &obj))
6341 return NULL;
6342
6343 return (PyObject*)newDBLockObject(self, locker, &obj, lock_mode, flags);
6344}
6345
6346
6347static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00006348DBEnv_lock_id(DBEnvObject* self)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006349{
6350 int err;
6351 u_int32_t theID;
6352
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006353 CHECK_ENV_NOT_CLOSED(self);
6354 MYDB_BEGIN_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006355 err = self->db_env->lock_id(self->db_env, &theID);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006356 MYDB_END_ALLOW_THREADS;
6357 RETURN_IF_ERR();
6358
Jesus Ceac5a11fa2008-07-23 11:38:42 +00006359 return NUMBER_FromLong((long)theID);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006360}
6361
Gregory P. Smithac11e022007-11-05 02:56:31 +00006362static PyObject*
6363DBEnv_lock_id_free(DBEnvObject* self, PyObject* args)
6364{
6365 int err;
6366 u_int32_t theID;
6367
6368 if (!PyArg_ParseTuple(args, "I:lock_id_free", &theID))
6369 return NULL;
6370
6371 CHECK_ENV_NOT_CLOSED(self);
6372 MYDB_BEGIN_ALLOW_THREADS;
6373 err = self->db_env->lock_id_free(self->db_env, theID);
6374 MYDB_END_ALLOW_THREADS;
6375 RETURN_IF_ERR();
6376 RETURN_NONE();
6377}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006378
6379static PyObject*
6380DBEnv_lock_put(DBEnvObject* self, PyObject* args)
6381{
6382 int err;
6383 DBLockObject* dblockobj;
6384
6385 if (!PyArg_ParseTuple(args, "O!:lock_put", &DBLock_Type, &dblockobj))
6386 return NULL;
6387
6388 CHECK_ENV_NOT_CLOSED(self);
6389 MYDB_BEGIN_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006390 err = self->db_env->lock_put(self->db_env, &dblockobj->lock);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006391 MYDB_END_ALLOW_THREADS;
6392 RETURN_IF_ERR();
6393 RETURN_NONE();
6394}
6395
Gregory P. Smithdb8a8072006-06-05 01:56:15 +00006396#if (DBVER >= 44)
6397static PyObject*
Jesus Cea6557aac2010-03-22 14:22:26 +00006398DBEnv_fileid_reset(DBEnvObject* self, PyObject* args, PyObject* kwargs)
6399{
6400 int err;
6401 char *file;
6402 u_int32_t flags = 0;
6403 static char* kwnames[] = { "file", "flags", NULL};
6404
6405 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "z|i:fileid_reset", kwnames,
6406 &file, &flags))
6407 return NULL;
6408 CHECK_ENV_NOT_CLOSED(self);
6409
6410 MYDB_BEGIN_ALLOW_THREADS;
6411 err = self->db_env->fileid_reset(self->db_env, file, flags);
6412 MYDB_END_ALLOW_THREADS;
6413 RETURN_IF_ERR();
6414 RETURN_NONE();
6415}
6416
6417static PyObject*
Gregory P. Smithdb8a8072006-06-05 01:56:15 +00006418DBEnv_lsn_reset(DBEnvObject* self, PyObject* args, PyObject* kwargs)
6419{
6420 int err;
6421 char *file;
6422 u_int32_t flags = 0;
6423 static char* kwnames[] = { "file", "flags", NULL};
6424
6425 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "z|i:lsn_reset", kwnames,
6426 &file, &flags))
6427 return NULL;
6428 CHECK_ENV_NOT_CLOSED(self);
6429
6430 MYDB_BEGIN_ALLOW_THREADS;
6431 err = self->db_env->lsn_reset(self->db_env, file, flags);
6432 MYDB_END_ALLOW_THREADS;
6433 RETURN_IF_ERR();
6434 RETURN_NONE();
6435}
6436#endif /* DBVER >= 4.4 */
6437
Jesus Cea6557aac2010-03-22 14:22:26 +00006438
Jesus Cea6557aac2010-03-22 14:22:26 +00006439static PyObject*
6440DBEnv_stat_print(DBEnvObject* self, PyObject* args, PyObject *kwargs)
6441{
6442 int err;
6443 int flags=0;
6444 static char* kwnames[] = { "flags", NULL };
6445
6446 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:stat_print",
6447 kwnames, &flags))
6448 {
6449 return NULL;
6450 }
6451 CHECK_ENV_NOT_CLOSED(self);
6452 MYDB_BEGIN_ALLOW_THREADS;
6453 err = self->db_env->stat_print(self->db_env, flags);
6454 MYDB_END_ALLOW_THREADS;
6455 RETURN_IF_ERR();
6456 RETURN_NONE();
6457}
Jesus Cea6557aac2010-03-22 14:22:26 +00006458
6459
Gregory P. Smith76a82e82006-06-05 01:39:52 +00006460static PyObject*
6461DBEnv_log_stat(DBEnvObject* self, PyObject* args)
6462{
6463 int err;
6464 DB_LOG_STAT* statp = NULL;
6465 PyObject* d = NULL;
6466 u_int32_t flags = 0;
6467
6468 if (!PyArg_ParseTuple(args, "|i:log_stat", &flags))
6469 return NULL;
6470 CHECK_ENV_NOT_CLOSED(self);
6471
6472 MYDB_BEGIN_ALLOW_THREADS;
6473 err = self->db_env->log_stat(self->db_env, &statp, flags);
6474 MYDB_END_ALLOW_THREADS;
6475 RETURN_IF_ERR();
6476
6477 /* Turn the stat structure into a dictionary */
6478 d = PyDict_New();
6479 if (d == NULL) {
6480 if (statp)
6481 free(statp);
6482 return NULL;
6483 }
6484
6485#define MAKE_ENTRY(name) _addIntToDict(d, #name, statp->st_##name)
6486
6487 MAKE_ENTRY(magic);
6488 MAKE_ENTRY(version);
6489 MAKE_ENTRY(mode);
6490 MAKE_ENTRY(lg_bsize);
6491#if (DBVER >= 44)
6492 MAKE_ENTRY(lg_size);
6493 MAKE_ENTRY(record);
6494#endif
Gregory P. Smith76a82e82006-06-05 01:39:52 +00006495 MAKE_ENTRY(w_mbytes);
6496 MAKE_ENTRY(w_bytes);
6497 MAKE_ENTRY(wc_mbytes);
6498 MAKE_ENTRY(wc_bytes);
6499 MAKE_ENTRY(wcount);
6500 MAKE_ENTRY(wcount_fill);
6501#if (DBVER >= 44)
6502 MAKE_ENTRY(rcount);
6503#endif
6504 MAKE_ENTRY(scount);
6505 MAKE_ENTRY(cur_file);
6506 MAKE_ENTRY(cur_offset);
6507 MAKE_ENTRY(disk_file);
6508 MAKE_ENTRY(disk_offset);
6509 MAKE_ENTRY(maxcommitperflush);
6510 MAKE_ENTRY(mincommitperflush);
6511 MAKE_ENTRY(regsize);
6512 MAKE_ENTRY(region_wait);
6513 MAKE_ENTRY(region_nowait);
6514
6515#undef MAKE_ENTRY
6516 free(statp);
6517 return d;
6518} /* DBEnv_log_stat */
Gregory P. Smith76a82e82006-06-05 01:39:52 +00006519
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006520
Jesus Cea6557aac2010-03-22 14:22:26 +00006521static PyObject*
6522DBEnv_log_stat_print(DBEnvObject* self, PyObject* args, PyObject *kwargs)
6523{
6524 int err;
6525 int flags=0;
6526 static char* kwnames[] = { "flags", NULL };
6527
6528 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:log_stat_print",
6529 kwnames, &flags))
6530 {
6531 return NULL;
6532 }
6533 CHECK_ENV_NOT_CLOSED(self);
6534 MYDB_BEGIN_ALLOW_THREADS;
6535 err = self->db_env->log_stat_print(self->db_env, flags);
6536 MYDB_END_ALLOW_THREADS;
6537 RETURN_IF_ERR();
6538 RETURN_NONE();
6539}
Jesus Cea6557aac2010-03-22 14:22:26 +00006540
6541
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006542static PyObject*
6543DBEnv_lock_stat(DBEnvObject* self, PyObject* args)
6544{
6545 int err;
6546 DB_LOCK_STAT* sp;
6547 PyObject* d = NULL;
Martin v. Löwisb2c7aff2002-11-23 11:26:07 +00006548 u_int32_t flags = 0;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006549
6550 if (!PyArg_ParseTuple(args, "|i:lock_stat", &flags))
6551 return NULL;
6552 CHECK_ENV_NOT_CLOSED(self);
6553
6554 MYDB_BEGIN_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006555 err = self->db_env->lock_stat(self->db_env, &sp, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006556 MYDB_END_ALLOW_THREADS;
6557 RETURN_IF_ERR();
6558
6559 /* Turn the stat structure into a dictionary */
6560 d = PyDict_New();
6561 if (d == NULL) {
6562 free(sp);
6563 return NULL;
6564 }
6565
6566#define MAKE_ENTRY(name) _addIntToDict(d, #name, sp->st_##name)
6567
Jesus Ceaef9764f2008-05-13 18:45:46 +00006568 MAKE_ENTRY(id);
6569 MAKE_ENTRY(cur_maxid);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006570 MAKE_ENTRY(nmodes);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006571 MAKE_ENTRY(maxlocks);
6572 MAKE_ENTRY(maxlockers);
6573 MAKE_ENTRY(maxobjects);
6574 MAKE_ENTRY(nlocks);
6575 MAKE_ENTRY(maxnlocks);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006576 MAKE_ENTRY(nlockers);
6577 MAKE_ENTRY(maxnlockers);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006578 MAKE_ENTRY(nobjects);
6579 MAKE_ENTRY(maxnobjects);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006580 MAKE_ENTRY(nrequests);
6581 MAKE_ENTRY(nreleases);
Jesus Ceaef9764f2008-05-13 18:45:46 +00006582#if (DBVER >= 44)
6583 MAKE_ENTRY(nupgrade);
6584 MAKE_ENTRY(ndowngrade);
6585#endif
Gregory P. Smith29602d22006-01-24 09:46:48 +00006586#if (DBVER < 44)
6587 MAKE_ENTRY(nnowaits); /* these were renamed in 4.4 */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006588 MAKE_ENTRY(nconflicts);
Gregory P. Smith29602d22006-01-24 09:46:48 +00006589#else
6590 MAKE_ENTRY(lock_nowait);
6591 MAKE_ENTRY(lock_wait);
6592#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006593 MAKE_ENTRY(ndeadlocks);
Jesus Ceaef9764f2008-05-13 18:45:46 +00006594 MAKE_ENTRY(locktimeout);
6595 MAKE_ENTRY(txntimeout);
Jesus Ceaef9764f2008-05-13 18:45:46 +00006596 MAKE_ENTRY(nlocktimeouts);
6597 MAKE_ENTRY(ntxntimeouts);
Jesus Ceaef9764f2008-05-13 18:45:46 +00006598#if (DBVER >= 46)
6599 MAKE_ENTRY(objs_wait);
6600 MAKE_ENTRY(objs_nowait);
6601 MAKE_ENTRY(lockers_wait);
6602 MAKE_ENTRY(lockers_nowait);
Jesus Ceaca3939c2008-05-22 15:27:38 +00006603#if (DBVER >= 47)
6604 MAKE_ENTRY(lock_wait);
6605 MAKE_ENTRY(lock_nowait);
6606#else
Jesus Ceaef9764f2008-05-13 18:45:46 +00006607 MAKE_ENTRY(locks_wait);
6608 MAKE_ENTRY(locks_nowait);
Jesus Ceaca3939c2008-05-22 15:27:38 +00006609#endif
Jesus Ceaef9764f2008-05-13 18:45:46 +00006610 MAKE_ENTRY(hash_len);
6611#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006612 MAKE_ENTRY(regsize);
6613 MAKE_ENTRY(region_wait);
6614 MAKE_ENTRY(region_nowait);
6615
6616#undef MAKE_ENTRY
6617 free(sp);
6618 return d;
6619}
6620
Jesus Cea6557aac2010-03-22 14:22:26 +00006621static PyObject*
6622DBEnv_lock_stat_print(DBEnvObject* self, PyObject* args, PyObject *kwargs)
6623{
6624 int err;
6625 int flags=0;
6626 static char* kwnames[] = { "flags", NULL };
6627
6628 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:lock_stat_print",
6629 kwnames, &flags))
6630 {
6631 return NULL;
6632 }
6633 CHECK_ENV_NOT_CLOSED(self);
6634 MYDB_BEGIN_ALLOW_THREADS;
6635 err = self->db_env->lock_stat_print(self->db_env, flags);
6636 MYDB_END_ALLOW_THREADS;
6637 RETURN_IF_ERR();
6638 RETURN_NONE();
6639}
Jesus Cea6557aac2010-03-22 14:22:26 +00006640
6641
6642static PyObject*
6643DBEnv_log_cursor(DBEnvObject* self)
6644{
6645 int err;
6646 DB_LOGC* dblogc;
6647
6648 CHECK_ENV_NOT_CLOSED(self);
6649
6650 MYDB_BEGIN_ALLOW_THREADS;
6651 err = self->db_env->log_cursor(self->db_env, &dblogc, 0);
6652 MYDB_END_ALLOW_THREADS;
6653 RETURN_IF_ERR();
6654 return (PyObject*) newDBLogCursorObject(dblogc, self);
6655}
6656
6657
Jesus Ceaef9764f2008-05-13 18:45:46 +00006658static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00006659DBEnv_log_flush(DBEnvObject* self)
Jesus Ceaef9764f2008-05-13 18:45:46 +00006660{
6661 int err;
6662
Jesus Ceaef9764f2008-05-13 18:45:46 +00006663 CHECK_ENV_NOT_CLOSED(self);
6664
6665 MYDB_BEGIN_ALLOW_THREADS
6666 err = self->db_env->log_flush(self->db_env, NULL);
6667 MYDB_END_ALLOW_THREADS
6668
6669 RETURN_IF_ERR();
6670 RETURN_NONE();
6671}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006672
6673static PyObject*
Jesus Cea6557aac2010-03-22 14:22:26 +00006674DBEnv_log_file(DBEnvObject* self, PyObject* args)
6675{
6676 int err;
6677 DB_LSN lsn = {0, 0};
6678 int size = 20;
6679 char *name = NULL;
6680 PyObject *retval;
6681
6682 if (!PyArg_ParseTuple(args, "(ii):log_file", &lsn.file, &lsn.offset))
6683 return NULL;
6684
6685 CHECK_ENV_NOT_CLOSED(self);
6686
6687 do {
6688 name = malloc(size);
6689 if (!name) {
6690 PyErr_NoMemory();
6691 return NULL;
6692 }
6693 MYDB_BEGIN_ALLOW_THREADS;
6694 err = self->db_env->log_file(self->db_env, &lsn, name, size);
6695 MYDB_END_ALLOW_THREADS;
6696 if (err == EINVAL) {
6697 free(name);
6698 size *= 2;
6699 } else if (err) {
6700 free(name);
6701 RETURN_IF_ERR();
6702 assert(0); /* Unreachable... supposely */
6703 return NULL;
6704 }
6705/*
6706** If the final buffer we try is too small, we will
6707** get this exception:
6708** DBInvalidArgError:
6709** (22, 'Invalid argument -- DB_ENV->log_file: name buffer is too short')
6710*/
6711 } while ((err == EINVAL) && (size<(1<<17)));
6712
6713 RETURN_IF_ERR(); /* Maybe the size is not the problem */
6714
6715 retval = Py_BuildValue("s", name);
6716 free(name);
6717 return retval;
6718}
6719
6720
6721#if (DBVER >= 44)
6722static PyObject*
6723DBEnv_log_printf(DBEnvObject* self, PyObject* args, PyObject *kwargs)
6724{
6725 int err;
6726 char *string;
6727 PyObject *txnobj = NULL;
6728 DB_TXN *txn = NULL;
6729 static char* kwnames[] = {"string", "txn", NULL };
6730
6731 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|O:log_printf", kwnames,
6732 &string, &txnobj))
6733 return NULL;
6734
6735 CHECK_ENV_NOT_CLOSED(self);
6736
6737 if (!checkTxnObj(txnobj, &txn))
6738 return NULL;
6739
6740 /*
6741 ** Do not use the format string directly, to avoid attacks.
6742 */
6743 MYDB_BEGIN_ALLOW_THREADS;
6744 err = self->db_env->log_printf(self->db_env, txn, "%s", string);
6745 MYDB_END_ALLOW_THREADS;
6746
6747 RETURN_IF_ERR();
6748 RETURN_NONE();
6749}
6750#endif
6751
6752
6753static PyObject*
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006754DBEnv_log_archive(DBEnvObject* self, PyObject* args)
6755{
6756 int flags=0;
6757 int err;
Gregory P. Smith3dd20022006-06-05 00:31:01 +00006758 char **log_list = NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006759 PyObject* list;
6760 PyObject* item = NULL;
6761
6762 if (!PyArg_ParseTuple(args, "|i:log_archive", &flags))
6763 return NULL;
6764
6765 CHECK_ENV_NOT_CLOSED(self);
6766 MYDB_BEGIN_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006767 err = self->db_env->log_archive(self->db_env, &log_list, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006768 MYDB_END_ALLOW_THREADS;
6769 RETURN_IF_ERR();
6770
Gregory P. Smithbad47452006-06-05 00:33:35 +00006771 list = PyList_New(0);
6772 if (list == NULL) {
6773 if (log_list)
6774 free(log_list);
6775 return NULL;
6776 }
6777
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006778 if (log_list) {
Gregory P. Smith3dd20022006-06-05 00:31:01 +00006779 char **log_list_start;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006780 for (log_list_start = log_list; *log_list != NULL; ++log_list) {
Christian Heimes593daf52008-05-26 12:51:38 +00006781 item = PyBytes_FromString (*log_list);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006782 if (item == NULL) {
6783 Py_DECREF(list);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006784 list = NULL;
6785 break;
6786 }
Jesus Ceac5a11fa2008-07-23 11:38:42 +00006787 if (PyList_Append(list, item)) {
6788 Py_DECREF(list);
6789 list = NULL;
6790 Py_DECREF(item);
6791 break;
6792 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006793 Py_DECREF(item);
6794 }
6795 free(log_list_start);
6796 }
6797 return list;
6798}
6799
6800
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07006801#if (DBVER >= 52)
6802static PyObject*
6803DBEnv_repmgr_site(DBEnvObject* self, PyObject* args, PyObject *kwargs)
6804{
6805 int err;
6806 DB_SITE* site;
6807 char *host;
6808 u_int port;
6809 static char* kwnames[] = {"host", "port", NULL};
6810
6811 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "si:repmgr_site", kwnames,
6812 &host, &port))
6813 return NULL;
6814
6815 CHECK_ENV_NOT_CLOSED(self);
6816
6817 MYDB_BEGIN_ALLOW_THREADS;
6818 err = self->db_env->repmgr_site(self->db_env, host, port, &site, 0);
6819 MYDB_END_ALLOW_THREADS;
6820 RETURN_IF_ERR();
6821 return (PyObject*) newDBSiteObject(site, self);
6822}
6823
6824static PyObject*
6825DBEnv_repmgr_site_by_eid(DBEnvObject* self, PyObject* args, PyObject *kwargs)
6826{
6827 int err;
6828 DB_SITE* site;
6829 int eid;
6830 static char* kwnames[] = {"eid", NULL};
6831
6832 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i:repmgr_site_by_eid",
6833 kwnames, &eid))
6834 return NULL;
6835
6836 CHECK_ENV_NOT_CLOSED(self);
6837
6838 MYDB_BEGIN_ALLOW_THREADS;
6839 err = self->db_env->repmgr_site_by_eid(self->db_env, eid, &site);
6840 MYDB_END_ALLOW_THREADS;
6841 RETURN_IF_ERR();
6842 return (PyObject*) newDBSiteObject(site, self);
6843}
6844#endif
6845
6846
Jesus Cea6557aac2010-03-22 14:22:26 +00006847#if (DBVER >= 44)
6848static PyObject*
6849DBEnv_mutex_stat(DBEnvObject* self, PyObject* args)
6850{
6851 int err;
6852 DB_MUTEX_STAT* statp = NULL;
6853 PyObject* d = NULL;
6854 u_int32_t flags = 0;
6855
6856 if (!PyArg_ParseTuple(args, "|i:mutex_stat", &flags))
6857 return NULL;
6858 CHECK_ENV_NOT_CLOSED(self);
6859
6860 MYDB_BEGIN_ALLOW_THREADS;
6861 err = self->db_env->mutex_stat(self->db_env, &statp, flags);
6862 MYDB_END_ALLOW_THREADS;
6863 RETURN_IF_ERR();
6864
6865 /* Turn the stat structure into a dictionary */
6866 d = PyDict_New();
6867 if (d == NULL) {
6868 if (statp)
6869 free(statp);
6870 return NULL;
6871 }
6872
6873#define MAKE_ENTRY(name) _addIntToDict(d, #name, statp->st_##name)
6874
6875 MAKE_ENTRY(mutex_align);
6876 MAKE_ENTRY(mutex_tas_spins);
6877 MAKE_ENTRY(mutex_cnt);
6878 MAKE_ENTRY(mutex_free);
6879 MAKE_ENTRY(mutex_inuse);
6880 MAKE_ENTRY(mutex_inuse_max);
6881 MAKE_ENTRY(regsize);
6882 MAKE_ENTRY(region_wait);
6883 MAKE_ENTRY(region_nowait);
6884
6885#undef MAKE_ENTRY
6886 free(statp);
6887 return d;
6888}
6889#endif
6890
6891
6892#if (DBVER >= 44)
6893static PyObject*
6894DBEnv_mutex_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:mutex_stat_print",
6901 kwnames, &flags))
6902 {
6903 return NULL;
6904 }
6905 CHECK_ENV_NOT_CLOSED(self);
6906 MYDB_BEGIN_ALLOW_THREADS;
6907 err = self->db_env->mutex_stat_print(self->db_env, flags);
6908 MYDB_END_ALLOW_THREADS;
6909 RETURN_IF_ERR();
6910 RETURN_NONE();
6911}
6912#endif
6913
6914
Jesus Cea6557aac2010-03-22 14:22:26 +00006915static PyObject*
6916DBEnv_txn_stat_print(DBEnvObject* self, PyObject* args, PyObject *kwargs)
6917{
6918 int err;
6919 int flags=0;
6920 static char* kwnames[] = { "flags", NULL };
6921
6922 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:stat_print",
6923 kwnames, &flags))
6924 {
6925 return NULL;
6926 }
6927
6928 CHECK_ENV_NOT_CLOSED(self);
6929
6930 MYDB_BEGIN_ALLOW_THREADS;
6931 err = self->db_env->txn_stat_print(self->db_env, flags);
6932 MYDB_END_ALLOW_THREADS;
6933 RETURN_IF_ERR();
6934 RETURN_NONE();
6935}
Jesus Cea6557aac2010-03-22 14:22:26 +00006936
6937
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006938static PyObject*
6939DBEnv_txn_stat(DBEnvObject* self, PyObject* args)
6940{
6941 int err;
6942 DB_TXN_STAT* sp;
6943 PyObject* d = NULL;
Martin v. Löwisb2c7aff2002-11-23 11:26:07 +00006944 u_int32_t flags=0;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006945
6946 if (!PyArg_ParseTuple(args, "|i:txn_stat", &flags))
6947 return NULL;
6948 CHECK_ENV_NOT_CLOSED(self);
6949
6950 MYDB_BEGIN_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006951 err = self->db_env->txn_stat(self->db_env, &sp, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006952 MYDB_END_ALLOW_THREADS;
6953 RETURN_IF_ERR();
6954
6955 /* Turn the stat structure into a dictionary */
6956 d = PyDict_New();
6957 if (d == NULL) {
6958 free(sp);
6959 return NULL;
6960 }
6961
Jesus Ceaef9764f2008-05-13 18:45:46 +00006962#define MAKE_ENTRY(name) _addIntToDict(d, #name, sp->st_##name)
6963#define MAKE_TIME_T_ENTRY(name) _addTimeTToDict(d, #name, sp->st_##name)
6964#define MAKE_DB_LSN_ENTRY(name) _addDB_lsnToDict(d, #name, sp->st_##name)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006965
Jesus Ceaef9764f2008-05-13 18:45:46 +00006966 MAKE_DB_LSN_ENTRY(last_ckp);
Kristján Valur Jónssonbd77c032007-04-26 15:24:54 +00006967 MAKE_TIME_T_ENTRY(time_ckp);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006968 MAKE_ENTRY(last_txnid);
6969 MAKE_ENTRY(maxtxns);
6970 MAKE_ENTRY(nactive);
6971 MAKE_ENTRY(maxnactive);
Jesus Ceaef9764f2008-05-13 18:45:46 +00006972#if (DBVER >= 45)
6973 MAKE_ENTRY(nsnapshot);
6974 MAKE_ENTRY(maxnsnapshot);
6975#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006976 MAKE_ENTRY(nbegins);
6977 MAKE_ENTRY(naborts);
6978 MAKE_ENTRY(ncommits);
Jesus Ceaef9764f2008-05-13 18:45:46 +00006979 MAKE_ENTRY(nrestores);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006980 MAKE_ENTRY(regsize);
6981 MAKE_ENTRY(region_wait);
6982 MAKE_ENTRY(region_nowait);
6983
Jesus Ceaef9764f2008-05-13 18:45:46 +00006984#undef MAKE_DB_LSN_ENTRY
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006985#undef MAKE_ENTRY
Kristján Valur Jónssonbd77c032007-04-26 15:24:54 +00006986#undef MAKE_TIME_T_ENTRY
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006987 free(sp);
6988 return d;
6989}
6990
6991
6992static PyObject*
6993DBEnv_set_get_returns_none(DBEnvObject* self, PyObject* args)
6994{
6995 int flags=0;
Gregory P. Smith455d46f2003-07-09 04:45:59 +00006996 int oldValue=0;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006997
6998 if (!PyArg_ParseTuple(args,"i:set_get_returns_none", &flags))
6999 return NULL;
7000 CHECK_ENV_NOT_CLOSED(self);
7001
Gregory P. Smith455d46f2003-07-09 04:45:59 +00007002 if (self->moduleFlags.getReturnsNone)
7003 ++oldValue;
7004 if (self->moduleFlags.cursorSetReturnsNone)
7005 ++oldValue;
7006 self->moduleFlags.getReturnsNone = (flags >= 1);
7007 self->moduleFlags.cursorSetReturnsNone = (flags >= 2);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007008 return NUMBER_FromLong(oldValue);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00007009}
7010
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007011static PyObject*
7012DBEnv_get_private(DBEnvObject* self)
7013{
7014 /* We can give out the private field even if dbenv is closed */
Jesus Cea4907d272008-08-31 14:00:51 +00007015 Py_INCREF(self->private_obj);
7016 return self->private_obj;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007017}
7018
7019static PyObject*
Jesus Cea4907d272008-08-31 14:00:51 +00007020DBEnv_set_private(DBEnvObject* self, PyObject* private_obj)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007021{
7022 /* We can set the private field even if dbenv is closed */
Jesus Cea4907d272008-08-31 14:00:51 +00007023 Py_INCREF(private_obj);
Serhiy Storchaka763a61c2016-04-10 18:05:12 +03007024 Py_SETREF(self->private_obj, private_obj);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007025 RETURN_NONE();
7026}
7027
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07007028#if (DBVER >= 47)
7029static PyObject*
7030DBEnv_set_intermediate_dir_mode(DBEnvObject* self, PyObject* args)
7031{
7032 int err;
7033 const char *mode;
7034
7035 if (!PyArg_ParseTuple(args,"s:set_intermediate_dir_mode", &mode))
7036 return NULL;
7037
7038 CHECK_ENV_NOT_CLOSED(self);
7039
7040 MYDB_BEGIN_ALLOW_THREADS;
7041 err = self->db_env->set_intermediate_dir_mode(self->db_env, mode);
7042 MYDB_END_ALLOW_THREADS;
7043 RETURN_IF_ERR();
7044 RETURN_NONE();
7045}
7046
7047static PyObject*
7048DBEnv_get_intermediate_dir_mode(DBEnvObject* self)
7049{
7050 int err;
7051 const char *mode;
7052
7053 CHECK_ENV_NOT_CLOSED(self);
7054
7055 MYDB_BEGIN_ALLOW_THREADS;
7056 err = self->db_env->get_intermediate_dir_mode(self->db_env, &mode);
7057 MYDB_END_ALLOW_THREADS;
7058 RETURN_IF_ERR();
7059 return Py_BuildValue("s", mode);
7060}
7061#endif
7062
7063#if (DBVER < 47)
7064static PyObject*
7065DBEnv_set_intermediate_dir(DBEnvObject* self, PyObject* args)
7066{
7067 int err;
7068 int mode;
7069 u_int32_t flags;
7070
7071 if (!PyArg_ParseTuple(args, "iI:set_intermediate_dir", &mode, &flags))
7072 return NULL;
7073
7074 CHECK_ENV_NOT_CLOSED(self);
7075
7076 MYDB_BEGIN_ALLOW_THREADS;
7077 err = self->db_env->set_intermediate_dir(self->db_env, mode, flags);
7078 MYDB_END_ALLOW_THREADS;
7079 RETURN_IF_ERR();
7080 RETURN_NONE();
7081}
7082#endif
7083
7084static PyObject*
7085DBEnv_get_open_flags(DBEnvObject* self)
7086{
7087 int err;
7088 unsigned int flags;
7089
7090 CHECK_ENV_NOT_CLOSED(self);
7091
7092 MYDB_BEGIN_ALLOW_THREADS;
7093 err = self->db_env->get_open_flags(self->db_env, &flags);
7094 MYDB_END_ALLOW_THREADS;
7095 RETURN_IF_ERR();
7096 return NUMBER_FromLong(flags);
7097}
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007098
Matthias Klose54cc5392010-03-15 12:46:18 +00007099#if (DBVER < 48)
Jesus Ceaef9764f2008-05-13 18:45:46 +00007100static PyObject*
Jesus Ceaca3939c2008-05-22 15:27:38 +00007101DBEnv_set_rpc_server(DBEnvObject* self, PyObject* args, PyObject* kwargs)
7102{
7103 int err;
7104 char *host;
7105 long cl_timeout=0, sv_timeout=0;
7106
7107 static char* kwnames[] = { "host", "cl_timeout", "sv_timeout", NULL};
7108
7109 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|ll:set_rpc_server", kwnames,
7110 &host, &cl_timeout, &sv_timeout))
7111 return NULL;
7112 CHECK_ENV_NOT_CLOSED(self);
7113
7114 MYDB_BEGIN_ALLOW_THREADS;
7115 err = self->db_env->set_rpc_server(self->db_env, NULL, host, cl_timeout,
7116 sv_timeout, 0);
7117 MYDB_END_ALLOW_THREADS;
7118 RETURN_IF_ERR();
7119 RETURN_NONE();
7120}
Matthias Klose54cc5392010-03-15 12:46:18 +00007121#endif
Jesus Ceaca3939c2008-05-22 15:27:38 +00007122
Jesus Cea6557aac2010-03-22 14:22:26 +00007123static PyObject*
7124DBEnv_set_mp_max_openfd(DBEnvObject* self, PyObject* args)
7125{
7126 int err;
7127 int maxopenfd;
7128
7129 if (!PyArg_ParseTuple(args, "i:set_mp_max_openfd", &maxopenfd)) {
7130 return NULL;
7131 }
7132 CHECK_ENV_NOT_CLOSED(self);
7133 MYDB_BEGIN_ALLOW_THREADS;
7134 err = self->db_env->set_mp_max_openfd(self->db_env, maxopenfd);
7135 MYDB_END_ALLOW_THREADS;
7136 RETURN_IF_ERR();
7137 RETURN_NONE();
7138}
7139
7140static PyObject*
7141DBEnv_get_mp_max_openfd(DBEnvObject* self)
7142{
7143 int err;
7144 int maxopenfd;
7145
7146 CHECK_ENV_NOT_CLOSED(self);
7147
7148 MYDB_BEGIN_ALLOW_THREADS;
7149 err = self->db_env->get_mp_max_openfd(self->db_env, &maxopenfd);
7150 MYDB_END_ALLOW_THREADS;
7151 RETURN_IF_ERR();
7152 return NUMBER_FromLong(maxopenfd);
7153}
7154
7155
7156static PyObject*
7157DBEnv_set_mp_max_write(DBEnvObject* self, PyObject* args)
7158{
7159 int err;
7160 int maxwrite, maxwrite_sleep;
7161
7162 if (!PyArg_ParseTuple(args, "ii:set_mp_max_write", &maxwrite,
7163 &maxwrite_sleep)) {
7164 return NULL;
7165 }
7166 CHECK_ENV_NOT_CLOSED(self);
7167 MYDB_BEGIN_ALLOW_THREADS;
7168 err = self->db_env->set_mp_max_write(self->db_env, maxwrite,
7169 maxwrite_sleep);
7170 MYDB_END_ALLOW_THREADS;
7171 RETURN_IF_ERR();
7172 RETURN_NONE();
7173}
7174
7175static PyObject*
7176DBEnv_get_mp_max_write(DBEnvObject* self)
7177{
7178 int err;
7179 int maxwrite;
7180#if (DBVER >= 46)
7181 db_timeout_t maxwrite_sleep;
7182#else
7183 int maxwrite_sleep;
7184#endif
7185
7186 CHECK_ENV_NOT_CLOSED(self);
7187
7188 MYDB_BEGIN_ALLOW_THREADS;
7189 err = self->db_env->get_mp_max_write(self->db_env, &maxwrite,
7190 &maxwrite_sleep);
7191 MYDB_END_ALLOW_THREADS;
7192 RETURN_IF_ERR();
7193
7194 return Py_BuildValue("(ii)", maxwrite, (int)maxwrite_sleep);
7195}
Jesus Cea6557aac2010-03-22 14:22:26 +00007196
7197
Jesus Ceaca3939c2008-05-22 15:27:38 +00007198static PyObject*
Jesus Ceaef9764f2008-05-13 18:45:46 +00007199DBEnv_set_verbose(DBEnvObject* self, PyObject* args)
7200{
7201 int err;
7202 int which, onoff;
7203
7204 if (!PyArg_ParseTuple(args, "ii:set_verbose", &which, &onoff)) {
7205 return NULL;
7206 }
7207 CHECK_ENV_NOT_CLOSED(self);
7208 MYDB_BEGIN_ALLOW_THREADS;
7209 err = self->db_env->set_verbose(self->db_env, which, onoff);
7210 MYDB_END_ALLOW_THREADS;
7211 RETURN_IF_ERR();
7212 RETURN_NONE();
7213}
7214
Jesus Ceaef9764f2008-05-13 18:45:46 +00007215static PyObject*
7216DBEnv_get_verbose(DBEnvObject* self, PyObject* args)
7217{
7218 int err;
7219 int which;
7220 int verbose;
7221
7222 if (!PyArg_ParseTuple(args, "i:get_verbose", &which)) {
7223 return NULL;
7224 }
7225 CHECK_ENV_NOT_CLOSED(self);
7226 MYDB_BEGIN_ALLOW_THREADS;
7227 err = self->db_env->get_verbose(self->db_env, which, &verbose);
7228 MYDB_END_ALLOW_THREADS;
7229 RETURN_IF_ERR();
7230 return PyBool_FromLong(verbose);
7231}
Jesus Ceaef9764f2008-05-13 18:45:46 +00007232
7233#if (DBVER >= 45)
7234static void
7235_dbenv_event_notifyCallback(DB_ENV* db_env, u_int32_t event, void *event_info)
7236{
7237 DBEnvObject *dbenv;
7238 PyObject* callback;
7239 PyObject* args;
7240 PyObject* result = NULL;
7241
7242 MYDB_BEGIN_BLOCK_THREADS;
7243 dbenv = (DBEnvObject *)db_env->app_private;
7244 callback = dbenv->event_notifyCallback;
7245 if (callback) {
7246 if (event == DB_EVENT_REP_NEWMASTER) {
7247 args = Py_BuildValue("(Oii)", dbenv, event, *((int *)event_info));
7248 } else {
7249 args = Py_BuildValue("(OiO)", dbenv, event, Py_None);
7250 }
7251 if (args) {
7252 result = PyEval_CallObject(callback, args);
7253 }
7254 if ((!args) || (!result)) {
7255 PyErr_Print();
7256 }
7257 Py_XDECREF(args);
7258 Py_XDECREF(result);
7259 }
7260 MYDB_END_BLOCK_THREADS;
7261}
7262#endif
7263
7264#if (DBVER >= 45)
7265static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007266DBEnv_set_event_notify(DBEnvObject* self, PyObject* notifyFunc)
Jesus Ceaef9764f2008-05-13 18:45:46 +00007267{
7268 int err;
Jesus Ceaef9764f2008-05-13 18:45:46 +00007269
7270 CHECK_ENV_NOT_CLOSED(self);
7271
7272 if (!PyCallable_Check(notifyFunc)) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00007273 makeTypeError("Callable", notifyFunc);
7274 return NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00007275 }
7276
Jesus Ceaef9764f2008-05-13 18:45:46 +00007277 Py_INCREF(notifyFunc);
Serhiy Storchakabc62af12016-04-06 09:51:18 +03007278 Py_XSETREF(self->event_notifyCallback, notifyFunc);
Jesus Ceaef9764f2008-05-13 18:45:46 +00007279
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007280 /* This is to workaround a problem with un-initialized threads (see
7281 comment in DB_associate) */
7282#ifdef WITH_THREAD
7283 PyEval_InitThreads();
7284#endif
7285
Jesus Ceaef9764f2008-05-13 18:45:46 +00007286 MYDB_BEGIN_ALLOW_THREADS;
7287 err = self->db_env->set_event_notify(self->db_env, _dbenv_event_notifyCallback);
7288 MYDB_END_ALLOW_THREADS;
7289
7290 if (err) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00007291 Py_DECREF(notifyFunc);
7292 self->event_notifyCallback = NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00007293 }
7294
7295 RETURN_IF_ERR();
7296 RETURN_NONE();
7297}
7298#endif
7299
7300
7301/* --------------------------------------------------------------------- */
7302/* REPLICATION METHODS: Base Replication */
7303
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007304
7305static PyObject*
7306DBEnv_rep_process_message(DBEnvObject* self, PyObject* args)
7307{
7308 int err;
7309 PyObject *control_py, *rec_py;
7310 DBT control, rec;
7311 int envid;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007312 DB_LSN lsn;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007313
7314 if (!PyArg_ParseTuple(args, "OOi:rep_process_message", &control_py,
7315 &rec_py, &envid))
7316 return NULL;
7317 CHECK_ENV_NOT_CLOSED(self);
7318
7319 if (!make_dbt(control_py, &control))
7320 return NULL;
7321 if (!make_dbt(rec_py, &rec))
7322 return NULL;
7323
7324 MYDB_BEGIN_ALLOW_THREADS;
7325#if (DBVER >= 46)
7326 err = self->db_env->rep_process_message(self->db_env, &control, &rec,
7327 envid, &lsn);
7328#else
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007329 err = self->db_env->rep_process_message(self->db_env, &control, &rec,
7330 &envid, &lsn);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007331#endif
7332 MYDB_END_ALLOW_THREADS;
7333 switch (err) {
7334 case DB_REP_NEWMASTER :
7335 return Py_BuildValue("(iO)", envid, Py_None);
7336 break;
7337
7338 case DB_REP_DUPMASTER :
7339 case DB_REP_HOLDELECTION :
7340#if (DBVER >= 44)
7341 case DB_REP_IGNORE :
7342 case DB_REP_JOIN_FAILURE :
7343#endif
7344 return Py_BuildValue("(iO)", err, Py_None);
7345 break;
7346 case DB_REP_NEWSITE :
Jesus Cea4907d272008-08-31 14:00:51 +00007347 {
7348 PyObject *tmp, *r;
7349
7350 if (!(tmp = PyBytes_FromStringAndSize(rec.data, rec.size))) {
7351 return NULL;
7352 }
7353
7354 r = Py_BuildValue("(iO)", err, tmp);
7355 Py_DECREF(tmp);
7356 return r;
7357 break;
7358 }
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007359 case DB_REP_NOTPERM :
7360 case DB_REP_ISPERM :
7361 return Py_BuildValue("(i(ll))", err, lsn.file, lsn.offset);
7362 break;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007363 }
7364 RETURN_IF_ERR();
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07007365 return PyTuple_Pack(2, Py_None, Py_None);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007366}
7367
7368static int
7369_DBEnv_rep_transportCallback(DB_ENV* db_env, const DBT* control, const DBT* rec,
7370 const DB_LSN *lsn, int envid, u_int32_t flags)
7371{
7372 DBEnvObject *dbenv;
7373 PyObject* rep_transport;
7374 PyObject* args;
Jesus Cea4907d272008-08-31 14:00:51 +00007375 PyObject *a, *b;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007376 PyObject* result = NULL;
7377 int ret=0;
7378
7379 MYDB_BEGIN_BLOCK_THREADS;
7380 dbenv = (DBEnvObject *)db_env->app_private;
7381 rep_transport = dbenv->rep_transport;
7382
Jesus Cea4907d272008-08-31 14:00:51 +00007383 /*
7384 ** The errors in 'a' or 'b' are detected in "Py_BuildValue".
7385 */
7386 a = PyBytes_FromStringAndSize(control->data, control->size);
7387 b = PyBytes_FromStringAndSize(rec->data, rec->size);
7388
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007389 args = Py_BuildValue(
Jesus Cea4907d272008-08-31 14:00:51 +00007390 "(OOO(ll)iI)",
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007391 dbenv,
Jesus Cea4907d272008-08-31 14:00:51 +00007392 a, b,
7393 lsn->file, lsn->offset, envid, flags);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007394 if (args) {
7395 result = PyEval_CallObject(rep_transport, args);
7396 }
7397
7398 if ((!args) || (!result)) {
7399 PyErr_Print();
7400 ret = -1;
7401 }
Jesus Cea4907d272008-08-31 14:00:51 +00007402 Py_XDECREF(a);
7403 Py_XDECREF(b);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007404 Py_XDECREF(args);
7405 Py_XDECREF(result);
7406 MYDB_END_BLOCK_THREADS;
7407 return ret;
7408}
7409
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007410static PyObject*
7411DBEnv_rep_set_transport(DBEnvObject* self, PyObject* args)
7412{
7413 int err;
7414 int envid;
7415 PyObject *rep_transport;
7416
7417 if (!PyArg_ParseTuple(args, "iO:rep_set_transport", &envid, &rep_transport))
7418 return NULL;
7419 CHECK_ENV_NOT_CLOSED(self);
7420 if (!PyCallable_Check(rep_transport)) {
7421 makeTypeError("Callable", rep_transport);
7422 return NULL;
7423 }
7424
7425 MYDB_BEGIN_ALLOW_THREADS;
7426#if (DBVER >=45)
7427 err = self->db_env->rep_set_transport(self->db_env, envid,
7428 &_DBEnv_rep_transportCallback);
7429#else
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007430 err = self->db_env->set_rep_transport(self->db_env, envid,
7431 &_DBEnv_rep_transportCallback);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007432#endif
7433 MYDB_END_ALLOW_THREADS;
7434 RETURN_IF_ERR();
7435
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007436 Py_INCREF(rep_transport);
Serhiy Storchaka763a61c2016-04-10 18:05:12 +03007437 Py_SETREF(self->rep_transport, rep_transport);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007438 RETURN_NONE();
7439}
7440
7441#if (DBVER >= 47)
7442static PyObject*
7443DBEnv_rep_set_request(DBEnvObject* self, PyObject* args)
7444{
7445 int err;
7446 unsigned int minimum, maximum;
7447
7448 if (!PyArg_ParseTuple(args,"II:rep_set_request", &minimum, &maximum))
7449 return NULL;
7450 CHECK_ENV_NOT_CLOSED(self);
7451
7452 MYDB_BEGIN_ALLOW_THREADS;
7453 err = self->db_env->rep_set_request(self->db_env, minimum, maximum);
7454 MYDB_END_ALLOW_THREADS;
7455 RETURN_IF_ERR();
7456 RETURN_NONE();
7457}
7458
7459static PyObject*
7460DBEnv_rep_get_request(DBEnvObject* self)
7461{
7462 int err;
7463 u_int32_t minimum, maximum;
7464
7465 CHECK_ENV_NOT_CLOSED(self);
7466 MYDB_BEGIN_ALLOW_THREADS;
7467 err = self->db_env->rep_get_request(self->db_env, &minimum, &maximum);
7468 MYDB_END_ALLOW_THREADS;
7469 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007470 return Py_BuildValue("II", minimum, maximum);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007471}
7472#endif
7473
7474#if (DBVER >= 45)
7475static PyObject*
7476DBEnv_rep_set_limit(DBEnvObject* self, PyObject* args)
7477{
7478 int err;
7479 int limit;
7480
7481 if (!PyArg_ParseTuple(args,"i:rep_set_limit", &limit))
7482 return NULL;
7483 CHECK_ENV_NOT_CLOSED(self);
7484
7485 MYDB_BEGIN_ALLOW_THREADS;
7486 err = self->db_env->rep_set_limit(self->db_env, 0, limit);
7487 MYDB_END_ALLOW_THREADS;
7488 RETURN_IF_ERR();
7489 RETURN_NONE();
7490}
7491
7492static PyObject*
7493DBEnv_rep_get_limit(DBEnvObject* self)
7494{
7495 int err;
7496 u_int32_t gbytes, bytes;
7497
7498 CHECK_ENV_NOT_CLOSED(self);
7499 MYDB_BEGIN_ALLOW_THREADS;
7500 err = self->db_env->rep_get_limit(self->db_env, &gbytes, &bytes);
7501 MYDB_END_ALLOW_THREADS;
7502 RETURN_IF_ERR();
7503 return NUMBER_FromLong(bytes);
7504}
7505#endif
7506
7507#if (DBVER >= 44)
7508static PyObject*
7509DBEnv_rep_set_config(DBEnvObject* self, PyObject* args)
7510{
7511 int err;
7512 int which;
7513 int onoff;
7514
7515 if (!PyArg_ParseTuple(args,"ii:rep_set_config", &which, &onoff))
7516 return NULL;
7517 CHECK_ENV_NOT_CLOSED(self);
7518
7519 MYDB_BEGIN_ALLOW_THREADS;
7520 err = self->db_env->rep_set_config(self->db_env, which, onoff);
7521 MYDB_END_ALLOW_THREADS;
7522 RETURN_IF_ERR();
7523 RETURN_NONE();
7524}
7525
7526static PyObject*
7527DBEnv_rep_get_config(DBEnvObject* self, PyObject* args)
7528{
7529 int err;
7530 int which;
7531 int onoff;
7532
7533 if (!PyArg_ParseTuple(args, "i:rep_get_config", &which)) {
7534 return NULL;
7535 }
7536 CHECK_ENV_NOT_CLOSED(self);
7537 MYDB_BEGIN_ALLOW_THREADS;
7538 err = self->db_env->rep_get_config(self->db_env, which, &onoff);
7539 MYDB_END_ALLOW_THREADS;
7540 RETURN_IF_ERR();
7541 return PyBool_FromLong(onoff);
7542}
7543#endif
7544
7545#if (DBVER >= 46)
7546static PyObject*
7547DBEnv_rep_elect(DBEnvObject* self, PyObject* args)
7548{
7549 int err;
7550 u_int32_t nsites, nvotes;
7551
7552 if (!PyArg_ParseTuple(args, "II:rep_elect", &nsites, &nvotes)) {
7553 return NULL;
7554 }
7555 CHECK_ENV_NOT_CLOSED(self);
7556 MYDB_BEGIN_ALLOW_THREADS;
Jesus Cea2ab4a912012-01-16 23:57:34 +01007557 err = self->db_env->rep_elect(self->db_env, nsites, nvotes, 0);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007558 MYDB_END_ALLOW_THREADS;
7559 RETURN_IF_ERR();
7560 RETURN_NONE();
7561}
7562#endif
7563
7564static PyObject*
7565DBEnv_rep_start(DBEnvObject* self, PyObject* args, PyObject* kwargs)
7566{
7567 int err;
7568 PyObject *cdata_py = Py_None;
7569 DBT cdata;
7570 int flags;
7571 static char* kwnames[] = {"flags","cdata", NULL};
7572
7573 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
7574 "i|O:rep_start", kwnames, &flags, &cdata_py))
7575 {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00007576 return NULL;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007577 }
7578 CHECK_ENV_NOT_CLOSED(self);
7579
7580 if (!make_dbt(cdata_py, &cdata))
7581 return NULL;
7582
7583 MYDB_BEGIN_ALLOW_THREADS;
7584 err = self->db_env->rep_start(self->db_env, cdata.size ? &cdata : NULL,
7585 flags);
7586 MYDB_END_ALLOW_THREADS;
7587 RETURN_IF_ERR();
7588 RETURN_NONE();
7589}
7590
7591#if (DBVER >= 44)
7592static PyObject*
7593DBEnv_rep_sync(DBEnvObject* self)
7594{
7595 int err;
7596
7597 CHECK_ENV_NOT_CLOSED(self);
7598 MYDB_BEGIN_ALLOW_THREADS;
7599 err = self->db_env->rep_sync(self->db_env, 0);
7600 MYDB_END_ALLOW_THREADS;
7601 RETURN_IF_ERR();
7602 RETURN_NONE();
7603}
7604#endif
7605
7606
Jesus Ceaef9764f2008-05-13 18:45:46 +00007607#if (DBVER >= 45)
7608static PyObject*
7609DBEnv_rep_set_nsites(DBEnvObject* self, PyObject* args)
7610{
7611 int err;
7612 int nsites;
7613
7614 if (!PyArg_ParseTuple(args, "i:rep_set_nsites", &nsites)) {
7615 return NULL;
7616 }
7617 CHECK_ENV_NOT_CLOSED(self);
7618 MYDB_BEGIN_ALLOW_THREADS;
7619 err = self->db_env->rep_set_nsites(self->db_env, nsites);
7620 MYDB_END_ALLOW_THREADS;
7621 RETURN_IF_ERR();
7622 RETURN_NONE();
7623}
7624
7625static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007626DBEnv_rep_get_nsites(DBEnvObject* self)
Jesus Ceaef9764f2008-05-13 18:45:46 +00007627{
7628 int err;
Jesus Ceaca3939c2008-05-22 15:27:38 +00007629#if (DBVER >= 47)
7630 u_int32_t nsites;
7631#else
Jesus Ceaef9764f2008-05-13 18:45:46 +00007632 int nsites;
Jesus Ceaca3939c2008-05-22 15:27:38 +00007633#endif
Jesus Ceaef9764f2008-05-13 18:45:46 +00007634
Jesus Ceaef9764f2008-05-13 18:45:46 +00007635 CHECK_ENV_NOT_CLOSED(self);
7636 MYDB_BEGIN_ALLOW_THREADS;
7637 err = self->db_env->rep_get_nsites(self->db_env, &nsites);
7638 MYDB_END_ALLOW_THREADS;
7639 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007640 return NUMBER_FromLong(nsites);
Jesus Ceaef9764f2008-05-13 18:45:46 +00007641}
7642
7643static PyObject*
7644DBEnv_rep_set_priority(DBEnvObject* self, PyObject* args)
7645{
7646 int err;
7647 int priority;
7648
7649 if (!PyArg_ParseTuple(args, "i:rep_set_priority", &priority)) {
7650 return NULL;
7651 }
7652 CHECK_ENV_NOT_CLOSED(self);
7653 MYDB_BEGIN_ALLOW_THREADS;
7654 err = self->db_env->rep_set_priority(self->db_env, priority);
7655 MYDB_END_ALLOW_THREADS;
7656 RETURN_IF_ERR();
7657 RETURN_NONE();
7658}
7659
7660static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007661DBEnv_rep_get_priority(DBEnvObject* self)
Jesus Ceaef9764f2008-05-13 18:45:46 +00007662{
7663 int err;
Jesus Ceaca3939c2008-05-22 15:27:38 +00007664#if (DBVER >= 47)
7665 u_int32_t priority;
7666#else
Jesus Ceaef9764f2008-05-13 18:45:46 +00007667 int priority;
Jesus Ceaca3939c2008-05-22 15:27:38 +00007668#endif
Jesus Ceaef9764f2008-05-13 18:45:46 +00007669
Jesus Ceaef9764f2008-05-13 18:45:46 +00007670 CHECK_ENV_NOT_CLOSED(self);
7671 MYDB_BEGIN_ALLOW_THREADS;
7672 err = self->db_env->rep_get_priority(self->db_env, &priority);
7673 MYDB_END_ALLOW_THREADS;
7674 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007675 return NUMBER_FromLong(priority);
Jesus Ceaef9764f2008-05-13 18:45:46 +00007676}
7677
7678static PyObject*
7679DBEnv_rep_set_timeout(DBEnvObject* self, PyObject* args)
7680{
7681 int err;
7682 int which, timeout;
7683
7684 if (!PyArg_ParseTuple(args, "ii:rep_set_timeout", &which, &timeout)) {
7685 return NULL;
7686 }
7687 CHECK_ENV_NOT_CLOSED(self);
7688 MYDB_BEGIN_ALLOW_THREADS;
7689 err = self->db_env->rep_set_timeout(self->db_env, which, timeout);
7690 MYDB_END_ALLOW_THREADS;
7691 RETURN_IF_ERR();
7692 RETURN_NONE();
7693}
7694
7695static PyObject*
7696DBEnv_rep_get_timeout(DBEnvObject* self, PyObject* args)
7697{
7698 int err;
7699 int which;
7700 u_int32_t timeout;
7701
7702 if (!PyArg_ParseTuple(args, "i:rep_get_timeout", &which)) {
7703 return NULL;
7704 }
7705 CHECK_ENV_NOT_CLOSED(self);
7706 MYDB_BEGIN_ALLOW_THREADS;
7707 err = self->db_env->rep_get_timeout(self->db_env, which, &timeout);
7708 MYDB_END_ALLOW_THREADS;
7709 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007710 return NUMBER_FromLong(timeout);
Jesus Ceaef9764f2008-05-13 18:45:46 +00007711}
7712#endif
7713
Jesus Cea6557aac2010-03-22 14:22:26 +00007714
7715#if (DBVER >= 47)
7716static PyObject*
7717DBEnv_rep_set_clockskew(DBEnvObject* self, PyObject* args)
7718{
7719 int err;
7720 unsigned int fast, slow;
7721
Jesus Cea6557aac2010-03-22 14:22:26 +00007722 if (!PyArg_ParseTuple(args,"II:rep_set_clockskew", &fast, &slow))
7723 return NULL;
Jesus Cea6557aac2010-03-22 14:22:26 +00007724
7725 CHECK_ENV_NOT_CLOSED(self);
7726
7727 MYDB_BEGIN_ALLOW_THREADS;
7728 err = self->db_env->rep_set_clockskew(self->db_env, fast, slow);
7729 MYDB_END_ALLOW_THREADS;
7730 RETURN_IF_ERR();
7731 RETURN_NONE();
7732}
7733
7734static PyObject*
7735DBEnv_rep_get_clockskew(DBEnvObject* self)
7736{
7737 int err;
7738 unsigned int fast, slow;
7739
7740 CHECK_ENV_NOT_CLOSED(self);
7741 MYDB_BEGIN_ALLOW_THREADS;
7742 err = self->db_env->rep_get_clockskew(self->db_env, &fast, &slow);
7743 MYDB_END_ALLOW_THREADS;
7744 RETURN_IF_ERR();
Jesus Cea6557aac2010-03-22 14:22:26 +00007745 return Py_BuildValue("(II)", fast, slow);
Jesus Cea6557aac2010-03-22 14:22:26 +00007746}
7747#endif
7748
Jesus Cea6557aac2010-03-22 14:22:26 +00007749static PyObject*
7750DBEnv_rep_stat_print(DBEnvObject* self, PyObject* args, PyObject *kwargs)
7751{
7752 int err;
7753 int flags=0;
7754 static char* kwnames[] = { "flags", NULL };
7755
7756 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:rep_stat_print",
7757 kwnames, &flags))
7758 {
7759 return NULL;
7760 }
7761 CHECK_ENV_NOT_CLOSED(self);
7762 MYDB_BEGIN_ALLOW_THREADS;
7763 err = self->db_env->rep_stat_print(self->db_env, flags);
7764 MYDB_END_ALLOW_THREADS;
7765 RETURN_IF_ERR();
7766 RETURN_NONE();
7767}
Jesus Cea6557aac2010-03-22 14:22:26 +00007768
7769static PyObject*
7770DBEnv_rep_stat(DBEnvObject* self, PyObject* args, PyObject *kwargs)
7771{
7772 int err;
7773 int flags=0;
7774 DB_REP_STAT *statp;
7775 PyObject *stats;
7776 static char* kwnames[] = { "flags", NULL };
7777
7778 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:rep_stat",
7779 kwnames, &flags))
7780 {
7781 return NULL;
7782 }
7783 CHECK_ENV_NOT_CLOSED(self);
7784 MYDB_BEGIN_ALLOW_THREADS;
7785 err = self->db_env->rep_stat(self->db_env, &statp, flags);
7786 MYDB_END_ALLOW_THREADS;
7787 RETURN_IF_ERR();
7788
7789 stats=PyDict_New();
7790 if (stats == NULL) {
7791 free(statp);
7792 return NULL;
7793 }
7794
7795#define MAKE_ENTRY(name) _addIntToDict(stats, #name, statp->st_##name)
7796#define MAKE_DB_LSN_ENTRY(name) _addDB_lsnToDict(stats , #name, statp->st_##name)
7797
7798#if (DBVER >= 44)
7799 MAKE_ENTRY(bulk_fills);
7800 MAKE_ENTRY(bulk_overflows);
7801 MAKE_ENTRY(bulk_records);
7802 MAKE_ENTRY(bulk_transfers);
7803 MAKE_ENTRY(client_rerequests);
7804 MAKE_ENTRY(client_svc_miss);
7805 MAKE_ENTRY(client_svc_req);
7806#endif
7807 MAKE_ENTRY(dupmasters);
Jesus Cea6557aac2010-03-22 14:22:26 +00007808 MAKE_ENTRY(egen);
7809 MAKE_ENTRY(election_nvotes);
7810 MAKE_ENTRY(startup_complete);
7811 MAKE_ENTRY(pg_duplicated);
7812 MAKE_ENTRY(pg_records);
7813 MAKE_ENTRY(pg_requested);
7814 MAKE_ENTRY(next_pg);
7815 MAKE_ENTRY(waiting_pg);
Jesus Cea6557aac2010-03-22 14:22:26 +00007816 MAKE_ENTRY(election_cur_winner);
7817 MAKE_ENTRY(election_gen);
7818 MAKE_DB_LSN_ENTRY(election_lsn);
7819 MAKE_ENTRY(election_nsites);
7820 MAKE_ENTRY(election_priority);
7821#if (DBVER >= 44)
7822 MAKE_ENTRY(election_sec);
7823 MAKE_ENTRY(election_usec);
7824#endif
7825 MAKE_ENTRY(election_status);
7826 MAKE_ENTRY(election_tiebreaker);
7827 MAKE_ENTRY(election_votes);
7828 MAKE_ENTRY(elections);
7829 MAKE_ENTRY(elections_won);
7830 MAKE_ENTRY(env_id);
7831 MAKE_ENTRY(env_priority);
7832 MAKE_ENTRY(gen);
7833 MAKE_ENTRY(log_duplicated);
7834 MAKE_ENTRY(log_queued);
7835 MAKE_ENTRY(log_queued_max);
7836 MAKE_ENTRY(log_queued_total);
7837 MAKE_ENTRY(log_records);
7838 MAKE_ENTRY(log_requested);
7839 MAKE_ENTRY(master);
7840 MAKE_ENTRY(master_changes);
7841#if (DBVER >= 47)
7842 MAKE_ENTRY(max_lease_sec);
7843 MAKE_ENTRY(max_lease_usec);
7844 MAKE_DB_LSN_ENTRY(max_perm_lsn);
7845#endif
7846 MAKE_ENTRY(msgs_badgen);
7847 MAKE_ENTRY(msgs_processed);
7848 MAKE_ENTRY(msgs_recover);
7849 MAKE_ENTRY(msgs_send_failures);
7850 MAKE_ENTRY(msgs_sent);
7851 MAKE_ENTRY(newsites);
7852 MAKE_DB_LSN_ENTRY(next_lsn);
7853 MAKE_ENTRY(nsites);
7854 MAKE_ENTRY(nthrottles);
7855 MAKE_ENTRY(outdated);
7856#if (DBVER >= 46)
7857 MAKE_ENTRY(startsync_delayed);
7858#endif
7859 MAKE_ENTRY(status);
7860 MAKE_ENTRY(txns_applied);
7861 MAKE_DB_LSN_ENTRY(waiting_lsn);
7862
7863#undef MAKE_DB_LSN_ENTRY
7864#undef MAKE_ENTRY
7865
7866 free(statp);
7867 return stats;
7868}
7869
Jesus Ceaef9764f2008-05-13 18:45:46 +00007870/* --------------------------------------------------------------------- */
7871/* REPLICATION METHODS: Replication Manager */
7872
7873#if (DBVER >= 45)
7874static PyObject*
7875DBEnv_repmgr_start(DBEnvObject* self, PyObject* args, PyObject*
7876 kwargs)
7877{
7878 int err;
7879 int nthreads, flags;
7880 static char* kwnames[] = {"nthreads","flags", NULL};
7881
7882 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
7883 "ii:repmgr_start", kwnames, &nthreads, &flags))
7884 {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00007885 return NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00007886 }
7887 CHECK_ENV_NOT_CLOSED(self);
7888 MYDB_BEGIN_ALLOW_THREADS;
7889 err = self->db_env->repmgr_start(self->db_env, nthreads, flags);
7890 MYDB_END_ALLOW_THREADS;
7891 RETURN_IF_ERR();
7892 RETURN_NONE();
7893}
7894
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07007895#if (DBVER < 52)
Jesus Ceaef9764f2008-05-13 18:45:46 +00007896static PyObject*
7897DBEnv_repmgr_set_local_site(DBEnvObject* self, PyObject* args, PyObject*
7898 kwargs)
7899{
7900 int err;
7901 char *host;
7902 int port;
7903 int flags = 0;
7904 static char* kwnames[] = {"host", "port", "flags", NULL};
7905
7906 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
7907 "si|i:repmgr_set_local_site", kwnames, &host, &port, &flags))
7908 {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00007909 return NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00007910 }
7911 CHECK_ENV_NOT_CLOSED(self);
7912 MYDB_BEGIN_ALLOW_THREADS;
7913 err = self->db_env->repmgr_set_local_site(self->db_env, host, port, flags);
7914 MYDB_END_ALLOW_THREADS;
7915 RETURN_IF_ERR();
7916 RETURN_NONE();
7917}
7918
7919static PyObject*
7920DBEnv_repmgr_add_remote_site(DBEnvObject* self, PyObject* args, PyObject*
7921 kwargs)
7922{
7923 int err;
7924 char *host;
7925 int port;
7926 int flags = 0;
7927 int eidp;
7928 static char* kwnames[] = {"host", "port", "flags", NULL};
7929
7930 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
7931 "si|i:repmgr_add_remote_site", kwnames, &host, &port, &flags))
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_add_remote_site(self->db_env, host, port, &eidp, flags);
7938 MYDB_END_ALLOW_THREADS;
7939 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007940 return NUMBER_FromLong(eidp);
Jesus Ceaef9764f2008-05-13 18:45:46 +00007941}
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07007942#endif
Jesus Ceaef9764f2008-05-13 18:45:46 +00007943
7944static PyObject*
7945DBEnv_repmgr_set_ack_policy(DBEnvObject* self, PyObject* args)
7946{
7947 int err;
7948 int ack_policy;
7949
7950 if (!PyArg_ParseTuple(args, "i:repmgr_set_ack_policy", &ack_policy))
7951 {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00007952 return NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00007953 }
7954 CHECK_ENV_NOT_CLOSED(self);
7955 MYDB_BEGIN_ALLOW_THREADS;
7956 err = self->db_env->repmgr_set_ack_policy(self->db_env, ack_policy);
7957 MYDB_END_ALLOW_THREADS;
7958 RETURN_IF_ERR();
7959 RETURN_NONE();
7960}
7961
7962static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007963DBEnv_repmgr_get_ack_policy(DBEnvObject* self)
Jesus Ceaef9764f2008-05-13 18:45:46 +00007964{
7965 int err;
7966 int ack_policy;
7967
Jesus Ceaef9764f2008-05-13 18:45:46 +00007968 CHECK_ENV_NOT_CLOSED(self);
7969 MYDB_BEGIN_ALLOW_THREADS;
7970 err = self->db_env->repmgr_get_ack_policy(self->db_env, &ack_policy);
7971 MYDB_END_ALLOW_THREADS;
7972 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007973 return NUMBER_FromLong(ack_policy);
Jesus Ceaef9764f2008-05-13 18:45:46 +00007974}
7975
7976static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007977DBEnv_repmgr_site_list(DBEnvObject* self)
Jesus Ceaef9764f2008-05-13 18:45:46 +00007978{
7979 int err;
7980 unsigned int countp;
7981 DB_REPMGR_SITE *listp;
7982 PyObject *stats, *key, *tuple;
7983
Jesus Ceaef9764f2008-05-13 18:45:46 +00007984 CHECK_ENV_NOT_CLOSED(self);
7985 MYDB_BEGIN_ALLOW_THREADS;
7986 err = self->db_env->repmgr_site_list(self->db_env, &countp, &listp);
7987 MYDB_END_ALLOW_THREADS;
7988 RETURN_IF_ERR();
7989
7990 stats=PyDict_New();
7991 if (stats == NULL) {
7992 free(listp);
7993 return NULL;
7994 }
7995
7996 for(;countp--;) {
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007997 key=NUMBER_FromLong(listp[countp].eid);
Jesus Ceaef9764f2008-05-13 18:45:46 +00007998 if(!key) {
7999 Py_DECREF(stats);
8000 free(listp);
8001 return NULL;
8002 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00008003 tuple=Py_BuildValue("(sII)", listp[countp].host,
8004 listp[countp].port, listp[countp].status);
Jesus Ceaef9764f2008-05-13 18:45:46 +00008005 if(!tuple) {
8006 Py_DECREF(key);
8007 Py_DECREF(stats);
8008 free(listp);
8009 return NULL;
8010 }
8011 if(PyDict_SetItem(stats, key, tuple)) {
8012 Py_DECREF(key);
8013 Py_DECREF(tuple);
8014 Py_DECREF(stats);
8015 free(listp);
8016 return NULL;
8017 }
Florent Xiclunae7901c52010-03-01 20:45:01 +00008018 Py_DECREF(key);
8019 Py_DECREF(tuple);
Jesus Ceaef9764f2008-05-13 18:45:46 +00008020 }
8021 free(listp);
8022 return stats;
8023}
8024#endif
8025
8026#if (DBVER >= 46)
8027static PyObject*
8028DBEnv_repmgr_stat_print(DBEnvObject* self, PyObject* args, PyObject *kwargs)
8029{
8030 int err;
8031 int flags=0;
8032 static char* kwnames[] = { "flags", NULL };
8033
8034 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:repmgr_stat_print",
8035 kwnames, &flags))
8036 {
8037 return NULL;
8038 }
8039 CHECK_ENV_NOT_CLOSED(self);
8040 MYDB_BEGIN_ALLOW_THREADS;
8041 err = self->db_env->repmgr_stat_print(self->db_env, flags);
8042 MYDB_END_ALLOW_THREADS;
8043 RETURN_IF_ERR();
8044 RETURN_NONE();
8045}
8046
8047static PyObject*
8048DBEnv_repmgr_stat(DBEnvObject* self, PyObject* args, PyObject *kwargs)
8049{
8050 int err;
8051 int flags=0;
8052 DB_REPMGR_STAT *statp;
8053 PyObject *stats;
8054 static char* kwnames[] = { "flags", NULL };
8055
8056 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:repmgr_stat",
8057 kwnames, &flags))
8058 {
8059 return NULL;
8060 }
8061 CHECK_ENV_NOT_CLOSED(self);
8062 MYDB_BEGIN_ALLOW_THREADS;
8063 err = self->db_env->repmgr_stat(self->db_env, &statp, flags);
8064 MYDB_END_ALLOW_THREADS;
8065 RETURN_IF_ERR();
8066
8067 stats=PyDict_New();
8068 if (stats == NULL) {
8069 free(statp);
8070 return NULL;
8071 }
8072
8073#define MAKE_ENTRY(name) _addIntToDict(stats, #name, statp->st_##name)
8074
8075 MAKE_ENTRY(perm_failed);
8076 MAKE_ENTRY(msgs_queued);
8077 MAKE_ENTRY(msgs_dropped);
8078 MAKE_ENTRY(connection_drop);
8079 MAKE_ENTRY(connect_fail);
8080
8081#undef MAKE_ENTRY
8082
8083 free(statp);
8084 return stats;
8085}
8086#endif
8087
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008088
8089/* --------------------------------------------------------------------- */
8090/* DBTxn methods */
8091
8092
Jesus Ceaef9764f2008-05-13 18:45:46 +00008093static void _close_transaction_cursors(DBTxnObject* txn)
8094{
8095 PyObject *dummy;
8096
8097 while(txn->children_cursors) {
8098 PyErr_Warn(PyExc_RuntimeWarning,
8099 "Must close cursors before resolving a transaction.");
8100 dummy=DBC_close_internal(txn->children_cursors);
8101 Py_XDECREF(dummy);
8102 }
8103}
8104
8105static void _promote_transaction_dbs_and_sequences(DBTxnObject *txn)
8106{
8107 DBObject *db;
Jesus Ceaef9764f2008-05-13 18:45:46 +00008108 DBSequenceObject *dbs;
Jesus Ceaef9764f2008-05-13 18:45:46 +00008109
8110 while (txn->children_dbs) {
8111 db=txn->children_dbs;
8112 EXTRACT_FROM_DOUBLE_LINKED_LIST_TXN(db);
8113 if (txn->parent_txn) {
8114 INSERT_IN_DOUBLE_LINKED_LIST_TXN(txn->parent_txn->children_dbs,db);
8115 db->txn=txn->parent_txn;
8116 } else {
8117 /* The db is already linked to its environment,
8118 ** so nothing to do.
8119 */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00008120 db->txn=NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00008121 }
8122 }
8123
Jesus Ceaef9764f2008-05-13 18:45:46 +00008124 while (txn->children_sequences) {
8125 dbs=txn->children_sequences;
8126 EXTRACT_FROM_DOUBLE_LINKED_LIST_TXN(dbs);
8127 if (txn->parent_txn) {
8128 INSERT_IN_DOUBLE_LINKED_LIST_TXN(txn->parent_txn->children_sequences,dbs);
8129 dbs->txn=txn->parent_txn;
8130 } else {
8131 /* The sequence is already linked to its
8132 ** parent db. Nothing to do.
8133 */
8134 dbs->txn=NULL;
8135 }
8136 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00008137}
8138
8139
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008140static PyObject*
8141DBTxn_commit(DBTxnObject* self, PyObject* args)
8142{
8143 int flags=0, err;
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008144 DB_TXN *txn;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008145
8146 if (!PyArg_ParseTuple(args, "|i:commit", &flags))
8147 return NULL;
8148
Jesus Ceaef9764f2008-05-13 18:45:46 +00008149 _close_transaction_cursors(self);
8150
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008151 if (!self->txn) {
Thomas Woutersb3153832006-03-08 01:47:19 +00008152 PyObject *t = Py_BuildValue("(is)", 0, "DBTxn must not be used "
Jesus Ceaef9764f2008-05-13 18:45:46 +00008153 "after txn_commit, txn_abort "
8154 "or txn_discard");
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008155 if (t) {
8156 PyErr_SetObject(DBError, t);
8157 Py_DECREF(t);
8158 }
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008159 return NULL;
8160 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00008161 self->flag_prepare=0;
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008162 txn = self->txn;
8163 self->txn = NULL; /* this DB_TXN is no longer valid after this call */
Jesus Ceaef9764f2008-05-13 18:45:46 +00008164
8165 EXTRACT_FROM_DOUBLE_LINKED_LIST(self);
8166
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008167 MYDB_BEGIN_ALLOW_THREADS;
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008168 err = txn->commit(txn, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008169 MYDB_END_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00008170
8171 _promote_transaction_dbs_and_sequences(self);
8172
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008173 RETURN_IF_ERR();
8174 RETURN_NONE();
8175}
8176
8177static PyObject*
8178DBTxn_prepare(DBTxnObject* self, PyObject* args)
8179{
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008180 int err;
8181 char* gid=NULL;
8182 int gid_size=0;
8183
8184 if (!PyArg_ParseTuple(args, "s#:prepare", &gid, &gid_size))
8185 return NULL;
8186
Matthias Klose54cc5392010-03-15 12:46:18 +00008187 if (gid_size != DB_GID_SIZE) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008188 PyErr_SetString(PyExc_TypeError,
Matthias Klose54cc5392010-03-15 12:46:18 +00008189 "gid must be DB_GID_SIZE bytes long");
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008190 return NULL;
8191 }
8192
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008193 if (!self->txn) {
Thomas Woutersb3153832006-03-08 01:47:19 +00008194 PyObject *t = Py_BuildValue("(is)", 0,"DBTxn must not be used "
Jesus Ceaef9764f2008-05-13 18:45:46 +00008195 "after txn_commit, txn_abort "
8196 "or txn_discard");
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008197 if (t) {
8198 PyErr_SetObject(DBError, t);
8199 Py_DECREF(t);
8200 }
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008201 return NULL;
8202 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00008203 self->flag_prepare=1; /* Prepare state */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008204 MYDB_BEGIN_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008205 err = self->txn->prepare(self->txn, (u_int8_t*)gid);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008206 MYDB_END_ALLOW_THREADS;
8207 RETURN_IF_ERR();
8208 RETURN_NONE();
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008209}
8210
8211
8212static PyObject*
Jesus Ceaef9764f2008-05-13 18:45:46 +00008213DBTxn_abort_discard_internal(DBTxnObject* self, int discard)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008214{
Jesus Ceaef9764f2008-05-13 18:45:46 +00008215 PyObject *dummy;
8216 int err=0;
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008217 DB_TXN *txn;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008218
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008219 if (!self->txn) {
Thomas Woutersb3153832006-03-08 01:47:19 +00008220 PyObject *t = Py_BuildValue("(is)", 0, "DBTxn must not be used "
Jesus Ceaef9764f2008-05-13 18:45:46 +00008221 "after txn_commit, txn_abort "
8222 "or txn_discard");
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008223 if (t) {
8224 PyErr_SetObject(DBError, t);
8225 Py_DECREF(t);
8226 }
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008227 return NULL;
8228 }
8229 txn = self->txn;
8230 self->txn = NULL; /* this DB_TXN is no longer valid after this call */
Jesus Ceaef9764f2008-05-13 18:45:46 +00008231
8232 _close_transaction_cursors(self);
Jesus Ceaef9764f2008-05-13 18:45:46 +00008233 while (self->children_sequences) {
8234 dummy=DBSequence_close_internal(self->children_sequences,0,0);
8235 Py_XDECREF(dummy);
8236 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00008237 while (self->children_dbs) {
Jesus Cea5cd5f122008-09-23 18:54:08 +00008238 dummy=DB_close_internal(self->children_dbs, 0, 0);
Jesus Ceaef9764f2008-05-13 18:45:46 +00008239 Py_XDECREF(dummy);
8240 }
8241
8242 EXTRACT_FROM_DOUBLE_LINKED_LIST(self);
8243
8244 MYDB_BEGIN_ALLOW_THREADS;
8245 if (discard) {
8246 assert(!self->flag_prepare);
Jesus Ceaef9764f2008-05-13 18:45:46 +00008247 err = txn->discard(txn,0);
Jesus Ceaef9764f2008-05-13 18:45:46 +00008248 } else {
8249 /*
8250 ** If the transaction is in the "prepare" or "recover" state,
8251 ** we better do not implicitly abort it.
8252 */
8253 if (!self->flag_prepare) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00008254 err = txn->abort(txn);
Jesus Ceaef9764f2008-05-13 18:45:46 +00008255 }
8256 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008257 MYDB_END_ALLOW_THREADS;
8258 RETURN_IF_ERR();
8259 RETURN_NONE();
8260}
8261
Jesus Ceaef9764f2008-05-13 18:45:46 +00008262static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008263DBTxn_abort(DBTxnObject* self)
Jesus Ceaef9764f2008-05-13 18:45:46 +00008264{
Jesus Ceaef9764f2008-05-13 18:45:46 +00008265 self->flag_prepare=0;
8266 _close_transaction_cursors(self);
8267
8268 return DBTxn_abort_discard_internal(self,0);
8269}
8270
8271static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008272DBTxn_discard(DBTxnObject* self)
Jesus Ceaef9764f2008-05-13 18:45:46 +00008273{
Jesus Ceaef9764f2008-05-13 18:45:46 +00008274 self->flag_prepare=0;
8275 _close_transaction_cursors(self);
8276
8277 return DBTxn_abort_discard_internal(self,1);
8278}
8279
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008280
8281static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008282DBTxn_id(DBTxnObject* self)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008283{
8284 int id;
8285
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008286 if (!self->txn) {
Thomas Woutersb3153832006-03-08 01:47:19 +00008287 PyObject *t = Py_BuildValue("(is)", 0, "DBTxn must not be used "
Jesus Ceaef9764f2008-05-13 18:45:46 +00008288 "after txn_commit, txn_abort "
8289 "or txn_discard");
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008290 if (t) {
8291 PyErr_SetObject(DBError, t);
8292 Py_DECREF(t);
8293 }
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008294 return NULL;
8295 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008296 MYDB_BEGIN_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008297 id = self->txn->id(self->txn);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008298 MYDB_END_ALLOW_THREADS;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008299 return NUMBER_FromLong(id);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008300}
8301
Jesus Cea6557aac2010-03-22 14:22:26 +00008302
8303static PyObject*
8304DBTxn_set_timeout(DBTxnObject* self, PyObject* args, PyObject* kwargs)
8305{
8306 int err;
8307 u_int32_t flags=0;
8308 u_int32_t timeout = 0;
8309 static char* kwnames[] = { "timeout", "flags", NULL };
8310
8311 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ii:set_timeout", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00008312 &timeout, &flags)) {
8313 return NULL;
Jesus Cea6557aac2010-03-22 14:22:26 +00008314 }
8315
8316 MYDB_BEGIN_ALLOW_THREADS;
8317 err = self->txn->set_timeout(self->txn, (db_timeout_t)timeout, flags);
8318 MYDB_END_ALLOW_THREADS;
8319
8320 RETURN_IF_ERR();
8321 RETURN_NONE();
8322}
8323
8324
8325#if (DBVER >= 44)
8326static PyObject*
8327DBTxn_set_name(DBTxnObject* self, PyObject* args)
8328{
8329 int err;
8330 const char *name;
8331
8332 if (!PyArg_ParseTuple(args, "s:set_name", &name))
8333 return NULL;
8334
8335 MYDB_BEGIN_ALLOW_THREADS;
8336 err = self->txn->set_name(self->txn, name);
8337 MYDB_END_ALLOW_THREADS;
8338
8339 RETURN_IF_ERR();
8340 RETURN_NONE();
8341}
8342#endif
8343
8344
8345#if (DBVER >= 44)
8346static PyObject*
8347DBTxn_get_name(DBTxnObject* self)
8348{
8349 int err;
8350 const char *name;
8351
8352 MYDB_BEGIN_ALLOW_THREADS;
8353 err = self->txn->get_name(self->txn, &name);
8354 MYDB_END_ALLOW_THREADS;
8355
8356 RETURN_IF_ERR();
8357#if (PY_VERSION_HEX < 0x03000000)
8358 if (!name) {
8359 return PyString_FromString("");
8360 }
8361 return PyString_FromString(name);
8362#else
8363 if (!name) {
8364 return PyUnicode_FromString("");
8365 }
8366 return PyUnicode_FromString(name);
8367#endif
8368}
8369#endif
8370
8371
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008372/* --------------------------------------------------------------------- */
8373/* DBSequence methods */
8374
8375
8376static PyObject*
Jesus Ceaef9764f2008-05-13 18:45:46 +00008377DBSequence_close_internal(DBSequenceObject* self, int flags, int do_not_close)
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008378{
Jesus Ceaef9764f2008-05-13 18:45:46 +00008379 int err=0;
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008380
Jesus Ceaef9764f2008-05-13 18:45:46 +00008381 if (self->sequence!=NULL) {
8382 EXTRACT_FROM_DOUBLE_LINKED_LIST(self);
8383 if (self->txn) {
8384 EXTRACT_FROM_DOUBLE_LINKED_LIST_TXN(self);
8385 self->txn=NULL;
8386 }
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008387
Jesus Cea5cd5f122008-09-23 18:54:08 +00008388 /*
8389 ** "do_not_close" is used to dispose all related objects in the
8390 ** tree, without actually releasing the "root" object.
8391 ** This is done, for example, because function calls like
8392 ** "DBSequence.remove()" implicitly close the underlying handle. So
8393 ** the handle doesn't need to be closed, but related objects
8394 ** must be cleaned up.
8395 */
Jesus Ceaef9764f2008-05-13 18:45:46 +00008396 if (!do_not_close) {
8397 MYDB_BEGIN_ALLOW_THREADS
8398 err = self->sequence->close(self->sequence, flags);
8399 MYDB_END_ALLOW_THREADS
8400 }
8401 self->sequence = NULL;
8402
8403 RETURN_IF_ERR();
8404 }
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008405
8406 RETURN_NONE();
8407}
8408
8409static PyObject*
Jesus Ceaef9764f2008-05-13 18:45:46 +00008410DBSequence_close(DBSequenceObject* self, PyObject* args)
8411{
8412 int flags=0;
8413 if (!PyArg_ParseTuple(args,"|i:close", &flags))
8414 return NULL;
8415
8416 return DBSequence_close_internal(self,flags,0);
8417}
8418
8419static PyObject*
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008420DBSequence_get(DBSequenceObject* self, PyObject* args, PyObject* kwargs)
8421{
8422 int err, flags = 0;
8423 int delta = 1;
8424 db_seq_t value;
8425 PyObject *txnobj = NULL;
8426 DB_TXN *txn = NULL;
8427 static char* kwnames[] = {"delta", "txn", "flags", NULL };
8428 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|iOi:get", kwnames, &delta, &txnobj, &flags))
8429 return NULL;
8430 CHECK_SEQUENCE_NOT_CLOSED(self)
8431
8432 if (!checkTxnObj(txnobj, &txn))
8433 return NULL;
8434
8435 MYDB_BEGIN_ALLOW_THREADS
8436 err = self->sequence->get(self->sequence, txn, delta, &value, flags);
8437 MYDB_END_ALLOW_THREADS
8438
8439 RETURN_IF_ERR();
8440 return PyLong_FromLongLong(value);
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008441}
8442
8443static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008444DBSequence_get_dbp(DBSequenceObject* self)
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008445{
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008446 CHECK_SEQUENCE_NOT_CLOSED(self)
8447 Py_INCREF(self->mydb);
8448 return (PyObject* )self->mydb;
8449}
8450
8451static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008452DBSequence_get_key(DBSequenceObject* self)
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008453{
8454 int err;
8455 DBT key;
Neal Norwitz088beae2007-10-12 03:01:54 +00008456 PyObject *retval = NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00008457
Gregory P. Smithe70be5c2007-10-06 07:48:10 +00008458 key.flags = DB_DBT_MALLOC;
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008459 CHECK_SEQUENCE_NOT_CLOSED(self)
8460 MYDB_BEGIN_ALLOW_THREADS
8461 err = self->sequence->get_key(self->sequence, &key);
8462 MYDB_END_ALLOW_THREADS
8463
Gregory P. Smithe70be5c2007-10-06 07:48:10 +00008464 if (!err)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008465 retval = Build_PyString(key.data, key.size);
Gregory P. Smithe70be5c2007-10-06 07:48:10 +00008466
8467 FREE_DBT(key);
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008468 RETURN_IF_ERR();
8469
Gregory P. Smithe70be5c2007-10-06 07:48:10 +00008470 return retval;
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008471}
8472
8473static PyObject*
Jesus Cea6557aac2010-03-22 14:22:26 +00008474DBSequence_initial_value(DBSequenceObject* self, PyObject* args)
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008475{
8476 int err;
Jesus Ceaef9764f2008-05-13 18:45:46 +00008477 PY_LONG_LONG value;
8478 db_seq_t value2;
Jesus Cea6557aac2010-03-22 14:22:26 +00008479 if (!PyArg_ParseTuple(args,"L:initial_value", &value))
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008480 return NULL;
8481 CHECK_SEQUENCE_NOT_CLOSED(self)
8482
Jesus Ceaef9764f2008-05-13 18:45:46 +00008483 value2=value; /* If truncation, compiler should show a warning */
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008484 MYDB_BEGIN_ALLOW_THREADS
Jesus Ceaef9764f2008-05-13 18:45:46 +00008485 err = self->sequence->initial_value(self->sequence, value2);
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008486 MYDB_END_ALLOW_THREADS
8487
8488 RETURN_IF_ERR();
8489
8490 RETURN_NONE();
8491}
8492
8493static PyObject*
8494DBSequence_open(DBSequenceObject* self, PyObject* args, PyObject* kwargs)
8495{
8496 int err, flags = 0;
8497 PyObject* keyobj;
8498 PyObject *txnobj = NULL;
8499 DB_TXN *txn = NULL;
8500 DBT key;
8501
8502 static char* kwnames[] = {"key", "txn", "flags", NULL };
Neal Norwitzdd2a6bf2006-06-06 07:23:01 +00008503 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|Oi:open", kwnames, &keyobj, &txnobj, &flags))
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008504 return NULL;
8505
8506 if (!checkTxnObj(txnobj, &txn))
8507 return NULL;
8508
8509 if (!make_key_dbt(self->mydb, keyobj, &key, NULL))
8510 return NULL;
8511
8512 MYDB_BEGIN_ALLOW_THREADS
8513 err = self->sequence->open(self->sequence, txn, &key, flags);
8514 MYDB_END_ALLOW_THREADS
8515
Jesus Ceaac25fab2008-09-03 17:50:32 +00008516 FREE_DBT(key);
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008517 RETURN_IF_ERR();
8518
Jesus Ceaef9764f2008-05-13 18:45:46 +00008519 if (txn) {
8520 INSERT_IN_DOUBLE_LINKED_LIST_TXN(((DBTxnObject *)txnobj)->children_sequences,self);
8521 self->txn=(DBTxnObject *)txnobj;
8522 }
8523
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008524 RETURN_NONE();
8525}
8526
8527static PyObject*
8528DBSequence_remove(DBSequenceObject* self, PyObject* args, PyObject* kwargs)
8529{
Jesus Ceaef9764f2008-05-13 18:45:46 +00008530 PyObject *dummy;
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008531 int err, flags = 0;
8532 PyObject *txnobj = NULL;
8533 DB_TXN *txn = NULL;
8534
8535 static char* kwnames[] = {"txn", "flags", NULL };
Neal Norwitzdd2a6bf2006-06-06 07:23:01 +00008536 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Oi:remove", kwnames, &txnobj, &flags))
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008537 return NULL;
8538
8539 if (!checkTxnObj(txnobj, &txn))
8540 return NULL;
8541
8542 CHECK_SEQUENCE_NOT_CLOSED(self)
8543
8544 MYDB_BEGIN_ALLOW_THREADS
8545 err = self->sequence->remove(self->sequence, txn, flags);
8546 MYDB_END_ALLOW_THREADS
8547
Jesus Ceaef9764f2008-05-13 18:45:46 +00008548 dummy=DBSequence_close_internal(self,flags,1);
8549 Py_XDECREF(dummy);
8550
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008551 RETURN_IF_ERR();
8552 RETURN_NONE();
8553}
8554
8555static PyObject*
8556DBSequence_set_cachesize(DBSequenceObject* self, PyObject* args)
8557{
8558 int err, size;
Neal Norwitzdd2a6bf2006-06-06 07:23:01 +00008559 if (!PyArg_ParseTuple(args,"i:set_cachesize", &size))
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008560 return NULL;
8561 CHECK_SEQUENCE_NOT_CLOSED(self)
8562
8563 MYDB_BEGIN_ALLOW_THREADS
8564 err = self->sequence->set_cachesize(self->sequence, size);
8565 MYDB_END_ALLOW_THREADS
8566
8567 RETURN_IF_ERR();
8568 RETURN_NONE();
8569}
8570
8571static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008572DBSequence_get_cachesize(DBSequenceObject* self)
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008573{
8574 int err, size;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008575
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008576 CHECK_SEQUENCE_NOT_CLOSED(self)
8577
8578 MYDB_BEGIN_ALLOW_THREADS
8579 err = self->sequence->get_cachesize(self->sequence, &size);
8580 MYDB_END_ALLOW_THREADS
8581
8582 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008583 return NUMBER_FromLong(size);
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008584}
8585
8586static PyObject*
8587DBSequence_set_flags(DBSequenceObject* self, PyObject* args)
8588{
8589 int err, flags = 0;
Neal Norwitzdd2a6bf2006-06-06 07:23:01 +00008590 if (!PyArg_ParseTuple(args,"i:set_flags", &flags))
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008591 return NULL;
8592 CHECK_SEQUENCE_NOT_CLOSED(self)
8593
8594 MYDB_BEGIN_ALLOW_THREADS
8595 err = self->sequence->set_flags(self->sequence, flags);
8596 MYDB_END_ALLOW_THREADS
8597
8598 RETURN_IF_ERR();
8599 RETURN_NONE();
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008600}
8601
8602static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008603DBSequence_get_flags(DBSequenceObject* self)
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008604{
8605 unsigned int flags;
8606 int err;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008607
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008608 CHECK_SEQUENCE_NOT_CLOSED(self)
8609
8610 MYDB_BEGIN_ALLOW_THREADS
8611 err = self->sequence->get_flags(self->sequence, &flags);
8612 MYDB_END_ALLOW_THREADS
8613
8614 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008615 return NUMBER_FromLong((int)flags);
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008616}
8617
8618static PyObject*
8619DBSequence_set_range(DBSequenceObject* self, PyObject* args)
8620{
8621 int err;
Jesus Ceaef9764f2008-05-13 18:45:46 +00008622 PY_LONG_LONG min, max;
8623 db_seq_t min2, max2;
Tim Petersbb21b2c2006-06-06 15:50:17 +00008624 if (!PyArg_ParseTuple(args,"(LL):set_range", &min, &max))
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008625 return NULL;
8626 CHECK_SEQUENCE_NOT_CLOSED(self)
8627
Jesus Ceaef9764f2008-05-13 18:45:46 +00008628 min2=min; /* If truncation, compiler should show a warning */
8629 max2=max;
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008630 MYDB_BEGIN_ALLOW_THREADS
Jesus Ceaef9764f2008-05-13 18:45:46 +00008631 err = self->sequence->set_range(self->sequence, min2, max2);
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008632 MYDB_END_ALLOW_THREADS
8633
8634 RETURN_IF_ERR();
8635 RETURN_NONE();
8636}
8637
8638static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008639DBSequence_get_range(DBSequenceObject* self)
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008640{
8641 int err;
Jesus Ceaef9764f2008-05-13 18:45:46 +00008642 PY_LONG_LONG min, max;
8643 db_seq_t min2, max2;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008644
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008645 CHECK_SEQUENCE_NOT_CLOSED(self)
8646
8647 MYDB_BEGIN_ALLOW_THREADS
Jesus Ceaef9764f2008-05-13 18:45:46 +00008648 err = self->sequence->get_range(self->sequence, &min2, &max2);
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008649 MYDB_END_ALLOW_THREADS
8650
8651 RETURN_IF_ERR();
Jesus Ceaef9764f2008-05-13 18:45:46 +00008652 min=min2; /* If truncation, compiler should show a warning */
8653 max=max2;
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008654 return Py_BuildValue("(LL)", min, max);
8655}
8656
Jesus Cea6557aac2010-03-22 14:22:26 +00008657
8658static PyObject*
8659DBSequence_stat_print(DBSequenceObject* self, PyObject* args, PyObject *kwargs)
8660{
8661 int err;
8662 int flags=0;
8663 static char* kwnames[] = { "flags", NULL };
8664
8665 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:stat_print",
8666 kwnames, &flags))
8667 {
8668 return NULL;
8669 }
8670
8671 CHECK_SEQUENCE_NOT_CLOSED(self);
8672
8673 MYDB_BEGIN_ALLOW_THREADS;
8674 err = self->sequence->stat_print(self->sequence, flags);
8675 MYDB_END_ALLOW_THREADS;
8676 RETURN_IF_ERR();
8677 RETURN_NONE();
8678}
8679
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008680static PyObject*
8681DBSequence_stat(DBSequenceObject* self, PyObject* args, PyObject* kwargs)
8682{
8683 int err, flags = 0;
8684 DB_SEQUENCE_STAT* sp = NULL;
8685 PyObject* dict_stat;
8686 static char* kwnames[] = {"flags", NULL };
8687 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:stat", kwnames, &flags))
8688 return NULL;
8689 CHECK_SEQUENCE_NOT_CLOSED(self);
8690
8691 MYDB_BEGIN_ALLOW_THREADS;
8692 err = self->sequence->stat(self->sequence, &sp, flags);
8693 MYDB_END_ALLOW_THREADS;
8694 RETURN_IF_ERR();
8695
8696 if ((dict_stat = PyDict_New()) == NULL) {
8697 free(sp);
8698 return NULL;
8699 }
8700
8701
8702#define MAKE_INT_ENTRY(name) _addIntToDict(dict_stat, #name, sp->st_##name)
8703#define MAKE_LONG_LONG_ENTRY(name) _addDb_seq_tToDict(dict_stat, #name, sp->st_##name)
8704
8705 MAKE_INT_ENTRY(wait);
8706 MAKE_INT_ENTRY(nowait);
8707 MAKE_LONG_LONG_ENTRY(current);
8708 MAKE_LONG_LONG_ENTRY(value);
8709 MAKE_LONG_LONG_ENTRY(last_value);
8710 MAKE_LONG_LONG_ENTRY(min);
8711 MAKE_LONG_LONG_ENTRY(max);
8712 MAKE_INT_ENTRY(cache_size);
8713 MAKE_INT_ENTRY(flags);
8714
8715#undef MAKE_INT_ENTRY
8716#undef MAKE_LONG_LONG_ENTRY
8717
8718 free(sp);
8719 return dict_stat;
8720}
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008721
8722
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008723/* --------------------------------------------------------------------- */
8724/* Method definition tables and type objects */
8725
8726static PyMethodDef DB_methods[] = {
Jesus Cea4907d272008-08-31 14:00:51 +00008727 {"append", (PyCFunction)DB_append, METH_VARARGS|METH_KEYWORDS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008728 {"associate", (PyCFunction)DB_associate, METH_VARARGS|METH_KEYWORDS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008729 {"close", (PyCFunction)DB_close, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008730#if (DBVER >= 47)
8731 {"compact", (PyCFunction)DB_compact, METH_VARARGS|METH_KEYWORDS},
8732#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008733 {"consume", (PyCFunction)DB_consume, METH_VARARGS|METH_KEYWORDS},
8734 {"consume_wait", (PyCFunction)DB_consume_wait, METH_VARARGS|METH_KEYWORDS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008735 {"cursor", (PyCFunction)DB_cursor, METH_VARARGS|METH_KEYWORDS},
8736 {"delete", (PyCFunction)DB_delete, METH_VARARGS|METH_KEYWORDS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008737 {"fd", (PyCFunction)DB_fd, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008738#if (DBVER >= 46)
8739 {"exists", (PyCFunction)DB_exists,
8740 METH_VARARGS|METH_KEYWORDS},
8741#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008742 {"get", (PyCFunction)DB_get, METH_VARARGS|METH_KEYWORDS},
Gregory P. Smith19699a92004-06-28 04:06:49 +00008743 {"pget", (PyCFunction)DB_pget, METH_VARARGS|METH_KEYWORDS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008744 {"get_both", (PyCFunction)DB_get_both, METH_VARARGS|METH_KEYWORDS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008745 {"get_byteswapped", (PyCFunction)DB_get_byteswapped,METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008746 {"get_size", (PyCFunction)DB_get_size, METH_VARARGS|METH_KEYWORDS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008747 {"get_type", (PyCFunction)DB_get_type, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008748 {"join", (PyCFunction)DB_join, METH_VARARGS},
8749 {"key_range", (PyCFunction)DB_key_range, METH_VARARGS|METH_KEYWORDS},
Jesus Cea4907d272008-08-31 14:00:51 +00008750 {"has_key", (PyCFunction)DB_has_key, METH_VARARGS|METH_KEYWORDS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008751 {"items", (PyCFunction)DB_items, METH_VARARGS},
8752 {"keys", (PyCFunction)DB_keys, METH_VARARGS},
8753 {"open", (PyCFunction)DB_open, METH_VARARGS|METH_KEYWORDS},
8754 {"put", (PyCFunction)DB_put, METH_VARARGS|METH_KEYWORDS},
8755 {"remove", (PyCFunction)DB_remove, METH_VARARGS|METH_KEYWORDS},
8756 {"rename", (PyCFunction)DB_rename, METH_VARARGS},
8757 {"set_bt_minkey", (PyCFunction)DB_set_bt_minkey, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008758 {"get_bt_minkey", (PyCFunction)DB_get_bt_minkey, METH_NOARGS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008759 {"set_bt_compare", (PyCFunction)DB_set_bt_compare, METH_O},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008760 {"set_cachesize", (PyCFunction)DB_set_cachesize, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008761 {"get_cachesize", (PyCFunction)DB_get_cachesize, METH_NOARGS},
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07008762 {"set_dup_compare", (PyCFunction)DB_set_dup_compare, METH_O},
Jesus Cea6557aac2010-03-22 14:22:26 +00008763 {"set_encrypt", (PyCFunction)DB_set_encrypt, METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008764 {"get_encrypt_flags", (PyCFunction)DB_get_encrypt_flags, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008765 {"set_flags", (PyCFunction)DB_set_flags, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008766 {"get_flags", (PyCFunction)DB_get_flags, METH_NOARGS},
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07008767 {"get_transactional", (PyCFunction)DB_get_transactional, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008768 {"set_h_ffactor", (PyCFunction)DB_set_h_ffactor, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008769 {"get_h_ffactor", (PyCFunction)DB_get_h_ffactor, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008770 {"set_h_nelem", (PyCFunction)DB_set_h_nelem, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008771 {"get_h_nelem", (PyCFunction)DB_get_h_nelem, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008772 {"set_lorder", (PyCFunction)DB_set_lorder, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008773 {"get_lorder", (PyCFunction)DB_get_lorder, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008774 {"set_pagesize", (PyCFunction)DB_set_pagesize, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008775 {"get_pagesize", (PyCFunction)DB_get_pagesize, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008776 {"set_re_delim", (PyCFunction)DB_set_re_delim, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008777 {"get_re_delim", (PyCFunction)DB_get_re_delim, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008778 {"set_re_len", (PyCFunction)DB_set_re_len, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008779 {"get_re_len", (PyCFunction)DB_get_re_len, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008780 {"set_re_pad", (PyCFunction)DB_set_re_pad, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008781 {"get_re_pad", (PyCFunction)DB_get_re_pad, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008782 {"set_re_source", (PyCFunction)DB_set_re_source, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008783 {"get_re_source", (PyCFunction)DB_get_re_source, METH_NOARGS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008784 {"set_q_extentsize",(PyCFunction)DB_set_q_extentsize, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008785 {"get_q_extentsize",(PyCFunction)DB_get_q_extentsize, METH_NOARGS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008786 {"set_private", (PyCFunction)DB_set_private, METH_O},
8787 {"get_private", (PyCFunction)DB_get_private, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008788#if (DBVER >= 46)
8789 {"set_priority", (PyCFunction)DB_set_priority, METH_VARARGS},
8790 {"get_priority", (PyCFunction)DB_get_priority, METH_NOARGS},
8791#endif
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07008792 {"get_dbname", (PyCFunction)DB_get_dbname, METH_NOARGS},
8793 {"get_open_flags", (PyCFunction)DB_get_open_flags, METH_NOARGS},
Gregory P. Smith8b7e9172004-12-13 09:51:23 +00008794 {"stat", (PyCFunction)DB_stat, METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008795 {"stat_print", (PyCFunction)DB_stat_print,
8796 METH_VARARGS|METH_KEYWORDS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008797 {"sync", (PyCFunction)DB_sync, METH_VARARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008798 {"truncate", (PyCFunction)DB_truncate, METH_VARARGS|METH_KEYWORDS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008799 {"type", (PyCFunction)DB_get_type, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008800 {"upgrade", (PyCFunction)DB_upgrade, METH_VARARGS},
8801 {"values", (PyCFunction)DB_values, METH_VARARGS},
8802 {"verify", (PyCFunction)DB_verify, METH_VARARGS|METH_KEYWORDS},
8803 {"set_get_returns_none",(PyCFunction)DB_set_get_returns_none, METH_VARARGS},
8804 {NULL, NULL} /* sentinel */
8805};
8806
8807
Jesus Cea6557aac2010-03-22 14:22:26 +00008808/* We need this to support __contains__() */
8809static PySequenceMethods DB_sequence = {
8810 0, /* sq_length, mapping wins here */
8811 0, /* sq_concat */
8812 0, /* sq_repeat */
8813 0, /* sq_item */
8814 0, /* sq_slice */
8815 0, /* sq_ass_item */
8816 0, /* sq_ass_slice */
8817 (objobjproc)DB_contains, /* sq_contains */
8818 0, /* sq_inplace_concat */
8819 0, /* sq_inplace_repeat */
8820};
8821
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008822static PyMappingMethods DB_mapping = {
Martin v. Löwis70ee3cc2006-06-12 04:26:31 +00008823 DB_length, /*mp_length*/
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008824 (binaryfunc)DB_subscript, /*mp_subscript*/
8825 (objobjargproc)DB_ass_sub, /*mp_ass_subscript*/
8826};
8827
8828
8829static PyMethodDef DBCursor_methods[] = {
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008830 {"close", (PyCFunction)DBC_close, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008831 {"count", (PyCFunction)DBC_count, METH_VARARGS},
8832 {"current", (PyCFunction)DBC_current, METH_VARARGS|METH_KEYWORDS},
8833 {"delete", (PyCFunction)DBC_delete, METH_VARARGS},
8834 {"dup", (PyCFunction)DBC_dup, METH_VARARGS},
8835 {"first", (PyCFunction)DBC_first, METH_VARARGS|METH_KEYWORDS},
8836 {"get", (PyCFunction)DBC_get, METH_VARARGS|METH_KEYWORDS},
Gregory P. Smith19699a92004-06-28 04:06:49 +00008837 {"pget", (PyCFunction)DBC_pget, METH_VARARGS|METH_KEYWORDS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008838 {"get_recno", (PyCFunction)DBC_get_recno, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008839 {"last", (PyCFunction)DBC_last, METH_VARARGS|METH_KEYWORDS},
8840 {"next", (PyCFunction)DBC_next, METH_VARARGS|METH_KEYWORDS},
8841 {"prev", (PyCFunction)DBC_prev, METH_VARARGS|METH_KEYWORDS},
8842 {"put", (PyCFunction)DBC_put, METH_VARARGS|METH_KEYWORDS},
8843 {"set", (PyCFunction)DBC_set, METH_VARARGS|METH_KEYWORDS},
8844 {"set_range", (PyCFunction)DBC_set_range, METH_VARARGS|METH_KEYWORDS},
8845 {"get_both", (PyCFunction)DBC_get_both, METH_VARARGS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008846 {"get_current_size",(PyCFunction)DBC_get_current_size, METH_NOARGS},
Gregory P. Smith455d46f2003-07-09 04:45:59 +00008847 {"set_both", (PyCFunction)DBC_set_both, METH_VARARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008848 {"set_recno", (PyCFunction)DBC_set_recno, METH_VARARGS|METH_KEYWORDS},
8849 {"consume", (PyCFunction)DBC_consume, METH_VARARGS|METH_KEYWORDS},
8850 {"next_dup", (PyCFunction)DBC_next_dup, METH_VARARGS|METH_KEYWORDS},
8851 {"next_nodup", (PyCFunction)DBC_next_nodup, METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008852#if (DBVER >= 46)
8853 {"prev_dup", (PyCFunction)DBC_prev_dup,
8854 METH_VARARGS|METH_KEYWORDS},
8855#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008856 {"prev_nodup", (PyCFunction)DBC_prev_nodup, METH_VARARGS|METH_KEYWORDS},
8857 {"join_item", (PyCFunction)DBC_join_item, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008858#if (DBVER >= 46)
8859 {"set_priority", (PyCFunction)DBC_set_priority,
8860 METH_VARARGS|METH_KEYWORDS},
8861 {"get_priority", (PyCFunction)DBC_get_priority, METH_NOARGS},
8862#endif
8863 {NULL, NULL} /* sentinel */
8864};
8865
8866
8867static PyMethodDef DBLogCursor_methods[] = {
8868 {"close", (PyCFunction)DBLogCursor_close, METH_NOARGS},
8869 {"current", (PyCFunction)DBLogCursor_current, METH_NOARGS},
8870 {"first", (PyCFunction)DBLogCursor_first, METH_NOARGS},
8871 {"last", (PyCFunction)DBLogCursor_last, METH_NOARGS},
8872 {"next", (PyCFunction)DBLogCursor_next, METH_NOARGS},
8873 {"prev", (PyCFunction)DBLogCursor_prev, METH_NOARGS},
8874 {"set", (PyCFunction)DBLogCursor_set, METH_VARARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008875 {NULL, NULL} /* sentinel */
8876};
8877
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07008878#if (DBVER >= 52)
8879static PyMethodDef DBSite_methods[] = {
8880 {"get_config", (PyCFunction)DBSite_get_config,
8881 METH_VARARGS | METH_KEYWORDS},
8882 {"set_config", (PyCFunction)DBSite_set_config,
8883 METH_VARARGS | METH_KEYWORDS},
8884 {"remove", (PyCFunction)DBSite_remove, METH_NOARGS},
8885 {"get_eid", (PyCFunction)DBSite_get_eid, METH_NOARGS},
8886 {"get_address", (PyCFunction)DBSite_get_address, METH_NOARGS},
8887 {"close", (PyCFunction)DBSite_close, METH_NOARGS},
8888 {NULL, NULL} /* sentinel */
8889};
8890#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008891
8892static PyMethodDef DBEnv_methods[] = {
8893 {"close", (PyCFunction)DBEnv_close, METH_VARARGS},
8894 {"open", (PyCFunction)DBEnv_open, METH_VARARGS},
8895 {"remove", (PyCFunction)DBEnv_remove, METH_VARARGS},
Barry Warsaw9a0d7792002-12-30 20:53:52 +00008896 {"dbremove", (PyCFunction)DBEnv_dbremove, METH_VARARGS|METH_KEYWORDS},
8897 {"dbrename", (PyCFunction)DBEnv_dbrename, METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008898#if (DBVER >= 46)
8899 {"set_thread_count", (PyCFunction)DBEnv_set_thread_count, METH_VARARGS},
8900 {"get_thread_count", (PyCFunction)DBEnv_get_thread_count, METH_NOARGS},
8901#endif
Barry Warsaw9a0d7792002-12-30 20:53:52 +00008902 {"set_encrypt", (PyCFunction)DBEnv_set_encrypt, METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008903 {"get_encrypt_flags", (PyCFunction)DBEnv_get_encrypt_flags, METH_NOARGS},
8904 {"get_timeout", (PyCFunction)DBEnv_get_timeout,
8905 METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008906 {"set_timeout", (PyCFunction)DBEnv_set_timeout, METH_VARARGS|METH_KEYWORDS},
8907 {"set_shm_key", (PyCFunction)DBEnv_set_shm_key, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008908 {"get_shm_key", (PyCFunction)DBEnv_get_shm_key, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008909#if (DBVER >= 46)
8910 {"set_cache_max", (PyCFunction)DBEnv_set_cache_max, METH_VARARGS},
8911 {"get_cache_max", (PyCFunction)DBEnv_get_cache_max, METH_NOARGS},
8912#endif
8913 {"set_cachesize", (PyCFunction)DBEnv_set_cachesize, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008914 {"get_cachesize", (PyCFunction)DBEnv_get_cachesize, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008915 {"memp_trickle", (PyCFunction)DBEnv_memp_trickle, METH_VARARGS},
8916 {"memp_sync", (PyCFunction)DBEnv_memp_sync, METH_VARARGS},
8917 {"memp_stat", (PyCFunction)DBEnv_memp_stat,
8918 METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008919 {"memp_stat_print", (PyCFunction)DBEnv_memp_stat_print,
8920 METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008921#if (DBVER >= 44)
8922 {"mutex_set_max", (PyCFunction)DBEnv_mutex_set_max, METH_VARARGS},
8923 {"mutex_get_max", (PyCFunction)DBEnv_mutex_get_max, METH_NOARGS},
8924 {"mutex_set_align", (PyCFunction)DBEnv_mutex_set_align, METH_VARARGS},
8925 {"mutex_get_align", (PyCFunction)DBEnv_mutex_get_align, METH_NOARGS},
8926 {"mutex_set_increment", (PyCFunction)DBEnv_mutex_set_increment,
8927 METH_VARARGS},
8928 {"mutex_get_increment", (PyCFunction)DBEnv_mutex_get_increment,
8929 METH_NOARGS},
8930 {"mutex_set_tas_spins", (PyCFunction)DBEnv_mutex_set_tas_spins,
8931 METH_VARARGS},
8932 {"mutex_get_tas_spins", (PyCFunction)DBEnv_mutex_get_tas_spins,
8933 METH_NOARGS},
8934 {"mutex_stat", (PyCFunction)DBEnv_mutex_stat, METH_VARARGS},
8935#if (DBVER >= 44)
8936 {"mutex_stat_print", (PyCFunction)DBEnv_mutex_stat_print,
8937 METH_VARARGS|METH_KEYWORDS},
8938#endif
8939#endif
8940 {"set_data_dir", (PyCFunction)DBEnv_set_data_dir, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008941 {"get_data_dirs", (PyCFunction)DBEnv_get_data_dirs, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008942 {"get_flags", (PyCFunction)DBEnv_get_flags, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008943 {"set_flags", (PyCFunction)DBEnv_set_flags, METH_VARARGS},
8944#if (DBVER >= 47)
8945 {"log_set_config", (PyCFunction)DBEnv_log_set_config, METH_VARARGS},
8946 {"log_get_config", (PyCFunction)DBEnv_log_get_config, METH_VARARGS},
8947#endif
8948 {"set_lg_bsize", (PyCFunction)DBEnv_set_lg_bsize, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008949 {"get_lg_bsize", (PyCFunction)DBEnv_get_lg_bsize, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008950 {"set_lg_dir", (PyCFunction)DBEnv_set_lg_dir, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008951 {"get_lg_dir", (PyCFunction)DBEnv_get_lg_dir, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008952 {"set_lg_max", (PyCFunction)DBEnv_set_lg_max, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008953 {"get_lg_max", (PyCFunction)DBEnv_get_lg_max, METH_NOARGS},
Gregory P. Smithe9477062005-06-04 06:46:59 +00008954 {"set_lg_regionmax",(PyCFunction)DBEnv_set_lg_regionmax, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008955 {"get_lg_regionmax",(PyCFunction)DBEnv_get_lg_regionmax, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008956#if (DBVER >= 44)
8957 {"set_lg_filemode", (PyCFunction)DBEnv_set_lg_filemode, METH_VARARGS},
8958 {"get_lg_filemode", (PyCFunction)DBEnv_get_lg_filemode, METH_NOARGS},
8959#endif
8960#if (DBVER >= 47)
8961 {"set_lk_partitions", (PyCFunction)DBEnv_set_lk_partitions, METH_VARARGS},
8962 {"get_lk_partitions", (PyCFunction)DBEnv_get_lk_partitions, METH_NOARGS},
8963#endif
8964 {"set_lk_detect", (PyCFunction)DBEnv_set_lk_detect, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008965 {"get_lk_detect", (PyCFunction)DBEnv_get_lk_detect, METH_NOARGS},
Gregory P. Smith8b96a352007-01-05 01:59:42 +00008966#if (DBVER < 45)
Jesus Cea6557aac2010-03-22 14:22:26 +00008967 {"set_lk_max", (PyCFunction)DBEnv_set_lk_max, METH_VARARGS},
Gregory P. Smith8b96a352007-01-05 01:59:42 +00008968#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008969 {"set_lk_max_locks", (PyCFunction)DBEnv_set_lk_max_locks, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008970 {"get_lk_max_locks", (PyCFunction)DBEnv_get_lk_max_locks, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008971 {"set_lk_max_lockers", (PyCFunction)DBEnv_set_lk_max_lockers, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008972 {"get_lk_max_lockers", (PyCFunction)DBEnv_get_lk_max_lockers, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008973 {"set_lk_max_objects", (PyCFunction)DBEnv_set_lk_max_objects, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008974 {"get_lk_max_objects", (PyCFunction)DBEnv_get_lk_max_objects, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008975 {"stat_print", (PyCFunction)DBEnv_stat_print,
8976 METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008977 {"set_mp_mmapsize", (PyCFunction)DBEnv_set_mp_mmapsize, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008978 {"get_mp_mmapsize", (PyCFunction)DBEnv_get_mp_mmapsize, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008979 {"set_tmp_dir", (PyCFunction)DBEnv_set_tmp_dir, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008980 {"get_tmp_dir", (PyCFunction)DBEnv_get_tmp_dir, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008981 {"txn_begin", (PyCFunction)DBEnv_txn_begin, METH_VARARGS|METH_KEYWORDS},
8982 {"txn_checkpoint", (PyCFunction)DBEnv_txn_checkpoint, METH_VARARGS},
8983 {"txn_stat", (PyCFunction)DBEnv_txn_stat, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008984 {"txn_stat_print", (PyCFunction)DBEnv_txn_stat_print,
8985 METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008986 {"get_tx_max", (PyCFunction)DBEnv_get_tx_max, METH_NOARGS},
8987 {"get_tx_timestamp", (PyCFunction)DBEnv_get_tx_timestamp, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008988 {"set_tx_max", (PyCFunction)DBEnv_set_tx_max, METH_VARARGS},
Gregory P. Smith8a474042006-01-27 07:05:40 +00008989 {"set_tx_timestamp", (PyCFunction)DBEnv_set_tx_timestamp, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008990 {"lock_detect", (PyCFunction)DBEnv_lock_detect, METH_VARARGS},
8991 {"lock_get", (PyCFunction)DBEnv_lock_get, METH_VARARGS},
8992 {"lock_id", (PyCFunction)DBEnv_lock_id, METH_NOARGS},
8993 {"lock_id_free", (PyCFunction)DBEnv_lock_id_free, METH_VARARGS},
8994 {"lock_put", (PyCFunction)DBEnv_lock_put, METH_VARARGS},
8995 {"lock_stat", (PyCFunction)DBEnv_lock_stat, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008996 {"lock_stat_print", (PyCFunction)DBEnv_lock_stat_print,
8997 METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008998 {"log_cursor", (PyCFunction)DBEnv_log_cursor, METH_NOARGS},
8999 {"log_file", (PyCFunction)DBEnv_log_file, METH_VARARGS},
Gregory P. Smithdb8a8072006-06-05 01:56:15 +00009000#if (DBVER >= 44)
Jesus Cea6557aac2010-03-22 14:22:26 +00009001 {"log_printf", (PyCFunction)DBEnv_log_printf,
9002 METH_VARARGS|METH_KEYWORDS},
9003#endif
9004 {"log_archive", (PyCFunction)DBEnv_log_archive, METH_VARARGS},
9005 {"log_flush", (PyCFunction)DBEnv_log_flush, METH_NOARGS},
9006 {"log_stat", (PyCFunction)DBEnv_log_stat, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00009007 {"log_stat_print", (PyCFunction)DBEnv_log_stat_print,
9008 METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00009009#if (DBVER >= 44)
9010 {"fileid_reset", (PyCFunction)DBEnv_fileid_reset, METH_VARARGS|METH_KEYWORDS},
9011 {"lsn_reset", (PyCFunction)DBEnv_lsn_reset, METH_VARARGS|METH_KEYWORDS},
Gregory P. Smithdb8a8072006-06-05 01:56:15 +00009012#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009013 {"set_get_returns_none",(PyCFunction)DBEnv_set_get_returns_none, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00009014 {"txn_recover", (PyCFunction)DBEnv_txn_recover, METH_NOARGS},
Matthias Klose54cc5392010-03-15 12:46:18 +00009015#if (DBVER < 48)
Jesus Ceaca3939c2008-05-22 15:27:38 +00009016 {"set_rpc_server", (PyCFunction)DBEnv_set_rpc_server,
Stefan Krah77112732011-09-15 22:56:00 +02009017 METH_VARARGS|METH_KEYWORDS},
Matthias Klose54cc5392010-03-15 12:46:18 +00009018#endif
Jesus Cea6557aac2010-03-22 14:22:26 +00009019 {"set_mp_max_openfd", (PyCFunction)DBEnv_set_mp_max_openfd, METH_VARARGS},
9020 {"get_mp_max_openfd", (PyCFunction)DBEnv_get_mp_max_openfd, METH_NOARGS},
9021 {"set_mp_max_write", (PyCFunction)DBEnv_set_mp_max_write, METH_VARARGS},
9022 {"get_mp_max_write", (PyCFunction)DBEnv_get_mp_max_write, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00009023 {"set_verbose", (PyCFunction)DBEnv_set_verbose, METH_VARARGS},
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009024 {"get_verbose", (PyCFunction)DBEnv_get_verbose, METH_VARARGS},
9025 {"set_private", (PyCFunction)DBEnv_set_private, METH_O},
9026 {"get_private", (PyCFunction)DBEnv_get_private, METH_NOARGS},
9027 {"get_open_flags", (PyCFunction)DBEnv_get_open_flags, METH_NOARGS},
9028#if (DBVER >= 47)
9029 {"set_intermediate_dir_mode", (PyCFunction)DBEnv_set_intermediate_dir_mode,
9030 METH_VARARGS},
9031 {"get_intermediate_dir_mode", (PyCFunction)DBEnv_get_intermediate_dir_mode,
9032 METH_NOARGS},
Jesus Ceaef9764f2008-05-13 18:45:46 +00009033#endif
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009034#if (DBVER < 47)
9035 {"set_intermediate_dir", (PyCFunction)DBEnv_set_intermediate_dir,
9036 METH_VARARGS},
9037#endif
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009038 {"rep_start", (PyCFunction)DBEnv_rep_start,
9039 METH_VARARGS|METH_KEYWORDS},
9040 {"rep_set_transport", (PyCFunction)DBEnv_rep_set_transport, METH_VARARGS},
9041 {"rep_process_message", (PyCFunction)DBEnv_rep_process_message,
9042 METH_VARARGS},
9043#if (DBVER >= 46)
9044 {"rep_elect", (PyCFunction)DBEnv_rep_elect, METH_VARARGS},
9045#endif
9046#if (DBVER >= 44)
9047 {"rep_set_config", (PyCFunction)DBEnv_rep_set_config, METH_VARARGS},
9048 {"rep_get_config", (PyCFunction)DBEnv_rep_get_config, METH_VARARGS},
9049 {"rep_sync", (PyCFunction)DBEnv_rep_sync, METH_NOARGS},
Jesus Ceaef9764f2008-05-13 18:45:46 +00009050#endif
9051#if (DBVER >= 45)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009052 {"rep_set_limit", (PyCFunction)DBEnv_rep_set_limit, METH_VARARGS},
9053 {"rep_get_limit", (PyCFunction)DBEnv_rep_get_limit, METH_NOARGS},
9054#endif
9055#if (DBVER >= 47)
9056 {"rep_set_request", (PyCFunction)DBEnv_rep_set_request, METH_VARARGS},
9057 {"rep_get_request", (PyCFunction)DBEnv_rep_get_request, METH_NOARGS},
9058#endif
9059#if (DBVER >= 45)
9060 {"set_event_notify", (PyCFunction)DBEnv_set_event_notify, METH_O},
Jesus Ceaef9764f2008-05-13 18:45:46 +00009061#endif
9062#if (DBVER >= 45)
9063 {"rep_set_nsites", (PyCFunction)DBEnv_rep_set_nsites, METH_VARARGS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009064 {"rep_get_nsites", (PyCFunction)DBEnv_rep_get_nsites, METH_NOARGS},
Jesus Ceaef9764f2008-05-13 18:45:46 +00009065 {"rep_set_priority", (PyCFunction)DBEnv_rep_set_priority, METH_VARARGS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009066 {"rep_get_priority", (PyCFunction)DBEnv_rep_get_priority, METH_NOARGS},
Jesus Ceaef9764f2008-05-13 18:45:46 +00009067 {"rep_set_timeout", (PyCFunction)DBEnv_rep_set_timeout, METH_VARARGS},
9068 {"rep_get_timeout", (PyCFunction)DBEnv_rep_get_timeout, METH_VARARGS},
9069#endif
Jesus Cea6557aac2010-03-22 14:22:26 +00009070#if (DBVER >= 47)
9071 {"rep_set_clockskew", (PyCFunction)DBEnv_rep_set_clockskew, METH_VARARGS},
9072 {"rep_get_clockskew", (PyCFunction)DBEnv_rep_get_clockskew, METH_VARARGS},
9073#endif
9074 {"rep_stat", (PyCFunction)DBEnv_rep_stat,
9075 METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00009076 {"rep_stat_print", (PyCFunction)DBEnv_rep_stat_print,
9077 METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00009078
Jesus Ceaef9764f2008-05-13 18:45:46 +00009079#if (DBVER >= 45)
9080 {"repmgr_start", (PyCFunction)DBEnv_repmgr_start,
9081 METH_VARARGS|METH_KEYWORDS},
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009082#if (DBVER < 52)
Jesus Ceaef9764f2008-05-13 18:45:46 +00009083 {"repmgr_set_local_site", (PyCFunction)DBEnv_repmgr_set_local_site,
9084 METH_VARARGS|METH_KEYWORDS},
9085 {"repmgr_add_remote_site", (PyCFunction)DBEnv_repmgr_add_remote_site,
9086 METH_VARARGS|METH_KEYWORDS},
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009087#endif
Jesus Ceaef9764f2008-05-13 18:45:46 +00009088 {"repmgr_set_ack_policy", (PyCFunction)DBEnv_repmgr_set_ack_policy,
9089 METH_VARARGS},
9090 {"repmgr_get_ack_policy", (PyCFunction)DBEnv_repmgr_get_ack_policy,
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009091 METH_NOARGS},
Jesus Ceaef9764f2008-05-13 18:45:46 +00009092 {"repmgr_site_list", (PyCFunction)DBEnv_repmgr_site_list,
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009093 METH_NOARGS},
Jesus Ceaef9764f2008-05-13 18:45:46 +00009094#endif
9095#if (DBVER >= 46)
9096 {"repmgr_stat", (PyCFunction)DBEnv_repmgr_stat,
9097 METH_VARARGS|METH_KEYWORDS},
9098 {"repmgr_stat_print", (PyCFunction)DBEnv_repmgr_stat_print,
9099 METH_VARARGS|METH_KEYWORDS},
9100#endif
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009101#if (DBVER >= 52)
9102 {"repmgr_site", (PyCFunction)DBEnv_repmgr_site,
9103 METH_VARARGS | METH_KEYWORDS},
9104 {"repmgr_site_by_eid", (PyCFunction)DBEnv_repmgr_site_by_eid,
9105 METH_VARARGS | METH_KEYWORDS},
9106#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009107 {NULL, NULL} /* sentinel */
9108};
9109
9110
9111static PyMethodDef DBTxn_methods[] = {
9112 {"commit", (PyCFunction)DBTxn_commit, METH_VARARGS},
9113 {"prepare", (PyCFunction)DBTxn_prepare, METH_VARARGS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009114 {"discard", (PyCFunction)DBTxn_discard, METH_NOARGS},
9115 {"abort", (PyCFunction)DBTxn_abort, METH_NOARGS},
9116 {"id", (PyCFunction)DBTxn_id, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00009117 {"set_timeout", (PyCFunction)DBTxn_set_timeout,
9118 METH_VARARGS|METH_KEYWORDS},
9119#if (DBVER >= 44)
9120 {"set_name", (PyCFunction)DBTxn_set_name, METH_VARARGS},
9121 {"get_name", (PyCFunction)DBTxn_get_name, METH_NOARGS},
9122#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009123 {NULL, NULL} /* sentinel */
9124};
9125
9126
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009127static PyMethodDef DBSequence_methods[] = {
9128 {"close", (PyCFunction)DBSequence_close, METH_VARARGS},
9129 {"get", (PyCFunction)DBSequence_get, METH_VARARGS|METH_KEYWORDS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009130 {"get_dbp", (PyCFunction)DBSequence_get_dbp, METH_NOARGS},
9131 {"get_key", (PyCFunction)DBSequence_get_key, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00009132 {"initial_value", (PyCFunction)DBSequence_initial_value, METH_VARARGS},
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009133 {"open", (PyCFunction)DBSequence_open, METH_VARARGS|METH_KEYWORDS},
9134 {"remove", (PyCFunction)DBSequence_remove, METH_VARARGS|METH_KEYWORDS},
9135 {"set_cachesize", (PyCFunction)DBSequence_set_cachesize, METH_VARARGS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009136 {"get_cachesize", (PyCFunction)DBSequence_get_cachesize, METH_NOARGS},
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009137 {"set_flags", (PyCFunction)DBSequence_set_flags, METH_VARARGS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009138 {"get_flags", (PyCFunction)DBSequence_get_flags, METH_NOARGS},
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009139 {"set_range", (PyCFunction)DBSequence_set_range, METH_VARARGS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009140 {"get_range", (PyCFunction)DBSequence_get_range, METH_NOARGS},
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009141 {"stat", (PyCFunction)DBSequence_stat, METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00009142 {"stat_print", (PyCFunction)DBSequence_stat_print,
9143 METH_VARARGS|METH_KEYWORDS},
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009144 {NULL, NULL} /* sentinel */
9145};
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009146
9147
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009148static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009149DBEnv_db_home_get(DBEnvObject* self)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009150{
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009151 const char *home = NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009152
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009153 CHECK_ENV_NOT_CLOSED(self);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009154
Jesus Cea6557aac2010-03-22 14:22:26 +00009155 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009156 self->db_env->get_home(self->db_env, &home);
Jesus Cea6557aac2010-03-22 14:22:26 +00009157 MYDB_END_ALLOW_THREADS;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009158
9159 if (home == NULL) {
9160 RETURN_NONE();
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009161 }
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009162 return PyBytes_FromString(home);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009163}
9164
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009165static PyGetSetDef DBEnv_getsets[] = {
9166 {"db_home", (getter)DBEnv_db_home_get, NULL,},
9167 {NULL}
9168};
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009169
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009170
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009171statichere PyTypeObject DB_Type = {
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009172#if (PY_VERSION_HEX < 0x03000000)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009173 PyObject_HEAD_INIT(NULL)
9174 0, /*ob_size*/
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009175#else
9176 PyVarObject_HEAD_INIT(NULL, 0)
9177#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009178 "DB", /*tp_name*/
9179 sizeof(DBObject), /*tp_basicsize*/
9180 0, /*tp_itemsize*/
9181 /* methods */
9182 (destructor)DB_dealloc, /*tp_dealloc*/
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009183 0, /*tp_print*/
9184 0, /*tp_getattr*/
9185 0, /*tp_setattr*/
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009186 0, /*tp_compare*/
9187 0, /*tp_repr*/
9188 0, /*tp_as_number*/
Jesus Cea6557aac2010-03-22 14:22:26 +00009189 &DB_sequence,/*tp_as_sequence*/
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009190 &DB_mapping,/*tp_as_mapping*/
9191 0, /*tp_hash*/
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009192 0, /* tp_call */
9193 0, /* tp_str */
9194 0, /* tp_getattro */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009195 0, /* tp_setattro */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009196 0, /* tp_as_buffer */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009197#if (PY_VERSION_HEX < 0x03000000)
Gregory P. Smith31c50652004-06-28 01:20:40 +00009198 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009199#else
9200 Py_TPFLAGS_DEFAULT, /* tp_flags */
9201#endif
9202 0, /* tp_doc */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009203 0, /* tp_traverse */
9204 0, /* tp_clear */
9205 0, /* tp_richcompare */
Gregory P. Smith31c50652004-06-28 01:20:40 +00009206 offsetof(DBObject, in_weakreflist), /* tp_weaklistoffset */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009207 0, /*tp_iter*/
9208 0, /*tp_iternext*/
9209 DB_methods, /*tp_methods*/
9210 0, /*tp_members*/
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009211};
9212
9213
9214statichere PyTypeObject DBCursor_Type = {
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009215#if (PY_VERSION_HEX < 0x03000000)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009216 PyObject_HEAD_INIT(NULL)
9217 0, /*ob_size*/
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009218#else
9219 PyVarObject_HEAD_INIT(NULL, 0)
9220#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009221 "DBCursor", /*tp_name*/
9222 sizeof(DBCursorObject), /*tp_basicsize*/
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009223 0, /*tp_itemsize*/
9224 /* methods */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009225 (destructor)DBCursor_dealloc,/*tp_dealloc*/
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009226 0, /*tp_print*/
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009227 0, /*tp_getattr*/
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009228 0, /*tp_setattr*/
9229 0, /*tp_compare*/
9230 0, /*tp_repr*/
9231 0, /*tp_as_number*/
9232 0, /*tp_as_sequence*/
9233 0, /*tp_as_mapping*/
9234 0, /*tp_hash*/
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009235 0, /*tp_call*/
9236 0, /*tp_str*/
9237 0, /*tp_getattro*/
9238 0, /*tp_setattro*/
9239 0, /*tp_as_buffer*/
9240#if (PY_VERSION_HEX < 0x03000000)
Gregory P. Smith31c50652004-06-28 01:20:40 +00009241 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009242#else
9243 Py_TPFLAGS_DEFAULT, /* tp_flags */
9244#endif
9245 0, /* tp_doc */
9246 0, /* tp_traverse */
9247 0, /* tp_clear */
9248 0, /* tp_richcompare */
9249 offsetof(DBCursorObject, in_weakreflist), /* tp_weaklistoffset */
9250 0, /*tp_iter*/
9251 0, /*tp_iternext*/
9252 DBCursor_methods, /*tp_methods*/
9253 0, /*tp_members*/
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009254};
9255
9256
Jesus Cea6557aac2010-03-22 14:22:26 +00009257statichere PyTypeObject DBLogCursor_Type = {
9258#if (PY_VERSION_HEX < 0x03000000)
9259 PyObject_HEAD_INIT(NULL)
9260 0, /*ob_size*/
9261#else
9262 PyVarObject_HEAD_INIT(NULL, 0)
9263#endif
9264 "DBLogCursor", /*tp_name*/
9265 sizeof(DBLogCursorObject), /*tp_basicsize*/
9266 0, /*tp_itemsize*/
9267 /* methods */
9268 (destructor)DBLogCursor_dealloc,/*tp_dealloc*/
9269 0, /*tp_print*/
9270 0, /*tp_getattr*/
9271 0, /*tp_setattr*/
9272 0, /*tp_compare*/
9273 0, /*tp_repr*/
9274 0, /*tp_as_number*/
9275 0, /*tp_as_sequence*/
9276 0, /*tp_as_mapping*/
9277 0, /*tp_hash*/
9278 0, /*tp_call*/
9279 0, /*tp_str*/
9280 0, /*tp_getattro*/
9281 0, /*tp_setattro*/
9282 0, /*tp_as_buffer*/
9283#if (PY_VERSION_HEX < 0x03000000)
9284 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
9285#else
9286 Py_TPFLAGS_DEFAULT, /* tp_flags */
9287#endif
9288 0, /* tp_doc */
9289 0, /* tp_traverse */
9290 0, /* tp_clear */
9291 0, /* tp_richcompare */
9292 offsetof(DBLogCursorObject, in_weakreflist), /* tp_weaklistoffset */
9293 0, /*tp_iter*/
9294 0, /*tp_iternext*/
9295 DBLogCursor_methods, /*tp_methods*/
9296 0, /*tp_members*/
9297};
9298
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009299#if (DBVER >= 52)
9300statichere PyTypeObject DBSite_Type = {
9301#if (PY_VERSION_HEX < 0x03000000)
9302 PyObject_HEAD_INIT(NULL)
9303 0, /*ob_size*/
9304#else
9305 PyVarObject_HEAD_INIT(NULL, 0)
9306#endif
9307 "DBSite", /*tp_name*/
9308 sizeof(DBSiteObject), /*tp_basicsize*/
9309 0, /*tp_itemsize*/
9310 /* methods */
9311 (destructor)DBSite_dealloc,/*tp_dealloc*/
9312 0, /*tp_print*/
9313 0, /*tp_getattr*/
9314 0, /*tp_setattr*/
9315 0, /*tp_compare*/
9316 0, /*tp_repr*/
9317 0, /*tp_as_number*/
9318 0, /*tp_as_sequence*/
9319 0, /*tp_as_mapping*/
9320 0, /*tp_hash*/
9321 0, /*tp_call*/
9322 0, /*tp_str*/
9323 0, /*tp_getattro*/
9324 0, /*tp_setattro*/
9325 0, /*tp_as_buffer*/
9326#if (PY_VERSION_HEX < 0x03000000)
9327 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
9328#else
9329 Py_TPFLAGS_DEFAULT, /* tp_flags */
9330#endif
9331 0, /* tp_doc */
9332 0, /* tp_traverse */
9333 0, /* tp_clear */
9334 0, /* tp_richcompare */
9335 offsetof(DBSiteObject, in_weakreflist), /* tp_weaklistoffset */
9336 0, /*tp_iter*/
9337 0, /*tp_iternext*/
9338 DBSite_methods, /*tp_methods*/
9339 0, /*tp_members*/
9340};
9341#endif
Jesus Cea6557aac2010-03-22 14:22:26 +00009342
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009343statichere PyTypeObject DBEnv_Type = {
9344#if (PY_VERSION_HEX < 0x03000000)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009345 PyObject_HEAD_INIT(NULL)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009346 0, /*ob_size*/
9347#else
9348 PyVarObject_HEAD_INIT(NULL, 0)
9349#endif
9350 "DBEnv", /*tp_name*/
9351 sizeof(DBEnvObject), /*tp_basicsize*/
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009352 0, /*tp_itemsize*/
9353 /* methods */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009354 (destructor)DBEnv_dealloc, /*tp_dealloc*/
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009355 0, /*tp_print*/
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009356 0, /*tp_getattr*/
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009357 0, /*tp_setattr*/
9358 0, /*tp_compare*/
9359 0, /*tp_repr*/
9360 0, /*tp_as_number*/
9361 0, /*tp_as_sequence*/
9362 0, /*tp_as_mapping*/
9363 0, /*tp_hash*/
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009364 0, /* tp_call */
9365 0, /* tp_str */
9366 0, /* tp_getattro */
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009367 0, /* tp_setattro */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009368 0, /* tp_as_buffer */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009369#if (PY_VERSION_HEX < 0x03000000)
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009370 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009371#else
9372 Py_TPFLAGS_DEFAULT, /* tp_flags */
9373#endif
9374 0, /* tp_doc */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009375 0, /* tp_traverse */
9376 0, /* tp_clear */
9377 0, /* tp_richcompare */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009378 offsetof(DBEnvObject, in_weakreflist), /* tp_weaklistoffset */
9379 0, /* tp_iter */
9380 0, /* tp_iternext */
9381 DBEnv_methods, /* tp_methods */
9382 0, /* tp_members */
9383 DBEnv_getsets, /* tp_getsets */
9384};
9385
9386statichere PyTypeObject DBTxn_Type = {
9387#if (PY_VERSION_HEX < 0x03000000)
9388 PyObject_HEAD_INIT(NULL)
9389 0, /*ob_size*/
9390#else
9391 PyVarObject_HEAD_INIT(NULL, 0)
9392#endif
9393 "DBTxn", /*tp_name*/
9394 sizeof(DBTxnObject), /*tp_basicsize*/
9395 0, /*tp_itemsize*/
9396 /* methods */
9397 (destructor)DBTxn_dealloc, /*tp_dealloc*/
9398 0, /*tp_print*/
9399 0, /*tp_getattr*/
9400 0, /*tp_setattr*/
9401 0, /*tp_compare*/
9402 0, /*tp_repr*/
9403 0, /*tp_as_number*/
9404 0, /*tp_as_sequence*/
9405 0, /*tp_as_mapping*/
9406 0, /*tp_hash*/
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009407 0, /* tp_call */
9408 0, /* tp_str */
9409 0, /* tp_getattro */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009410 0, /* tp_setattro */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009411 0, /* tp_as_buffer */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009412#if (PY_VERSION_HEX < 0x03000000)
9413 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
9414#else
9415 Py_TPFLAGS_DEFAULT, /* tp_flags */
9416#endif
9417 0, /* tp_doc */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009418 0, /* tp_traverse */
9419 0, /* tp_clear */
9420 0, /* tp_richcompare */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009421 offsetof(DBTxnObject, in_weakreflist), /* tp_weaklistoffset */
9422 0, /*tp_iter*/
9423 0, /*tp_iternext*/
9424 DBTxn_methods, /*tp_methods*/
9425 0, /*tp_members*/
9426};
9427
9428
9429statichere PyTypeObject DBLock_Type = {
9430#if (PY_VERSION_HEX < 0x03000000)
9431 PyObject_HEAD_INIT(NULL)
9432 0, /*ob_size*/
9433#else
9434 PyVarObject_HEAD_INIT(NULL, 0)
9435#endif
9436 "DBLock", /*tp_name*/
9437 sizeof(DBLockObject), /*tp_basicsize*/
9438 0, /*tp_itemsize*/
9439 /* methods */
9440 (destructor)DBLock_dealloc, /*tp_dealloc*/
9441 0, /*tp_print*/
9442 0, /*tp_getattr*/
9443 0, /*tp_setattr*/
9444 0, /*tp_compare*/
9445 0, /*tp_repr*/
9446 0, /*tp_as_number*/
9447 0, /*tp_as_sequence*/
9448 0, /*tp_as_mapping*/
9449 0, /*tp_hash*/
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009450 0, /* tp_call */
9451 0, /* tp_str */
9452 0, /* tp_getattro */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009453 0, /* tp_setattro */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009454 0, /* tp_as_buffer */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009455#if (PY_VERSION_HEX < 0x03000000)
9456 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
9457#else
9458 Py_TPFLAGS_DEFAULT, /* tp_flags */
9459#endif
9460 0, /* tp_doc */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009461 0, /* tp_traverse */
9462 0, /* tp_clear */
9463 0, /* tp_richcompare */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009464 offsetof(DBLockObject, in_weakreflist), /* tp_weaklistoffset */
9465};
9466
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009467statichere PyTypeObject DBSequence_Type = {
9468#if (PY_VERSION_HEX < 0x03000000)
9469 PyObject_HEAD_INIT(NULL)
9470 0, /*ob_size*/
9471#else
9472 PyVarObject_HEAD_INIT(NULL, 0)
9473#endif
9474 "DBSequence", /*tp_name*/
9475 sizeof(DBSequenceObject), /*tp_basicsize*/
9476 0, /*tp_itemsize*/
9477 /* methods */
9478 (destructor)DBSequence_dealloc, /*tp_dealloc*/
9479 0, /*tp_print*/
9480 0, /*tp_getattr*/
9481 0, /*tp_setattr*/
9482 0, /*tp_compare*/
9483 0, /*tp_repr*/
9484 0, /*tp_as_number*/
9485 0, /*tp_as_sequence*/
9486 0, /*tp_as_mapping*/
9487 0, /*tp_hash*/
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009488 0, /* tp_call */
9489 0, /* tp_str */
9490 0, /* tp_getattro */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009491 0, /* tp_setattro */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009492 0, /* tp_as_buffer */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009493#if (PY_VERSION_HEX < 0x03000000)
9494 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
9495#else
9496 Py_TPFLAGS_DEFAULT, /* tp_flags */
9497#endif
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009498 0, /* tp_doc */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009499 0, /* tp_traverse */
9500 0, /* tp_clear */
9501 0, /* tp_richcompare */
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009502 offsetof(DBSequenceObject, in_weakreflist), /* tp_weaklistoffset */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009503 0, /*tp_iter*/
9504 0, /*tp_iternext*/
9505 DBSequence_methods, /*tp_methods*/
9506 0, /*tp_members*/
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009507};
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009508
9509/* --------------------------------------------------------------------- */
9510/* Module-level functions */
9511
9512static PyObject*
9513DB_construct(PyObject* self, PyObject* args, PyObject* kwargs)
9514{
9515 PyObject* dbenvobj = NULL;
9516 int flags = 0;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00009517 static char* kwnames[] = { "dbEnv", "flags", NULL};
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009518
Barry Warsaw9a0d7792002-12-30 20:53:52 +00009519 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Oi:DB", kwnames,
9520 &dbenvobj, &flags))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009521 return NULL;
9522 if (dbenvobj == Py_None)
9523 dbenvobj = NULL;
9524 else if (dbenvobj && !DBEnvObject_Check(dbenvobj)) {
9525 makeTypeError("DBEnv", dbenvobj);
9526 return NULL;
9527 }
9528
9529 return (PyObject* )newDBObject((DBEnvObject*)dbenvobj, flags);
9530}
9531
9532
9533static PyObject*
9534DBEnv_construct(PyObject* self, PyObject* args)
9535{
9536 int flags = 0;
9537 if (!PyArg_ParseTuple(args, "|i:DbEnv", &flags)) return NULL;
9538 return (PyObject* )newDBEnvObject(flags);
9539}
9540
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009541static PyObject*
9542DBSequence_construct(PyObject* self, PyObject* args, PyObject* kwargs)
9543{
Neal Norwitzb4fcf8d2006-06-11 05:44:18 +00009544 PyObject* dbobj;
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009545 int flags = 0;
9546 static char* kwnames[] = { "db", "flags", NULL};
9547
9548 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|i:DBSequence", kwnames, &dbobj, &flags))
9549 return NULL;
Neal Norwitzb4fcf8d2006-06-11 05:44:18 +00009550 if (!DBObject_Check(dbobj)) {
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009551 makeTypeError("DB", dbobj);
9552 return NULL;
9553 }
9554 return (PyObject* )newDBSequenceObject((DBObject*)dbobj, flags);
9555}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009556
9557static char bsddb_version_doc[] =
9558"Returns a tuple of major, minor, and patch release numbers of the\n\
9559underlying DB library.";
9560
9561static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009562bsddb_version(PyObject* self)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009563{
9564 int major, minor, patch;
9565
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009566 /* This should be instantaneous, no need to release the GIL */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009567 db_version(&major, &minor, &patch);
9568 return Py_BuildValue("(iii)", major, minor, patch);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009569}
9570
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009571#if (DBVER >= 50)
9572static PyObject*
9573bsddb_version_full(PyObject* self)
9574{
9575 char *version_string;
9576 int family, release, major, minor, patch;
9577
9578 /* This should be instantaneous, no need to release the GIL */
9579 version_string = db_full_version(&family, &release, &major, &minor, &patch);
9580 return Py_BuildValue("(siiiii)",
9581 version_string, family, release, major, minor, patch);
9582}
9583#endif
9584
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009585
9586/* List of functions defined in the module */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009587static PyMethodDef bsddb_methods[] = {
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009588 {"DB", (PyCFunction)DB_construct, METH_VARARGS | METH_KEYWORDS },
9589 {"DBEnv", (PyCFunction)DBEnv_construct, METH_VARARGS},
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009590 {"DBSequence", (PyCFunction)DBSequence_construct, METH_VARARGS | METH_KEYWORDS },
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009591 {"version", (PyCFunction)bsddb_version, METH_NOARGS, bsddb_version_doc},
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009592#if (DBVER >= 50)
9593 {"full_version", (PyCFunction)bsddb_version_full, METH_NOARGS},
9594#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009595 {NULL, NULL} /* sentinel */
9596};
9597
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009598
Gregory P. Smith39250532007-10-09 06:02:21 +00009599/* API structure */
9600static BSDDB_api bsddb_api;
9601
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009602
9603/* --------------------------------------------------------------------- */
9604/* Module initialization */
9605
9606
9607/* Convenience routine to export an integer value.
9608 * Errors are silently ignored, for better or for worse...
9609 */
9610#define ADD_INT(dict, NAME) _addIntToDict(dict, #NAME, NAME)
9611
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009612/*
9613** We can rename the module at import time, so the string allocated
9614** must be big enough, and any use of the name must use this particular
9615** string.
9616*/
Gregory P. Smith41631e82003-09-21 00:08:14 +00009617#define MODULE_NAME_MAX_LEN 11
9618static char _bsddbModuleName[MODULE_NAME_MAX_LEN+1] = "_bsddb";
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009619
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009620#if (PY_VERSION_HEX >= 0x03000000)
9621static struct PyModuleDef bsddbmodule = {
9622 PyModuleDef_HEAD_INIT,
9623 _bsddbModuleName, /* Name of module */
9624 NULL, /* module documentation, may be NULL */
9625 -1, /* size of per-interpreter state of the module,
9626 or -1 if the module keeps state in global variables. */
9627 bsddb_methods,
9628 NULL, /* Reload */
9629 NULL, /* Traverse */
9630 NULL, /* Clear */
9631 NULL /* Free */
9632};
9633#endif
9634
9635
9636#if (PY_VERSION_HEX < 0x03000000)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009637DL_EXPORT(void) init_bsddb(void)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009638#else
9639PyMODINIT_FUNC PyInit__bsddb(void) /* Note the two underscores */
9640#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009641{
9642 PyObject* m;
9643 PyObject* d;
Gregory P. Smith39250532007-10-09 06:02:21 +00009644 PyObject* py_api;
Jesus Cea6557aac2010-03-22 14:22:26 +00009645 PyObject* pybsddb_version_s;
9646 PyObject* db_version_s;
9647 PyObject* cvsid_s;
9648
9649#if (PY_VERSION_HEX < 0x03000000)
9650 pybsddb_version_s = PyString_FromString(PY_BSDDB_VERSION);
9651 db_version_s = PyString_FromString(DB_VERSION_STRING);
9652 cvsid_s = PyString_FromString(rcs_id);
9653#else
9654 /* This data should be ascii, so UTF-8 conversion is fine */
9655 pybsddb_version_s = PyUnicode_FromString(PY_BSDDB_VERSION);
9656 db_version_s = PyUnicode_FromString(DB_VERSION_STRING);
9657 cvsid_s = PyUnicode_FromString(rcs_id);
9658#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009659
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009660 /* Initialize object types */
9661 if ((PyType_Ready(&DB_Type) < 0)
9662 || (PyType_Ready(&DBCursor_Type) < 0)
Jesus Cea6557aac2010-03-22 14:22:26 +00009663 || (PyType_Ready(&DBLogCursor_Type) < 0)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009664 || (PyType_Ready(&DBEnv_Type) < 0)
9665 || (PyType_Ready(&DBTxn_Type) < 0)
9666 || (PyType_Ready(&DBLock_Type) < 0)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009667 || (PyType_Ready(&DBSequence_Type) < 0)
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009668#if (DBVER >= 52)
9669 || (PyType_Ready(&DBSite_Type) < 0)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009670#endif
9671 ) {
9672#if (PY_VERSION_HEX < 0x03000000)
9673 return;
9674#else
9675 return NULL;
9676#endif
9677 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009678
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009679 /* Create the module and add the functions */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009680#if (PY_VERSION_HEX < 0x03000000)
Gregory P. Smith41631e82003-09-21 00:08:14 +00009681 m = Py_InitModule(_bsddbModuleName, bsddb_methods);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009682#else
9683 m=PyModule_Create(&bsddbmodule);
9684#endif
9685 if (m == NULL) {
9686#if (PY_VERSION_HEX < 0x03000000)
9687 return;
9688#else
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009689 return NULL;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009690#endif
9691 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009692
9693 /* Add some symbolic constants to the module */
9694 d = PyModule_GetDict(m);
9695 PyDict_SetItemString(d, "__version__", pybsddb_version_s);
9696 PyDict_SetItemString(d, "cvsid", cvsid_s);
9697 PyDict_SetItemString(d, "DB_VERSION_STRING", db_version_s);
9698 Py_DECREF(pybsddb_version_s);
9699 pybsddb_version_s = NULL;
9700 Py_DECREF(cvsid_s);
9701 cvsid_s = NULL;
9702 Py_DECREF(db_version_s);
9703 db_version_s = NULL;
9704
9705 ADD_INT(d, DB_VERSION_MAJOR);
9706 ADD_INT(d, DB_VERSION_MINOR);
9707 ADD_INT(d, DB_VERSION_PATCH);
9708
9709 ADD_INT(d, DB_MAX_PAGES);
9710 ADD_INT(d, DB_MAX_RECORDS);
9711
Matthias Klose54cc5392010-03-15 12:46:18 +00009712#if (DBVER < 48)
Gregory P. Smith41631e82003-09-21 00:08:14 +00009713 ADD_INT(d, DB_RPCCLIENT);
Matthias Klose54cc5392010-03-15 12:46:18 +00009714#endif
9715
9716#if (DBVER < 48)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009717 ADD_INT(d, DB_XA_CREATE);
Matthias Klose54cc5392010-03-15 12:46:18 +00009718#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009719
9720 ADD_INT(d, DB_CREATE);
9721 ADD_INT(d, DB_NOMMAP);
9722 ADD_INT(d, DB_THREAD);
Jesus Ceaef9764f2008-05-13 18:45:46 +00009723#if (DBVER >= 45)
9724 ADD_INT(d, DB_MULTIVERSION);
9725#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009726
9727 ADD_INT(d, DB_FORCE);
9728 ADD_INT(d, DB_INIT_CDB);
9729 ADD_INT(d, DB_INIT_LOCK);
9730 ADD_INT(d, DB_INIT_LOG);
9731 ADD_INT(d, DB_INIT_MPOOL);
9732 ADD_INT(d, DB_INIT_TXN);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009733 ADD_INT(d, DB_JOINENV);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009734
Matthias Klose54cc5392010-03-15 12:46:18 +00009735#if (DBVER >= 48)
9736 ADD_INT(d, DB_GID_SIZE);
9737#else
Jesus Ceaef9764f2008-05-13 18:45:46 +00009738 ADD_INT(d, DB_XIDDATASIZE);
Matthias Klose54cc5392010-03-15 12:46:18 +00009739 /* Allow new code to work in old BDB releases */
9740 _addIntToDict(d, "DB_GID_SIZE", DB_XIDDATASIZE);
9741#endif
Jesus Ceaef9764f2008-05-13 18:45:46 +00009742
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009743 ADD_INT(d, DB_RECOVER);
9744 ADD_INT(d, DB_RECOVER_FATAL);
9745 ADD_INT(d, DB_TXN_NOSYNC);
9746 ADD_INT(d, DB_USE_ENVIRON);
9747 ADD_INT(d, DB_USE_ENVIRON_ROOT);
9748
9749 ADD_INT(d, DB_LOCKDOWN);
9750 ADD_INT(d, DB_PRIVATE);
9751 ADD_INT(d, DB_SYSTEM_MEM);
9752
9753 ADD_INT(d, DB_TXN_SYNC);
9754 ADD_INT(d, DB_TXN_NOWAIT);
9755
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009756#if (DBVER >= 51)
9757 ADD_INT(d, DB_TXN_BULK);
9758#endif
9759
9760#if (DBVER >= 48)
9761 ADD_INT(d, DB_CURSOR_BULK);
9762#endif
9763
Jesus Cea6557aac2010-03-22 14:22:26 +00009764#if (DBVER >= 46)
9765 ADD_INT(d, DB_TXN_WAIT);
9766#endif
9767
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009768 ADD_INT(d, DB_EXCL);
9769 ADD_INT(d, DB_FCNTL_LOCKING);
9770 ADD_INT(d, DB_ODDFILESIZE);
9771 ADD_INT(d, DB_RDWRMASTER);
9772 ADD_INT(d, DB_RDONLY);
9773 ADD_INT(d, DB_TRUNCATE);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009774 ADD_INT(d, DB_EXTENT);
9775 ADD_INT(d, DB_CDB_ALLDB);
9776 ADD_INT(d, DB_VERIFY);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009777 ADD_INT(d, DB_UPGRADE);
9778
Jesus Cea6557aac2010-03-22 14:22:26 +00009779 ADD_INT(d, DB_PRINTABLE);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009780 ADD_INT(d, DB_AGGRESSIVE);
9781 ADD_INT(d, DB_NOORDERCHK);
9782 ADD_INT(d, DB_ORDERCHKONLY);
9783 ADD_INT(d, DB_PR_PAGE);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009784
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009785 ADD_INT(d, DB_PR_RECOVERYTEST);
9786 ADD_INT(d, DB_SALVAGE);
9787
9788 ADD_INT(d, DB_LOCK_NORUN);
9789 ADD_INT(d, DB_LOCK_DEFAULT);
9790 ADD_INT(d, DB_LOCK_OLDEST);
9791 ADD_INT(d, DB_LOCK_RANDOM);
9792 ADD_INT(d, DB_LOCK_YOUNGEST);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009793 ADD_INT(d, DB_LOCK_MAXLOCKS);
9794 ADD_INT(d, DB_LOCK_MINLOCKS);
9795 ADD_INT(d, DB_LOCK_MINWRITE);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009796
Jesus Ceaef9764f2008-05-13 18:45:46 +00009797 ADD_INT(d, DB_LOCK_EXPIRE);
Jesus Ceaef9764f2008-05-13 18:45:46 +00009798 ADD_INT(d, DB_LOCK_MAXWRITE);
Jesus Ceaef9764f2008-05-13 18:45:46 +00009799
Barry Warsaw9a0d7792002-12-30 20:53:52 +00009800 _addIntToDict(d, "DB_LOCK_CONFLICT", 0);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009801
9802 ADD_INT(d, DB_LOCK_DUMP);
9803 ADD_INT(d, DB_LOCK_GET);
9804 ADD_INT(d, DB_LOCK_INHERIT);
9805 ADD_INT(d, DB_LOCK_PUT);
9806 ADD_INT(d, DB_LOCK_PUT_ALL);
9807 ADD_INT(d, DB_LOCK_PUT_OBJ);
9808
9809 ADD_INT(d, DB_LOCK_NG);
9810 ADD_INT(d, DB_LOCK_READ);
9811 ADD_INT(d, DB_LOCK_WRITE);
9812 ADD_INT(d, DB_LOCK_NOWAIT);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009813 ADD_INT(d, DB_LOCK_WAIT);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009814 ADD_INT(d, DB_LOCK_IWRITE);
9815 ADD_INT(d, DB_LOCK_IREAD);
9816 ADD_INT(d, DB_LOCK_IWR);
Gregory P. Smith29602d22006-01-24 09:46:48 +00009817#if (DBVER < 44)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009818 ADD_INT(d, DB_LOCK_DIRTY);
Gregory P. Smith29602d22006-01-24 09:46:48 +00009819#else
9820 ADD_INT(d, DB_LOCK_READ_UNCOMMITTED); /* renamed in 4.4 */
9821#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009822 ADD_INT(d, DB_LOCK_WWRITE);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009823
9824 ADD_INT(d, DB_LOCK_RECORD);
9825 ADD_INT(d, DB_LOCK_UPGRADE);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009826 ADD_INT(d, DB_LOCK_SWITCH);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009827 ADD_INT(d, DB_LOCK_UPGRADE_WRITE);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009828
9829 ADD_INT(d, DB_LOCK_NOWAIT);
9830 ADD_INT(d, DB_LOCK_RECORD);
9831 ADD_INT(d, DB_LOCK_UPGRADE);
9832
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009833 ADD_INT(d, DB_LSTAT_ABORTED);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009834 ADD_INT(d, DB_LSTAT_FREE);
9835 ADD_INT(d, DB_LSTAT_HELD);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009836
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009837 ADD_INT(d, DB_LSTAT_PENDING);
9838 ADD_INT(d, DB_LSTAT_WAITING);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009839
9840 ADD_INT(d, DB_ARCH_ABS);
9841 ADD_INT(d, DB_ARCH_DATA);
9842 ADD_INT(d, DB_ARCH_LOG);
Gregory P. Smith3dd20022006-06-05 00:31:01 +00009843 ADD_INT(d, DB_ARCH_REMOVE);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009844
9845 ADD_INT(d, DB_BTREE);
9846 ADD_INT(d, DB_HASH);
9847 ADD_INT(d, DB_RECNO);
9848 ADD_INT(d, DB_QUEUE);
9849 ADD_INT(d, DB_UNKNOWN);
9850
9851 ADD_INT(d, DB_DUP);
9852 ADD_INT(d, DB_DUPSORT);
9853 ADD_INT(d, DB_RECNUM);
9854 ADD_INT(d, DB_RENUMBER);
9855 ADD_INT(d, DB_REVSPLITOFF);
9856 ADD_INT(d, DB_SNAPSHOT);
9857
Jesus Cea6557aac2010-03-22 14:22:26 +00009858 ADD_INT(d, DB_INORDER);
Jesus Cea6557aac2010-03-22 14:22:26 +00009859
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009860 ADD_INT(d, DB_JOIN_NOSORT);
9861
9862 ADD_INT(d, DB_AFTER);
9863 ADD_INT(d, DB_APPEND);
9864 ADD_INT(d, DB_BEFORE);
Gregory P. Smith8b96a352007-01-05 01:59:42 +00009865#if (DBVER < 45)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009866 ADD_INT(d, DB_CACHED_COUNTS);
Gregory P. Smith8b96a352007-01-05 01:59:42 +00009867#endif
Jesus Ceaca3939c2008-05-22 15:27:38 +00009868
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009869 ADD_INT(d, DB_CONSUME);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009870 ADD_INT(d, DB_CONSUME_WAIT);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009871 ADD_INT(d, DB_CURRENT);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009872 ADD_INT(d, DB_FAST_STAT);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009873 ADD_INT(d, DB_FIRST);
9874 ADD_INT(d, DB_FLUSH);
9875 ADD_INT(d, DB_GET_BOTH);
Jesus Cea6557aac2010-03-22 14:22:26 +00009876 ADD_INT(d, DB_GET_BOTH_RANGE);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009877 ADD_INT(d, DB_GET_RECNO);
9878 ADD_INT(d, DB_JOIN_ITEM);
9879 ADD_INT(d, DB_KEYFIRST);
9880 ADD_INT(d, DB_KEYLAST);
9881 ADD_INT(d, DB_LAST);
9882 ADD_INT(d, DB_NEXT);
9883 ADD_INT(d, DB_NEXT_DUP);
9884 ADD_INT(d, DB_NEXT_NODUP);
9885 ADD_INT(d, DB_NODUPDATA);
9886 ADD_INT(d, DB_NOOVERWRITE);
9887 ADD_INT(d, DB_NOSYNC);
9888 ADD_INT(d, DB_POSITION);
9889 ADD_INT(d, DB_PREV);
9890 ADD_INT(d, DB_PREV_NODUP);
Jesus Cea6557aac2010-03-22 14:22:26 +00009891#if (DBVER >= 46)
9892 ADD_INT(d, DB_PREV_DUP);
9893#endif
Gregory P. Smith8b96a352007-01-05 01:59:42 +00009894#if (DBVER < 45)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009895 ADD_INT(d, DB_RECORDCOUNT);
Gregory P. Smith8b96a352007-01-05 01:59:42 +00009896#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009897 ADD_INT(d, DB_SET);
9898 ADD_INT(d, DB_SET_RANGE);
9899 ADD_INT(d, DB_SET_RECNO);
9900 ADD_INT(d, DB_WRITECURSOR);
9901
9902 ADD_INT(d, DB_OPFLAGS_MASK);
9903 ADD_INT(d, DB_RMW);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009904 ADD_INT(d, DB_DIRTY_READ);
9905 ADD_INT(d, DB_MULTIPLE);
9906 ADD_INT(d, DB_MULTIPLE_KEY);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009907
Gregory P. Smith29602d22006-01-24 09:46:48 +00009908#if (DBVER >= 44)
Jesus Cea6557aac2010-03-22 14:22:26 +00009909 ADD_INT(d, DB_IMMUTABLE_KEY);
Gregory P. Smith29602d22006-01-24 09:46:48 +00009910 ADD_INT(d, DB_READ_UNCOMMITTED); /* replaces DB_DIRTY_READ in 4.4 */
9911 ADD_INT(d, DB_READ_COMMITTED);
9912#endif
9913
Jesus Cea6557aac2010-03-22 14:22:26 +00009914#if (DBVER >= 44)
9915 ADD_INT(d, DB_FREELIST_ONLY);
9916 ADD_INT(d, DB_FREE_SPACE);
9917#endif
9918
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009919 ADD_INT(d, DB_DONOTINDEX);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009920
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009921 ADD_INT(d, DB_KEYEMPTY);
9922 ADD_INT(d, DB_KEYEXIST);
9923 ADD_INT(d, DB_LOCK_DEADLOCK);
9924 ADD_INT(d, DB_LOCK_NOTGRANTED);
9925 ADD_INT(d, DB_NOSERVER);
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009926#if (DBVER < 52)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009927 ADD_INT(d, DB_NOSERVER_HOME);
9928 ADD_INT(d, DB_NOSERVER_ID);
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009929#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009930 ADD_INT(d, DB_NOTFOUND);
9931 ADD_INT(d, DB_OLD_VERSION);
9932 ADD_INT(d, DB_RUNRECOVERY);
9933 ADD_INT(d, DB_VERIFY_BAD);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009934 ADD_INT(d, DB_PAGE_NOTFOUND);
9935 ADD_INT(d, DB_SECONDARY_BAD);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009936 ADD_INT(d, DB_STAT_CLEAR);
9937 ADD_INT(d, DB_REGION_INIT);
9938 ADD_INT(d, DB_NOLOCKING);
9939 ADD_INT(d, DB_YIELDCPU);
9940 ADD_INT(d, DB_PANIC_ENVIRONMENT);
9941 ADD_INT(d, DB_NOPANIC);
Jesus Ceaef9764f2008-05-13 18:45:46 +00009942 ADD_INT(d, DB_OVERWRITE);
Jesus Cea6557aac2010-03-22 14:22:26 +00009943
Jesus Cea6557aac2010-03-22 14:22:26 +00009944 ADD_INT(d, DB_STAT_SUBSYSTEM);
9945 ADD_INT(d, DB_STAT_MEMP_HASH);
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009946 ADD_INT(d, DB_STAT_LOCK_CONF);
9947 ADD_INT(d, DB_STAT_LOCK_LOCKERS);
9948 ADD_INT(d, DB_STAT_LOCK_OBJECTS);
9949 ADD_INT(d, DB_STAT_LOCK_PARAMS);
Jesus Ceaef9764f2008-05-13 18:45:46 +00009950
Jesus Cea6557aac2010-03-22 14:22:26 +00009951#if (DBVER >= 48)
9952 ADD_INT(d, DB_OVERWRITE_DUP);
9953#endif
9954
9955#if (DBVER >= 47)
9956 ADD_INT(d, DB_FOREIGN_ABORT);
9957 ADD_INT(d, DB_FOREIGN_CASCADE);
9958 ADD_INT(d, DB_FOREIGN_NULLIFY);
9959#endif
9960
9961#if (DBVER >= 44)
Gregory P. Smithaae141a2007-11-01 21:08:14 +00009962 ADD_INT(d, DB_REGISTER);
9963#endif
9964
Jesus Cea6557aac2010-03-22 14:22:26 +00009965 ADD_INT(d, DB_EID_INVALID);
9966 ADD_INT(d, DB_EID_BROADCAST);
9967
Gregory P. Smith41631e82003-09-21 00:08:14 +00009968 ADD_INT(d, DB_TIME_NOTGRANTED);
9969 ADD_INT(d, DB_TXN_NOT_DURABLE);
9970 ADD_INT(d, DB_TXN_WRITE_NOSYNC);
Gregory P. Smith41631e82003-09-21 00:08:14 +00009971 ADD_INT(d, DB_DIRECT_DB);
9972 ADD_INT(d, DB_INIT_REP);
9973 ADD_INT(d, DB_ENCRYPT);
9974 ADD_INT(d, DB_CHKSUM);
Gregory P. Smith41631e82003-09-21 00:08:14 +00009975
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009976#if (DBVER < 47)
Jesus Ceaca3939c2008-05-22 15:27:38 +00009977 ADD_INT(d, DB_LOG_AUTOREMOVE);
9978 ADD_INT(d, DB_DIRECT_LOG);
9979#endif
9980
9981#if (DBVER >= 47)
9982 ADD_INT(d, DB_LOG_DIRECT);
9983 ADD_INT(d, DB_LOG_DSYNC);
9984 ADD_INT(d, DB_LOG_IN_MEMORY);
9985 ADD_INT(d, DB_LOG_AUTO_REMOVE);
9986 ADD_INT(d, DB_LOG_ZERO);
9987#endif
9988
Jesus Ceaef9764f2008-05-13 18:45:46 +00009989#if (DBVER >= 44)
9990 ADD_INT(d, DB_DSYNC_DB);
9991#endif
9992
9993#if (DBVER >= 45)
9994 ADD_INT(d, DB_TXN_SNAPSHOT);
9995#endif
9996
Jesus Ceaef9764f2008-05-13 18:45:46 +00009997 ADD_INT(d, DB_VERB_DEADLOCK);
9998#if (DBVER >= 46)
9999 ADD_INT(d, DB_VERB_FILEOPS);
10000 ADD_INT(d, DB_VERB_FILEOPS_ALL);
10001#endif
10002 ADD_INT(d, DB_VERB_RECOVERY);
10003#if (DBVER >= 44)
10004 ADD_INT(d, DB_VERB_REGISTER);
10005#endif
10006 ADD_INT(d, DB_VERB_REPLICATION);
10007 ADD_INT(d, DB_VERB_WAITSFOR);
Jesus Ceaef9764f2008-05-13 18:45:46 +000010008
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010009#if (DBVER >= 50)
10010 ADD_INT(d, DB_VERB_REP_SYSTEM);
10011#endif
10012
10013#if (DBVER >= 47)
10014 ADD_INT(d, DB_VERB_REP_ELECT);
10015 ADD_INT(d, DB_VERB_REP_LEASE);
10016 ADD_INT(d, DB_VERB_REP_MISC);
10017 ADD_INT(d, DB_VERB_REP_MSGS);
10018 ADD_INT(d, DB_VERB_REP_SYNC);
10019 ADD_INT(d, DB_VERB_REPMGR_CONNFAIL);
10020 ADD_INT(d, DB_VERB_REPMGR_MISC);
10021#endif
10022
Jesus Ceaef9764f2008-05-13 18:45:46 +000010023#if (DBVER >= 45)
10024 ADD_INT(d, DB_EVENT_PANIC);
10025 ADD_INT(d, DB_EVENT_REP_CLIENT);
10026#if (DBVER >= 46)
10027 ADD_INT(d, DB_EVENT_REP_ELECTED);
10028#endif
10029 ADD_INT(d, DB_EVENT_REP_MASTER);
10030 ADD_INT(d, DB_EVENT_REP_NEWMASTER);
10031#if (DBVER >= 46)
10032 ADD_INT(d, DB_EVENT_REP_PERM_FAILED);
10033#endif
10034 ADD_INT(d, DB_EVENT_REP_STARTUPDONE);
10035 ADD_INT(d, DB_EVENT_WRITE_FAILED);
10036#endif
10037
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010038#if (DBVER >= 50)
10039 ADD_INT(d, DB_REPMGR_CONF_ELECTIONS);
10040 ADD_INT(d, DB_EVENT_REP_MASTER_FAILURE);
10041 ADD_INT(d, DB_EVENT_REP_DUPMASTER);
10042 ADD_INT(d, DB_EVENT_REP_ELECTION_FAILED);
10043#endif
10044#if (DBVER >= 48)
10045 ADD_INT(d, DB_EVENT_REG_ALIVE);
10046 ADD_INT(d, DB_EVENT_REG_PANIC);
10047#endif
10048
10049#if (DBVER >=52)
10050 ADD_INT(d, DB_EVENT_REP_SITE_ADDED);
10051 ADD_INT(d, DB_EVENT_REP_SITE_REMOVED);
10052 ADD_INT(d, DB_EVENT_REP_LOCAL_SITE_REMOVED);
10053 ADD_INT(d, DB_EVENT_REP_CONNECT_BROKEN);
10054 ADD_INT(d, DB_EVENT_REP_CONNECT_ESTD);
10055 ADD_INT(d, DB_EVENT_REP_CONNECT_TRY_FAILED);
10056 ADD_INT(d, DB_EVENT_REP_INIT_DONE);
10057
10058 ADD_INT(d, DB_MEM_LOCK);
10059 ADD_INT(d, DB_MEM_LOCKOBJECT);
10060 ADD_INT(d, DB_MEM_LOCKER);
10061 ADD_INT(d, DB_MEM_LOGID);
10062 ADD_INT(d, DB_MEM_TRANSACTION);
10063 ADD_INT(d, DB_MEM_THREAD);
10064
10065 ADD_INT(d, DB_BOOTSTRAP_HELPER);
10066 ADD_INT(d, DB_GROUP_CREATOR);
10067 ADD_INT(d, DB_LEGACY);
10068 ADD_INT(d, DB_LOCAL_SITE);
10069 ADD_INT(d, DB_REPMGR_PEER);
10070#endif
10071
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010072 ADD_INT(d, DB_REP_DUPMASTER);
10073 ADD_INT(d, DB_REP_HOLDELECTION);
10074#if (DBVER >= 44)
10075 ADD_INT(d, DB_REP_IGNORE);
10076 ADD_INT(d, DB_REP_JOIN_FAILURE);
10077#endif
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010078 ADD_INT(d, DB_REP_ISPERM);
10079 ADD_INT(d, DB_REP_NOTPERM);
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010080 ADD_INT(d, DB_REP_NEWSITE);
10081
Jesus Ceaef9764f2008-05-13 18:45:46 +000010082 ADD_INT(d, DB_REP_MASTER);
10083 ADD_INT(d, DB_REP_CLIENT);
Jesus Cea6557aac2010-03-22 14:22:26 +000010084
10085 ADD_INT(d, DB_REP_PERMANENT);
10086
10087#if (DBVER >= 44)
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010088#if (DBVER >= 50)
10089 ADD_INT(d, DB_REP_CONF_AUTOINIT);
10090#else
Jesus Cea6557aac2010-03-22 14:22:26 +000010091 ADD_INT(d, DB_REP_CONF_NOAUTOINIT);
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010092#endif /* 5.0 */
10093#endif /* 4.4 */
10094#if (DBVER >= 44)
Jesus Cea6557aac2010-03-22 14:22:26 +000010095 ADD_INT(d, DB_REP_CONF_DELAYCLIENT);
10096 ADD_INT(d, DB_REP_CONF_BULK);
10097 ADD_INT(d, DB_REP_CONF_NOWAIT);
10098 ADD_INT(d, DB_REP_ANYWHERE);
10099 ADD_INT(d, DB_REP_REREQUEST);
10100#endif
10101
Jesus Cea6557aac2010-03-22 14:22:26 +000010102 ADD_INT(d, DB_REP_NOBUFFER);
Jesus Cea6557aac2010-03-22 14:22:26 +000010103
10104#if (DBVER >= 46)
10105 ADD_INT(d, DB_REP_LEASE_EXPIRED);
10106 ADD_INT(d, DB_IGNORE_LEASE);
10107#endif
10108
10109#if (DBVER >= 47)
10110 ADD_INT(d, DB_REP_CONF_LEASE);
10111 ADD_INT(d, DB_REPMGR_CONF_2SITE_STRICT);
10112#endif
10113
Jesus Ceaef9764f2008-05-13 18:45:46 +000010114#if (DBVER >= 45)
10115 ADD_INT(d, DB_REP_ELECTION);
10116
10117 ADD_INT(d, DB_REP_ACK_TIMEOUT);
10118 ADD_INT(d, DB_REP_CONNECTION_RETRY);
10119 ADD_INT(d, DB_REP_ELECTION_TIMEOUT);
10120 ADD_INT(d, DB_REP_ELECTION_RETRY);
10121#endif
10122#if (DBVER >= 46)
10123 ADD_INT(d, DB_REP_CHECKPOINT_DELAY);
10124 ADD_INT(d, DB_REP_FULL_ELECTION_TIMEOUT);
Jesus Cea6557aac2010-03-22 14:22:26 +000010125 ADD_INT(d, DB_REP_LEASE_TIMEOUT);
10126#endif
10127#if (DBVER >= 47)
10128 ADD_INT(d, DB_REP_HEARTBEAT_MONITOR);
10129 ADD_INT(d, DB_REP_HEARTBEAT_SEND);
Jesus Ceaef9764f2008-05-13 18:45:46 +000010130#endif
Jesus Ceaef9764f2008-05-13 18:45:46 +000010131
10132#if (DBVER >= 45)
10133 ADD_INT(d, DB_REPMGR_PEER);
10134 ADD_INT(d, DB_REPMGR_ACKS_ALL);
10135 ADD_INT(d, DB_REPMGR_ACKS_ALL_PEERS);
10136 ADD_INT(d, DB_REPMGR_ACKS_NONE);
10137 ADD_INT(d, DB_REPMGR_ACKS_ONE);
10138 ADD_INT(d, DB_REPMGR_ACKS_ONE_PEER);
10139 ADD_INT(d, DB_REPMGR_ACKS_QUORUM);
10140 ADD_INT(d, DB_REPMGR_CONNECTED);
10141 ADD_INT(d, DB_REPMGR_DISCONNECTED);
Jesus Ceaef9764f2008-05-13 18:45:46 +000010142 ADD_INT(d, DB_STAT_ALL);
10143#endif
10144
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010145#if (DBVER >= 51)
10146 ADD_INT(d, DB_REPMGR_ACKS_ALL_AVAILABLE);
10147#endif
10148
10149#if (DBVER >= 48)
10150 ADD_INT(d, DB_REP_CONF_INMEM);
10151#endif
10152
10153 ADD_INT(d, DB_TIMEOUT);
10154
10155#if (DBVER >= 50)
10156 ADD_INT(d, DB_FORCESYNC);
10157#endif
10158
10159#if (DBVER >= 48)
10160 ADD_INT(d, DB_FAILCHK);
10161#endif
10162
10163#if (DBVER >= 51)
10164 ADD_INT(d, DB_HOTBACKUP_IN_PROGRESS);
10165#endif
10166
Gregory P. Smith8b7e9172004-12-13 09:51:23 +000010167 ADD_INT(d, DB_BUFFER_SMALL);
Gregory P. Smithf0547d02006-06-05 17:38:04 +000010168 ADD_INT(d, DB_SEQ_DEC);
10169 ADD_INT(d, DB_SEQ_INC);
10170 ADD_INT(d, DB_SEQ_WRAP);
Gregory P. Smith8b7e9172004-12-13 09:51:23 +000010171
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010172#if (DBVER < 47)
Jesus Ceaca3939c2008-05-22 15:27:38 +000010173 ADD_INT(d, DB_LOG_INMEMORY);
10174 ADD_INT(d, DB_DSYNC_LOG);
10175#endif
10176
Barry Warsaw9a0d7792002-12-30 20:53:52 +000010177 ADD_INT(d, DB_ENCRYPT_AES);
10178 ADD_INT(d, DB_AUTO_COMMIT);
Jesus Cea6557aac2010-03-22 14:22:26 +000010179 ADD_INT(d, DB_PRIORITY_VERY_LOW);
10180 ADD_INT(d, DB_PRIORITY_LOW);
10181 ADD_INT(d, DB_PRIORITY_DEFAULT);
10182 ADD_INT(d, DB_PRIORITY_HIGH);
10183 ADD_INT(d, DB_PRIORITY_VERY_HIGH);
10184
10185#if (DBVER >= 46)
10186 ADD_INT(d, DB_PRIORITY_UNCHANGED);
Barry Warsaw9a0d7792002-12-30 20:53:52 +000010187#endif
10188
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010189 ADD_INT(d, EINVAL);
10190 ADD_INT(d, EACCES);
10191 ADD_INT(d, ENOSPC);
10192 ADD_INT(d, ENOMEM);
10193 ADD_INT(d, EAGAIN);
10194 ADD_INT(d, EBUSY);
10195 ADD_INT(d, EEXIST);
10196 ADD_INT(d, ENOENT);
10197 ADD_INT(d, EPERM);
10198
Barry Warsaw1baa9822003-03-31 19:51:29 +000010199 ADD_INT(d, DB_SET_LOCK_TIMEOUT);
10200 ADD_INT(d, DB_SET_TXN_TIMEOUT);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010201
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010202#if (DBVER >= 48)
10203 ADD_INT(d, DB_SET_REG_TIMEOUT);
10204#endif
10205
Gregory P. Smith7f5b6f42006-04-08 07:10:51 +000010206 /* The exception name must be correct for pickled exception *
10207 * objects to unpickle properly. */
10208#ifdef PYBSDDB_STANDALONE /* different value needed for standalone pybsddb */
10209#define PYBSDDB_EXCEPTION_BASE "bsddb3.db."
10210#else
10211#define PYBSDDB_EXCEPTION_BASE "bsddb.db."
10212#endif
10213
10214 /* All the rest of the exceptions derive only from DBError */
10215#define MAKE_EX(name) name = PyErr_NewException(PYBSDDB_EXCEPTION_BASE #name, DBError, NULL); \
10216 PyDict_SetItemString(d, #name, name)
10217
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010218 /* The base exception class is DBError */
Gregory P. Smith7f5b6f42006-04-08 07:10:51 +000010219 DBError = NULL; /* used in MAKE_EX so that it derives from nothing */
10220 MAKE_EX(DBError);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010221
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010222#if (PY_VERSION_HEX < 0x03000000)
Gregory P. Smithe9477062005-06-04 06:46:59 +000010223 /* Some magic to make DBNotFoundError and DBKeyEmptyError derive
10224 * from both DBError and KeyError, since the API only supports
10225 * using one base class. */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010226 PyDict_SetItemString(d, "KeyError", PyExc_KeyError);
Gregory P. Smithe9477062005-06-04 06:46:59 +000010227 PyRun_String("class DBNotFoundError(DBError, KeyError): pass\n"
Antoine Pitrouc83ea132010-05-09 14:46:46 +000010228 "class DBKeyEmptyError(DBError, KeyError): pass",
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010229 Py_file_input, d, d);
10230 DBNotFoundError = PyDict_GetItemString(d, "DBNotFoundError");
Gregory P. Smithe9477062005-06-04 06:46:59 +000010231 DBKeyEmptyError = PyDict_GetItemString(d, "DBKeyEmptyError");
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010232 PyDict_DelItemString(d, "KeyError");
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010233#else
10234 /* Since Python 2.5, PyErr_NewException() accepts a tuple, to be able to
10235 ** derive from several classes. We use this new API only for Python 3.0,
10236 ** though.
10237 */
10238 {
10239 PyObject* bases;
10240
10241 bases = PyTuple_Pack(2, DBError, PyExc_KeyError);
10242
10243#define MAKE_EX2(name) name = PyErr_NewException(PYBSDDB_EXCEPTION_BASE #name, bases, NULL); \
10244 PyDict_SetItemString(d, #name, name)
10245 MAKE_EX2(DBNotFoundError);
10246 MAKE_EX2(DBKeyEmptyError);
10247
10248#undef MAKE_EX2
10249
10250 Py_XDECREF(bases);
10251 }
10252#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010253
Gregory P. Smithe2767172003-11-02 08:06:29 +000010254 MAKE_EX(DBCursorClosedError);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010255 MAKE_EX(DBKeyExistError);
10256 MAKE_EX(DBLockDeadlockError);
10257 MAKE_EX(DBLockNotGrantedError);
10258 MAKE_EX(DBOldVersionError);
10259 MAKE_EX(DBRunRecoveryError);
10260 MAKE_EX(DBVerifyBadError);
10261 MAKE_EX(DBNoServerError);
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010262#if (DBVER < 52)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010263 MAKE_EX(DBNoServerHomeError);
10264 MAKE_EX(DBNoServerIDError);
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010265#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010266 MAKE_EX(DBPageNotFoundError);
10267 MAKE_EX(DBSecondaryBadError);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010268
10269 MAKE_EX(DBInvalidArgError);
10270 MAKE_EX(DBAccessError);
10271 MAKE_EX(DBNoSpaceError);
10272 MAKE_EX(DBNoMemoryError);
10273 MAKE_EX(DBAgainError);
10274 MAKE_EX(DBBusyError);
10275 MAKE_EX(DBFileExistsError);
10276 MAKE_EX(DBNoSuchFileError);
10277 MAKE_EX(DBPermissionsError);
10278
Jesus Ceaef9764f2008-05-13 18:45:46 +000010279 MAKE_EX(DBRepHandleDeadError);
Jesus Cea6557aac2010-03-22 14:22:26 +000010280#if (DBVER >= 44)
10281 MAKE_EX(DBRepLockoutError);
10282#endif
Jesus Ceaef9764f2008-05-13 18:45:46 +000010283
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010284 MAKE_EX(DBRepUnavailError);
10285
Jesus Cea6557aac2010-03-22 14:22:26 +000010286#if (DBVER >= 46)
10287 MAKE_EX(DBRepLeaseExpiredError);
10288#endif
10289
10290#if (DBVER >= 47)
10291 MAKE_EX(DBForeignConflictError);
10292#endif
10293
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010294#undef MAKE_EX
10295
Jesus Cea6557aac2010-03-22 14:22:26 +000010296 /* Initialise the C API structure and add it to the module */
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010297 bsddb_api.api_version = PYBSDDB_API_VERSION;
Jesus Cea6557aac2010-03-22 14:22:26 +000010298 bsddb_api.db_type = &DB_Type;
10299 bsddb_api.dbcursor_type = &DBCursor_Type;
10300 bsddb_api.dblogcursor_type = &DBLogCursor_Type;
10301 bsddb_api.dbenv_type = &DBEnv_Type;
10302 bsddb_api.dbtxn_type = &DBTxn_Type;
10303 bsddb_api.dblock_type = &DBLock_Type;
Jesus Cea6557aac2010-03-22 14:22:26 +000010304 bsddb_api.dbsequence_type = &DBSequence_Type;
Jesus Cea6557aac2010-03-22 14:22:26 +000010305 bsddb_api.makeDBError = makeDBError;
Gregory P. Smith39250532007-10-09 06:02:21 +000010306
Jesus Cea6557aac2010-03-22 14:22:26 +000010307 /*
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010308 ** Capsules exist from Python 2.7 and 3.1.
10309 ** We don't support Python 3.0 anymore, so...
10310 ** #if (PY_VERSION_HEX < ((PY_MAJOR_VERSION < 3) ? 0x02070000 : 0x03020000))
Jesus Cea6557aac2010-03-22 14:22:26 +000010311 */
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010312#if (PY_VERSION_HEX < 0x02070000)
Gregory P. Smith39250532007-10-09 06:02:21 +000010313 py_api = PyCObject_FromVoidPtr((void*)&bsddb_api, NULL);
Jesus Cea6557aac2010-03-22 14:22:26 +000010314#else
10315 {
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010316 /*
10317 ** The data must outlive the call!!. So, the static definition.
10318 ** The buffer must be big enough...
10319 */
10320 static char py_api_name[MODULE_NAME_MAX_LEN+10];
Jesus Cea6557aac2010-03-22 14:22:26 +000010321
10322 strcpy(py_api_name, _bsddbModuleName);
10323 strcat(py_api_name, ".api");
10324
10325 py_api = PyCapsule_New((void*)&bsddb_api, py_api_name, NULL);
10326 }
10327#endif
10328
Jesus Cea84f2c322010-11-05 00:13:50 +000010329 /* Check error control */
10330 /*
10331 ** PyErr_NoMemory();
10332 ** py_api = NULL;
10333 */
10334
10335 if (py_api) {
10336 PyDict_SetItemString(d, "api", py_api);
10337 Py_DECREF(py_api);
10338 } else { /* Something bad happened */
10339 PyErr_WriteUnraisable(m);
Jesus Ceabf088f82010-11-08 12:57:59 +000010340 if(PyErr_Warn(PyExc_RuntimeWarning,
10341 "_bsddb/_pybsddb C API will be not available")) {
10342 PyErr_WriteUnraisable(m);
10343 }
Jesus Cea84f2c322010-11-05 00:13:50 +000010344 PyErr_Clear();
10345 }
Gregory P. Smith39250532007-10-09 06:02:21 +000010346
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010347 /* Check for errors */
10348 if (PyErr_Occurred()) {
10349 PyErr_Print();
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010350 Py_FatalError("can't initialize module _bsddb/_pybsddb");
10351 Py_DECREF(m);
10352 m = NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010353 }
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010354#if (PY_VERSION_HEX < 0x03000000)
10355 return;
10356#else
10357 return m;
10358#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010359}
Gregory P. Smith41631e82003-09-21 00:08:14 +000010360
10361/* allow this module to be named _pybsddb so that it can be installed
10362 * and imported on top of python >= 2.3 that includes its own older
10363 * copy of the library named _bsddb without importing the old version. */
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010364#if (PY_VERSION_HEX < 0x03000000)
Gregory P. Smith41631e82003-09-21 00:08:14 +000010365DL_EXPORT(void) init_pybsddb(void)
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010366#else
10367PyMODINIT_FUNC PyInit__pybsddb(void) /* Note the two underscores */
10368#endif
Gregory P. Smith41631e82003-09-21 00:08:14 +000010369{
10370 strncpy(_bsddbModuleName, "_pybsddb", MODULE_NAME_MAX_LEN);
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010371#if (PY_VERSION_HEX < 0x03000000)
Gregory P. Smith41631e82003-09-21 00:08:14 +000010372 init_bsddb();
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010373#else
10374 return PyInit__bsddb(); /* Note the two underscores */
10375#endif
Gregory P. Smith41631e82003-09-21 00:08:14 +000010376}