blob: 6a1c188cbd963905b256b8ad9269e2ed7a7d7887 [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);
2300 return NULL;
2301 }
2302 cursors[x] = ((DBCursorObject*)item)->dbc;
Thomas Woutersb2820ae2006-03-12 00:01:38 +00002303 Py_DECREF(item);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002304 }
2305
2306 MYDB_BEGIN_ALLOW_THREADS;
2307 err = self->db->join(self->db, cursors, &dbc, flags);
2308 MYDB_END_ALLOW_THREADS;
2309 free(cursors);
2310 RETURN_IF_ERR();
2311
Gregory P. Smith7441e652003-11-03 21:35:31 +00002312 /* FIXME: this is a buggy interface. The returned cursor
2313 contains internal references to the passed in cursors
2314 but does not hold python references to them or prevent
2315 them from being closed prematurely. This can cause
2316 python to crash when things are done in the wrong order. */
Jesus Ceaef9764f2008-05-13 18:45:46 +00002317 return (PyObject*) newDBCursorObject(dbc, NULL, self);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002318}
2319
2320
2321static PyObject*
2322DB_key_range(DBObject* self, PyObject* args, PyObject* kwargs)
2323{
2324 int err, flags=0;
2325 PyObject* txnobj = NULL;
2326 PyObject* keyobj;
2327 DBT key;
2328 DB_TXN *txn = NULL;
2329 DB_KEY_RANGE range;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002330 static char* kwnames[] = { "key", "txn", "flags", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002331
2332 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|Oi:key_range", kwnames,
2333 &keyobj, &txnobj, &flags))
2334 return NULL;
2335 CHECK_DB_NOT_CLOSED(self);
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002336 if (!make_dbt(keyobj, &key))
2337 /* BTree only, don't need to allow for an int key */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002338 return NULL;
2339 if (!checkTxnObj(txnobj, &txn))
2340 return NULL;
2341
2342 MYDB_BEGIN_ALLOW_THREADS;
2343 err = self->db->key_range(self->db, txn, &key, &range, flags);
2344 MYDB_END_ALLOW_THREADS;
2345
2346 RETURN_IF_ERR();
2347 return Py_BuildValue("ddd", range.less, range.equal, range.greater);
2348}
2349
2350
2351static PyObject*
2352DB_open(DBObject* self, PyObject* args, PyObject* kwargs)
2353{
2354 int err, type = DB_UNKNOWN, flags=0, mode=0660;
2355 char* filename = NULL;
2356 char* dbname = NULL;
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002357 PyObject *txnobj = NULL;
2358 DB_TXN *txn = NULL;
2359 /* with dbname */
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002360 static char* kwnames[] = {
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002361 "filename", "dbname", "dbtype", "flags", "mode", "txn", NULL};
2362 /* without dbname */
Tim Peters85b10522006-02-28 18:33:35 +00002363 static char* kwnames_basic[] = {
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002364 "filename", "dbtype", "flags", "mode", "txn", NULL};
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002365
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002366 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "z|ziiiO:open", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002367 &filename, &dbname, &type, &flags, &mode,
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002368 &txnobj))
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002369 {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002370 PyErr_Clear();
2371 type = DB_UNKNOWN; flags = 0; mode = 0660;
2372 filename = NULL; dbname = NULL;
2373 if (!PyArg_ParseTupleAndKeywords(args, kwargs,"z|iiiO:open",
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002374 kwnames_basic,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002375 &filename, &type, &flags, &mode,
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002376 &txnobj))
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002377 return NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002378 }
2379
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002380 if (!checkTxnObj(txnobj, &txn)) return NULL;
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002381
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002382 if (NULL == self->db) {
Thomas Woutersb3153832006-03-08 01:47:19 +00002383 PyObject *t = Py_BuildValue("(is)", 0,
2384 "Cannot call open() twice for DB object");
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002385 if (t) {
2386 PyErr_SetObject(DBError, t);
2387 Py_DECREF(t);
2388 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002389 return NULL;
2390 }
2391
Jesus Ceaef9764f2008-05-13 18:45:46 +00002392 if (txn) { /* Can't use 'txnobj' because could be 'txnobj==Py_None' */
2393 INSERT_IN_DOUBLE_LINKED_LIST_TXN(((DBTxnObject *)txnobj)->children_dbs,self);
2394 self->txn=(DBTxnObject *)txnobj;
2395 } else {
2396 self->txn=NULL;
2397 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00002398
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002399 MYDB_BEGIN_ALLOW_THREADS;
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002400 err = self->db->open(self->db, txn, filename, dbname, type, flags, mode);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002401 MYDB_END_ALLOW_THREADS;
Jesus Cea6557aac2010-03-22 14:22:26 +00002402
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002403 if (makeDBError(err)) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00002404 PyObject *dummy;
2405
Jesus Cea5cd5f122008-09-23 18:54:08 +00002406 dummy=DB_close_internal(self, 0, 0);
Jesus Ceaef9764f2008-05-13 18:45:46 +00002407 Py_XDECREF(dummy);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002408 return NULL;
2409 }
2410
Gregory P. Smithec10a4a2007-11-05 02:32:26 +00002411 self->db->get_flags(self->db, &self->setflags);
2412
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002413 self->flags = flags;
Jesus Ceaef9764f2008-05-13 18:45:46 +00002414
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002415 RETURN_NONE();
2416}
2417
2418
2419static PyObject*
2420DB_put(DBObject* self, PyObject* args, PyObject* kwargs)
2421{
2422 int flags=0;
2423 PyObject* txnobj = NULL;
2424 int dlen = -1;
2425 int doff = -1;
2426 PyObject* keyobj, *dataobj, *retval;
2427 DBT key, data;
2428 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002429 static char* kwnames[] = { "key", "data", "txn", "flags", "dlen",
Jeremy Hyltonaf68c872005-12-10 18:50:16 +00002430 "doff", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002431
2432 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|Oiii:put", kwnames,
2433 &keyobj, &dataobj, &txnobj, &flags, &dlen, &doff))
2434 return NULL;
2435
2436 CHECK_DB_NOT_CLOSED(self);
Gregory P. Smithdc5af702004-06-27 23:32:34 +00002437 if (!make_key_dbt(self, keyobj, &key, NULL))
2438 return NULL;
2439 if ( !make_dbt(dataobj, &data) ||
2440 !add_partial_dbt(&data, dlen, doff) ||
2441 !checkTxnObj(txnobj, &txn) )
2442 {
2443 FREE_DBT(key);
2444 return NULL;
2445 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002446
2447 if (-1 == _DB_put(self, txn, &key, &data, flags)) {
2448 FREE_DBT(key);
2449 return NULL;
2450 }
2451
2452 if (flags & DB_APPEND)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002453 retval = NUMBER_FromLong(*((db_recno_t*)key.data));
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002454 else {
2455 retval = Py_None;
2456 Py_INCREF(retval);
2457 }
2458 FREE_DBT(key);
2459 return retval;
2460}
2461
2462
2463
2464static PyObject*
2465DB_remove(DBObject* self, PyObject* args, PyObject* kwargs)
2466{
2467 char* filename;
2468 char* database = NULL;
2469 int err, flags=0;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002470 static char* kwnames[] = { "filename", "dbname", "flags", NULL};
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002471
2472 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|zi:remove", kwnames,
2473 &filename, &database, &flags))
2474 return NULL;
2475 CHECK_DB_NOT_CLOSED(self);
2476
Jesus Cea4907d272008-08-31 14:00:51 +00002477 EXTRACT_FROM_DOUBLE_LINKED_LIST_MAYBE_NULL(self);
2478
2479 MYDB_BEGIN_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002480 err = self->db->remove(self->db, filename, database, flags);
Jesus Cea4907d272008-08-31 14:00:51 +00002481 MYDB_END_ALLOW_THREADS;
2482
Gregory P. Smithf655dff2003-05-15 00:13:18 +00002483 self->db = NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002484 RETURN_IF_ERR();
2485 RETURN_NONE();
2486}
2487
2488
2489
2490static PyObject*
2491DB_rename(DBObject* self, PyObject* args)
2492{
2493 char* filename;
2494 char* database;
2495 char* newname;
2496 int err, flags=0;
2497
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002498 if (!PyArg_ParseTuple(args, "sss|i:rename", &filename, &database, &newname,
2499 &flags))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002500 return NULL;
2501 CHECK_DB_NOT_CLOSED(self);
2502
2503 MYDB_BEGIN_ALLOW_THREADS;
2504 err = self->db->rename(self->db, filename, database, newname, flags);
2505 MYDB_END_ALLOW_THREADS;
2506 RETURN_IF_ERR();
2507 RETURN_NONE();
2508}
2509
2510
2511static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002512DB_get_private(DBObject* self)
2513{
2514 /* We can give out the private field even if db is closed */
Jesus Cea4907d272008-08-31 14:00:51 +00002515 Py_INCREF(self->private_obj);
2516 return self->private_obj;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002517}
2518
2519static PyObject*
Jesus Cea4907d272008-08-31 14:00:51 +00002520DB_set_private(DBObject* self, PyObject* private_obj)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002521{
2522 /* We can set the private field even if db is closed */
Jesus Cea4907d272008-08-31 14:00:51 +00002523 Py_INCREF(private_obj);
Serhiy Storchaka763a61c2016-04-10 18:05:12 +03002524 Py_SETREF(self->private_obj, private_obj);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002525 RETURN_NONE();
2526}
2527
Jesus Cea6557aac2010-03-22 14:22:26 +00002528#if (DBVER >= 46)
2529static PyObject*
2530DB_set_priority(DBObject* self, PyObject* args)
2531{
2532 int err, priority;
2533
2534 if (!PyArg_ParseTuple(args,"i:set_priority", &priority))
2535 return NULL;
2536 CHECK_DB_NOT_CLOSED(self);
2537
2538 MYDB_BEGIN_ALLOW_THREADS;
2539 err = self->db->set_priority(self->db, priority);
2540 MYDB_END_ALLOW_THREADS;
2541 RETURN_IF_ERR();
2542 RETURN_NONE();
2543}
2544
2545static PyObject*
2546DB_get_priority(DBObject* self)
2547{
2548 int err = 0;
2549 DB_CACHE_PRIORITY priority;
2550
2551 CHECK_DB_NOT_CLOSED(self);
2552
2553 MYDB_BEGIN_ALLOW_THREADS;
2554 err = self->db->get_priority(self->db, &priority);
2555 MYDB_END_ALLOW_THREADS;
2556 RETURN_IF_ERR();
2557 return NUMBER_FromLong(priority);
2558}
2559#endif
2560
2561static PyObject*
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07002562DB_get_dbname(DBObject* self)
2563{
2564 int err;
2565 const char *filename, *dbname;
2566
2567 CHECK_DB_NOT_CLOSED(self);
2568
2569 MYDB_BEGIN_ALLOW_THREADS;
2570 err = self->db->get_dbname(self->db, &filename, &dbname);
2571 MYDB_END_ALLOW_THREADS;
2572 RETURN_IF_ERR();
2573 /* If "dbname==NULL", it is correctly converted to "None" */
2574 return Py_BuildValue("(ss)", filename, dbname);
2575}
2576
2577static PyObject*
2578DB_get_open_flags(DBObject* self)
2579{
2580 int err;
2581 unsigned int flags;
2582
2583 CHECK_DB_NOT_CLOSED(self);
2584
2585 MYDB_BEGIN_ALLOW_THREADS;
2586 err = self->db->get_open_flags(self->db, &flags);
2587 MYDB_END_ALLOW_THREADS;
2588 RETURN_IF_ERR();
2589 return NUMBER_FromLong(flags);
2590}
2591
2592static PyObject*
Jesus Cea6557aac2010-03-22 14:22:26 +00002593DB_set_q_extentsize(DBObject* self, PyObject* args)
2594{
2595 int err;
2596 u_int32_t extentsize;
2597
2598 if (!PyArg_ParseTuple(args,"i:set_q_extentsize", &extentsize))
2599 return NULL;
2600 CHECK_DB_NOT_CLOSED(self);
2601
2602 MYDB_BEGIN_ALLOW_THREADS;
2603 err = self->db->set_q_extentsize(self->db, extentsize);
2604 MYDB_END_ALLOW_THREADS;
2605 RETURN_IF_ERR();
2606 RETURN_NONE();
2607}
2608
Jesus Cea6557aac2010-03-22 14:22:26 +00002609static PyObject*
2610DB_get_q_extentsize(DBObject* self)
2611{
2612 int err = 0;
2613 u_int32_t extentsize;
2614
2615 CHECK_DB_NOT_CLOSED(self);
2616
2617 MYDB_BEGIN_ALLOW_THREADS;
2618 err = self->db->get_q_extentsize(self->db, &extentsize);
2619 MYDB_END_ALLOW_THREADS;
2620 RETURN_IF_ERR();
2621 return NUMBER_FromLong(extentsize);
2622}
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002623
2624static PyObject*
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002625DB_set_bt_minkey(DBObject* self, PyObject* args)
2626{
2627 int err, minkey;
2628
Jesus Cea6557aac2010-03-22 14:22:26 +00002629 if (!PyArg_ParseTuple(args,"i:set_bt_minkey", &minkey))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002630 return NULL;
2631 CHECK_DB_NOT_CLOSED(self);
2632
2633 MYDB_BEGIN_ALLOW_THREADS;
2634 err = self->db->set_bt_minkey(self->db, minkey);
2635 MYDB_END_ALLOW_THREADS;
2636 RETURN_IF_ERR();
2637 RETURN_NONE();
2638}
2639
Jesus Cea6557aac2010-03-22 14:22:26 +00002640static PyObject*
2641DB_get_bt_minkey(DBObject* self)
2642{
2643 int err;
2644 u_int32_t bt_minkey;
2645
2646 CHECK_DB_NOT_CLOSED(self);
2647
2648 MYDB_BEGIN_ALLOW_THREADS;
2649 err = self->db->get_bt_minkey(self->db, &bt_minkey);
2650 MYDB_END_ALLOW_THREADS;
2651 RETURN_IF_ERR();
2652 return NUMBER_FromLong(bt_minkey);
2653}
Jesus Cea6557aac2010-03-22 14:22:26 +00002654
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002655static int
Georg Brandlef1701f2006-03-07 14:57:48 +00002656_default_cmp(const DBT *leftKey,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002657 const DBT *rightKey)
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002658{
2659 int res;
2660 int lsize = leftKey->size, rsize = rightKey->size;
2661
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002662 res = memcmp(leftKey->data, rightKey->data,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002663 lsize < rsize ? lsize : rsize);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002664
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002665 if (res == 0) {
2666 if (lsize < rsize) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002667 res = -1;
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002668 }
2669 else if (lsize > rsize) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002670 res = 1;
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002671 }
2672 }
2673 return res;
2674}
2675
2676static int
Jesus Ceaef9764f2008-05-13 18:45:46 +00002677_db_compareCallback(DB* db,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002678 const DBT *leftKey,
2679 const DBT *rightKey)
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002680{
2681 int res = 0;
2682 PyObject *args;
Thomas Woutersb2820ae2006-03-12 00:01:38 +00002683 PyObject *result = NULL;
Georg Brandlef1701f2006-03-07 14:57:48 +00002684 DBObject *self = (DBObject *)db->app_private;
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002685
2686 if (self == NULL || self->btCompareCallback == NULL) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002687 MYDB_BEGIN_BLOCK_THREADS;
2688 PyErr_SetString(PyExc_TypeError,
2689 (self == 0
2690 ? "DB_bt_compare db is NULL."
2691 : "DB_bt_compare callback is NULL."));
2692 /* we're in a callback within the DB code, we can't raise */
2693 PyErr_Print();
2694 res = _default_cmp(leftKey, rightKey);
2695 MYDB_END_BLOCK_THREADS;
Georg Brandlef1701f2006-03-07 14:57:48 +00002696 } else {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002697 MYDB_BEGIN_BLOCK_THREADS;
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002698
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002699 args = BuildValue_SS(leftKey->data, leftKey->size, rightKey->data, rightKey->size);
2700 if (args != NULL) {
2701 result = PyEval_CallObject(self->btCompareCallback, args);
2702 }
2703 if (args == NULL || result == NULL) {
2704 /* we're in a callback within the DB code, we can't raise */
2705 PyErr_Print();
2706 res = _default_cmp(leftKey, rightKey);
2707 } else if (NUMBER_Check(result)) {
2708 res = NUMBER_AsLong(result);
2709 } else {
2710 PyErr_SetString(PyExc_TypeError,
2711 "DB_bt_compare callback MUST return an int.");
2712 /* we're in a callback within the DB code, we can't raise */
2713 PyErr_Print();
2714 res = _default_cmp(leftKey, rightKey);
2715 }
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002716
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002717 Py_XDECREF(args);
2718 Py_XDECREF(result);
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002719
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002720 MYDB_END_BLOCK_THREADS;
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002721 }
2722 return res;
2723}
2724
2725static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002726DB_set_bt_compare(DBObject* self, PyObject* comparator)
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002727{
2728 int err;
Thomas Woutersb3153832006-03-08 01:47:19 +00002729 PyObject *tuple, *result;
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002730
Georg Brandlef1701f2006-03-07 14:57:48 +00002731 CHECK_DB_NOT_CLOSED(self);
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002732
Georg Brandlef1701f2006-03-07 14:57:48 +00002733 if (!PyCallable_Check(comparator)) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002734 makeTypeError("Callable", comparator);
2735 return NULL;
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002736 }
2737
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002738 /*
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002739 * Perform a test call of the comparator function with two empty
2740 * string objects here. verify that it returns an int (0).
2741 * err if not.
2742 */
Thomas Woutersb3153832006-03-08 01:47:19 +00002743 tuple = Py_BuildValue("(ss)", "", "");
Georg Brandlef1701f2006-03-07 14:57:48 +00002744 result = PyEval_CallObject(comparator, tuple);
2745 Py_DECREF(tuple);
Thomas Woutersb3153832006-03-08 01:47:19 +00002746 if (result == NULL)
2747 return NULL;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002748 if (!NUMBER_Check(result)) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002749 Py_DECREF(result);
2750 PyErr_SetString(PyExc_TypeError,
2751 "callback MUST return an int");
2752 return NULL;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002753 } else if (NUMBER_AsLong(result) != 0) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002754 Py_DECREF(result);
2755 PyErr_SetString(PyExc_TypeError,
2756 "callback failed to return 0 on two empty strings");
2757 return NULL;
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002758 }
Thomas Woutersb3153832006-03-08 01:47:19 +00002759 Py_DECREF(result);
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002760
2761 /* We don't accept multiple set_bt_compare operations, in order to
2762 * simplify the code. This would have no real use, as one cannot
2763 * change the function once the db is opened anyway */
2764 if (self->btCompareCallback != NULL) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002765 PyErr_SetString(PyExc_RuntimeError, "set_bt_compare() cannot be called more than once");
2766 return NULL;
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002767 }
2768
Georg Brandlef1701f2006-03-07 14:57:48 +00002769 Py_INCREF(comparator);
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002770 self->btCompareCallback = comparator;
2771
2772 /* This is to workaround a problem with un-initialized threads (see
2773 comment in DB_associate) */
2774#ifdef WITH_THREAD
2775 PyEval_InitThreads();
2776#endif
2777
Thomas Woutersb3153832006-03-08 01:47:19 +00002778 err = self->db->set_bt_compare(self->db, _db_compareCallback);
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002779
2780 if (err) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002781 /* restore the old state in case of error */
2782 Py_DECREF(comparator);
2783 self->btCompareCallback = NULL;
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002784 }
2785
Georg Brandlef1701f2006-03-07 14:57:48 +00002786 RETURN_IF_ERR();
2787 RETURN_NONE();
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002788}
2789
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07002790static int
2791_db_dupCompareCallback(DB* db,
2792 const DBT *leftKey,
2793 const DBT *rightKey)
2794{
2795 int res = 0;
2796 PyObject *args;
2797 PyObject *result = NULL;
2798 DBObject *self = (DBObject *)db->app_private;
2799
2800 if (self == NULL || self->dupCompareCallback == NULL) {
2801 MYDB_BEGIN_BLOCK_THREADS;
2802 PyErr_SetString(PyExc_TypeError,
2803 (self == 0
2804 ? "DB_dup_compare db is NULL."
2805 : "DB_dup_compare callback is NULL."));
2806 /* we're in a callback within the DB code, we can't raise */
2807 PyErr_Print();
2808 res = _default_cmp(leftKey, rightKey);
2809 MYDB_END_BLOCK_THREADS;
2810 } else {
2811 MYDB_BEGIN_BLOCK_THREADS;
2812
2813 args = BuildValue_SS(leftKey->data, leftKey->size, rightKey->data, rightKey->size);
2814 if (args != NULL) {
2815 result = PyEval_CallObject(self->dupCompareCallback, args);
2816 }
2817 if (args == NULL || result == NULL) {
2818 /* we're in a callback within the DB code, we can't raise */
2819 PyErr_Print();
2820 res = _default_cmp(leftKey, rightKey);
2821 } else if (NUMBER_Check(result)) {
2822 res = NUMBER_AsLong(result);
2823 } else {
2824 PyErr_SetString(PyExc_TypeError,
2825 "DB_dup_compare callback MUST return an int.");
2826 /* we're in a callback within the DB code, we can't raise */
2827 PyErr_Print();
2828 res = _default_cmp(leftKey, rightKey);
2829 }
2830
2831 Py_XDECREF(args);
2832 Py_XDECREF(result);
2833
2834 MYDB_END_BLOCK_THREADS;
2835 }
2836 return res;
2837}
2838
2839static PyObject*
2840DB_set_dup_compare(DBObject* self, PyObject* comparator)
2841{
2842 int err;
2843 PyObject *tuple, *result;
2844
2845 CHECK_DB_NOT_CLOSED(self);
2846
2847 if (!PyCallable_Check(comparator)) {
2848 makeTypeError("Callable", comparator);
2849 return NULL;
2850 }
2851
2852 /*
2853 * Perform a test call of the comparator function with two empty
2854 * string objects here. verify that it returns an int (0).
2855 * err if not.
2856 */
2857 tuple = Py_BuildValue("(ss)", "", "");
2858 result = PyEval_CallObject(comparator, tuple);
2859 Py_DECREF(tuple);
2860 if (result == NULL)
2861 return NULL;
2862 if (!NUMBER_Check(result)) {
2863 Py_DECREF(result);
2864 PyErr_SetString(PyExc_TypeError,
2865 "callback MUST return an int");
2866 return NULL;
2867 } else if (NUMBER_AsLong(result) != 0) {
2868 Py_DECREF(result);
2869 PyErr_SetString(PyExc_TypeError,
2870 "callback failed to return 0 on two empty strings");
2871 return NULL;
2872 }
2873 Py_DECREF(result);
2874
2875 /* We don't accept multiple set_dup_compare operations, in order to
2876 * simplify the code. This would have no real use, as one cannot
2877 * change the function once the db is opened anyway */
2878 if (self->dupCompareCallback != NULL) {
2879 PyErr_SetString(PyExc_RuntimeError, "set_dup_compare() cannot be called more than once");
2880 return NULL;
2881 }
2882
2883 Py_INCREF(comparator);
2884 self->dupCompareCallback = comparator;
2885
2886 /* This is to workaround a problem with un-initialized threads (see
2887 comment in DB_associate) */
2888#ifdef WITH_THREAD
2889 PyEval_InitThreads();
2890#endif
2891
2892 err = self->db->set_dup_compare(self->db, _db_dupCompareCallback);
2893
2894 if (err) {
2895 /* restore the old state in case of error */
2896 Py_DECREF(comparator);
2897 self->dupCompareCallback = NULL;
2898 }
2899
2900 RETURN_IF_ERR();
2901 RETURN_NONE();
2902}
2903
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002904
2905static PyObject*
2906DB_set_cachesize(DBObject* self, PyObject* args)
2907{
2908 int err;
2909 int gbytes = 0, bytes = 0, ncache = 0;
2910
2911 if (!PyArg_ParseTuple(args,"ii|i:set_cachesize",
2912 &gbytes,&bytes,&ncache))
2913 return NULL;
2914 CHECK_DB_NOT_CLOSED(self);
2915
2916 MYDB_BEGIN_ALLOW_THREADS;
2917 err = self->db->set_cachesize(self->db, gbytes, bytes, ncache);
2918 MYDB_END_ALLOW_THREADS;
2919 RETURN_IF_ERR();
2920 RETURN_NONE();
2921}
2922
Jesus Cea6557aac2010-03-22 14:22:26 +00002923static PyObject*
2924DB_get_cachesize(DBObject* self)
2925{
2926 int err;
2927 u_int32_t gbytes, bytes;
2928 int ncache;
2929
2930 CHECK_DB_NOT_CLOSED(self);
2931
2932 MYDB_BEGIN_ALLOW_THREADS;
2933 err = self->db->get_cachesize(self->db, &gbytes, &bytes, &ncache);
2934 MYDB_END_ALLOW_THREADS;
2935
2936 RETURN_IF_ERR();
2937
2938 return Py_BuildValue("(iii)", gbytes, bytes, ncache);
2939}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002940
2941static PyObject*
2942DB_set_flags(DBObject* self, PyObject* args)
2943{
2944 int err, flags;
2945
2946 if (!PyArg_ParseTuple(args,"i:set_flags", &flags))
2947 return NULL;
2948 CHECK_DB_NOT_CLOSED(self);
2949
2950 MYDB_BEGIN_ALLOW_THREADS;
2951 err = self->db->set_flags(self->db, flags);
2952 MYDB_END_ALLOW_THREADS;
2953 RETURN_IF_ERR();
2954
2955 self->setflags |= flags;
2956 RETURN_NONE();
2957}
2958
Jesus Cea6557aac2010-03-22 14:22:26 +00002959static PyObject*
2960DB_get_flags(DBObject* self)
2961{
2962 int err;
2963 u_int32_t flags;
2964
2965 CHECK_DB_NOT_CLOSED(self);
2966
2967 MYDB_BEGIN_ALLOW_THREADS;
2968 err = self->db->get_flags(self->db, &flags);
2969 MYDB_END_ALLOW_THREADS;
2970 RETURN_IF_ERR();
2971 return NUMBER_FromLong(flags);
2972}
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07002973
2974static PyObject*
2975DB_get_transactional(DBObject* self)
2976{
2977 int err;
2978
2979 CHECK_DB_NOT_CLOSED(self);
2980
2981 MYDB_BEGIN_ALLOW_THREADS;
2982 err = self->db->get_transactional(self->db);
2983 MYDB_END_ALLOW_THREADS;
2984
2985 if(err == 0) {
2986 Py_INCREF(Py_False);
2987 return Py_False;
2988 } else if(err == 1) {
2989 Py_INCREF(Py_True);
2990 return Py_True;
2991 }
2992
2993 /*
2994 ** If we reach there, there was an error. The
2995 ** "return" should be unreachable.
2996 */
2997 RETURN_IF_ERR();
2998 assert(0); /* This code SHOULD be unreachable */
2999 return NULL;
3000}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003001
3002static PyObject*
3003DB_set_h_ffactor(DBObject* self, PyObject* args)
3004{
3005 int err, ffactor;
3006
3007 if (!PyArg_ParseTuple(args,"i:set_h_ffactor", &ffactor))
3008 return NULL;
3009 CHECK_DB_NOT_CLOSED(self);
3010
3011 MYDB_BEGIN_ALLOW_THREADS;
3012 err = self->db->set_h_ffactor(self->db, ffactor);
3013 MYDB_END_ALLOW_THREADS;
3014 RETURN_IF_ERR();
3015 RETURN_NONE();
3016}
3017
Jesus Cea6557aac2010-03-22 14:22:26 +00003018static PyObject*
3019DB_get_h_ffactor(DBObject* self)
3020{
3021 int err;
3022 u_int32_t ffactor;
3023
3024 CHECK_DB_NOT_CLOSED(self);
3025
3026 MYDB_BEGIN_ALLOW_THREADS;
3027 err = self->db->get_h_ffactor(self->db, &ffactor);
3028 MYDB_END_ALLOW_THREADS;
3029 RETURN_IF_ERR();
3030 return NUMBER_FromLong(ffactor);
3031}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003032
3033static PyObject*
3034DB_set_h_nelem(DBObject* self, PyObject* args)
3035{
3036 int err, nelem;
3037
3038 if (!PyArg_ParseTuple(args,"i:set_h_nelem", &nelem))
3039 return NULL;
3040 CHECK_DB_NOT_CLOSED(self);
3041
3042 MYDB_BEGIN_ALLOW_THREADS;
3043 err = self->db->set_h_nelem(self->db, nelem);
3044 MYDB_END_ALLOW_THREADS;
3045 RETURN_IF_ERR();
3046 RETURN_NONE();
3047}
3048
Jesus Cea6557aac2010-03-22 14:22:26 +00003049static PyObject*
3050DB_get_h_nelem(DBObject* self)
3051{
3052 int err;
3053 u_int32_t nelem;
3054
3055 CHECK_DB_NOT_CLOSED(self);
3056
3057 MYDB_BEGIN_ALLOW_THREADS;
3058 err = self->db->get_h_nelem(self->db, &nelem);
3059 MYDB_END_ALLOW_THREADS;
3060 RETURN_IF_ERR();
3061 return NUMBER_FromLong(nelem);
3062}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003063
3064static PyObject*
3065DB_set_lorder(DBObject* self, PyObject* args)
3066{
3067 int err, lorder;
3068
3069 if (!PyArg_ParseTuple(args,"i:set_lorder", &lorder))
3070 return NULL;
3071 CHECK_DB_NOT_CLOSED(self);
3072
3073 MYDB_BEGIN_ALLOW_THREADS;
3074 err = self->db->set_lorder(self->db, lorder);
3075 MYDB_END_ALLOW_THREADS;
3076 RETURN_IF_ERR();
3077 RETURN_NONE();
3078}
3079
Jesus Cea6557aac2010-03-22 14:22:26 +00003080static PyObject*
3081DB_get_lorder(DBObject* self)
3082{
3083 int err;
3084 int lorder;
3085
3086 CHECK_DB_NOT_CLOSED(self);
3087
3088 MYDB_BEGIN_ALLOW_THREADS;
3089 err = self->db->get_lorder(self->db, &lorder);
3090 MYDB_END_ALLOW_THREADS;
3091 RETURN_IF_ERR();
3092 return NUMBER_FromLong(lorder);
3093}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003094
3095static PyObject*
3096DB_set_pagesize(DBObject* self, PyObject* args)
3097{
3098 int err, pagesize;
3099
3100 if (!PyArg_ParseTuple(args,"i:set_pagesize", &pagesize))
3101 return NULL;
3102 CHECK_DB_NOT_CLOSED(self);
3103
3104 MYDB_BEGIN_ALLOW_THREADS;
3105 err = self->db->set_pagesize(self->db, pagesize);
3106 MYDB_END_ALLOW_THREADS;
3107 RETURN_IF_ERR();
3108 RETURN_NONE();
3109}
3110
Jesus Cea6557aac2010-03-22 14:22:26 +00003111static PyObject*
3112DB_get_pagesize(DBObject* self)
3113{
3114 int err;
3115 u_int32_t pagesize;
3116
3117 CHECK_DB_NOT_CLOSED(self);
3118
3119 MYDB_BEGIN_ALLOW_THREADS;
3120 err = self->db->get_pagesize(self->db, &pagesize);
3121 MYDB_END_ALLOW_THREADS;
3122 RETURN_IF_ERR();
3123 return NUMBER_FromLong(pagesize);
3124}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003125
3126static PyObject*
3127DB_set_re_delim(DBObject* self, PyObject* args)
3128{
3129 int err;
3130 char delim;
3131
3132 if (!PyArg_ParseTuple(args,"b:set_re_delim", &delim)) {
3133 PyErr_Clear();
3134 if (!PyArg_ParseTuple(args,"c:set_re_delim", &delim))
3135 return NULL;
3136 }
3137
3138 CHECK_DB_NOT_CLOSED(self);
3139
3140 MYDB_BEGIN_ALLOW_THREADS;
3141 err = self->db->set_re_delim(self->db, delim);
3142 MYDB_END_ALLOW_THREADS;
3143 RETURN_IF_ERR();
3144 RETURN_NONE();
3145}
3146
Jesus Cea6557aac2010-03-22 14:22:26 +00003147static PyObject*
3148DB_get_re_delim(DBObject* self)
3149{
3150 int err, re_delim;
3151
3152 CHECK_DB_NOT_CLOSED(self);
3153
3154 MYDB_BEGIN_ALLOW_THREADS;
3155 err = self->db->get_re_delim(self->db, &re_delim);
3156 MYDB_END_ALLOW_THREADS;
3157 RETURN_IF_ERR();
3158 return NUMBER_FromLong(re_delim);
3159}
Jesus Cea6557aac2010-03-22 14:22:26 +00003160
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003161static PyObject*
3162DB_set_re_len(DBObject* self, PyObject* args)
3163{
3164 int err, len;
3165
3166 if (!PyArg_ParseTuple(args,"i:set_re_len", &len))
3167 return NULL;
3168 CHECK_DB_NOT_CLOSED(self);
3169
3170 MYDB_BEGIN_ALLOW_THREADS;
3171 err = self->db->set_re_len(self->db, len);
3172 MYDB_END_ALLOW_THREADS;
3173 RETURN_IF_ERR();
3174 RETURN_NONE();
3175}
3176
Jesus Cea6557aac2010-03-22 14:22:26 +00003177static PyObject*
3178DB_get_re_len(DBObject* self)
3179{
3180 int err;
3181 u_int32_t re_len;
3182
3183 CHECK_DB_NOT_CLOSED(self);
3184
3185 MYDB_BEGIN_ALLOW_THREADS;
3186 err = self->db->get_re_len(self->db, &re_len);
3187 MYDB_END_ALLOW_THREADS;
3188 RETURN_IF_ERR();
3189 return NUMBER_FromLong(re_len);
3190}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003191
3192static PyObject*
3193DB_set_re_pad(DBObject* self, PyObject* args)
3194{
3195 int err;
3196 char pad;
3197
3198 if (!PyArg_ParseTuple(args,"b:set_re_pad", &pad)) {
3199 PyErr_Clear();
3200 if (!PyArg_ParseTuple(args,"c:set_re_pad", &pad))
3201 return NULL;
3202 }
3203 CHECK_DB_NOT_CLOSED(self);
3204
3205 MYDB_BEGIN_ALLOW_THREADS;
3206 err = self->db->set_re_pad(self->db, pad);
3207 MYDB_END_ALLOW_THREADS;
3208 RETURN_IF_ERR();
3209 RETURN_NONE();
3210}
3211
Jesus Cea6557aac2010-03-22 14:22:26 +00003212static PyObject*
3213DB_get_re_pad(DBObject* self)
3214{
3215 int err, re_pad;
3216
3217 CHECK_DB_NOT_CLOSED(self);
3218
3219 MYDB_BEGIN_ALLOW_THREADS;
3220 err = self->db->get_re_pad(self->db, &re_pad);
3221 MYDB_END_ALLOW_THREADS;
3222 RETURN_IF_ERR();
3223 return NUMBER_FromLong(re_pad);
3224}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003225
3226static PyObject*
3227DB_set_re_source(DBObject* self, PyObject* args)
3228{
3229 int err;
Jesus Cea6557aac2010-03-22 14:22:26 +00003230 char *source;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003231
Jesus Cea6557aac2010-03-22 14:22:26 +00003232 if (!PyArg_ParseTuple(args,"s:set_re_source", &source))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003233 return NULL;
3234 CHECK_DB_NOT_CLOSED(self);
3235
3236 MYDB_BEGIN_ALLOW_THREADS;
Jesus Cea6557aac2010-03-22 14:22:26 +00003237 err = self->db->set_re_source(self->db, source);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003238 MYDB_END_ALLOW_THREADS;
3239 RETURN_IF_ERR();
3240 RETURN_NONE();
3241}
3242
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003243static PyObject*
Jesus Cea6557aac2010-03-22 14:22:26 +00003244DB_get_re_source(DBObject* self)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003245{
3246 int err;
Jesus Cea6557aac2010-03-22 14:22:26 +00003247 const char *source;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003248
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003249 CHECK_DB_NOT_CLOSED(self);
3250
3251 MYDB_BEGIN_ALLOW_THREADS;
Jesus Cea6557aac2010-03-22 14:22:26 +00003252 err = self->db->get_re_source(self->db, &source);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003253 MYDB_END_ALLOW_THREADS;
3254 RETURN_IF_ERR();
Jesus Cea6557aac2010-03-22 14:22:26 +00003255 return PyBytes_FromString(source);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003256}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003257
3258static PyObject*
Gregory P. Smith8b7e9172004-12-13 09:51:23 +00003259DB_stat(DBObject* self, PyObject* args, PyObject* kwargs)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003260{
3261 int err, flags = 0, type;
3262 void* sp;
3263 PyObject* d;
Gregory P. Smith8b7e9172004-12-13 09:51:23 +00003264 PyObject* txnobj = NULL;
3265 DB_TXN *txn = NULL;
Gregory P. Smith2fa06792006-09-19 17:35:04 +00003266 static char* kwnames[] = { "flags", "txn", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003267
Gregory P. Smith8b7e9172004-12-13 09:51:23 +00003268 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|iO:stat", kwnames,
3269 &flags, &txnobj))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003270 return NULL;
Gregory P. Smith8b7e9172004-12-13 09:51:23 +00003271 if (!checkTxnObj(txnobj, &txn))
3272 return NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003273 CHECK_DB_NOT_CLOSED(self);
3274
3275 MYDB_BEGIN_ALLOW_THREADS;
Gregory P. Smith8b7e9172004-12-13 09:51:23 +00003276 err = self->db->stat(self->db, txn, &sp, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003277 MYDB_END_ALLOW_THREADS;
3278 RETURN_IF_ERR();
3279
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003280 /* Turn the stat structure into a dictionary */
3281 type = _DB_get_type(self);
3282 if ((type == -1) || ((d = PyDict_New()) == NULL)) {
3283 free(sp);
3284 return NULL;
3285 }
3286
3287#define MAKE_HASH_ENTRY(name) _addIntToDict(d, #name, ((DB_HASH_STAT*)sp)->hash_##name)
3288#define MAKE_BT_ENTRY(name) _addIntToDict(d, #name, ((DB_BTREE_STAT*)sp)->bt_##name)
3289#define MAKE_QUEUE_ENTRY(name) _addIntToDict(d, #name, ((DB_QUEUE_STAT*)sp)->qs_##name)
3290
3291 switch (type) {
3292 case DB_HASH:
3293 MAKE_HASH_ENTRY(magic);
3294 MAKE_HASH_ENTRY(version);
3295 MAKE_HASH_ENTRY(nkeys);
3296 MAKE_HASH_ENTRY(ndata);
Jesus Ceaef9764f2008-05-13 18:45:46 +00003297#if (DBVER >= 46)
3298 MAKE_HASH_ENTRY(pagecnt);
3299#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003300 MAKE_HASH_ENTRY(pagesize);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003301 MAKE_HASH_ENTRY(ffactor);
3302 MAKE_HASH_ENTRY(buckets);
3303 MAKE_HASH_ENTRY(free);
3304 MAKE_HASH_ENTRY(bfree);
3305 MAKE_HASH_ENTRY(bigpages);
3306 MAKE_HASH_ENTRY(big_bfree);
3307 MAKE_HASH_ENTRY(overflows);
3308 MAKE_HASH_ENTRY(ovfl_free);
3309 MAKE_HASH_ENTRY(dup);
3310 MAKE_HASH_ENTRY(dup_free);
3311 break;
3312
3313 case DB_BTREE:
3314 case DB_RECNO:
3315 MAKE_BT_ENTRY(magic);
3316 MAKE_BT_ENTRY(version);
3317 MAKE_BT_ENTRY(nkeys);
3318 MAKE_BT_ENTRY(ndata);
Jesus Ceaef9764f2008-05-13 18:45:46 +00003319#if (DBVER >= 46)
3320 MAKE_BT_ENTRY(pagecnt);
3321#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003322 MAKE_BT_ENTRY(pagesize);
3323 MAKE_BT_ENTRY(minkey);
3324 MAKE_BT_ENTRY(re_len);
3325 MAKE_BT_ENTRY(re_pad);
3326 MAKE_BT_ENTRY(levels);
3327 MAKE_BT_ENTRY(int_pg);
3328 MAKE_BT_ENTRY(leaf_pg);
3329 MAKE_BT_ENTRY(dup_pg);
3330 MAKE_BT_ENTRY(over_pg);
Jesus Ceaef9764f2008-05-13 18:45:46 +00003331 MAKE_BT_ENTRY(empty_pg);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003332 MAKE_BT_ENTRY(free);
3333 MAKE_BT_ENTRY(int_pgfree);
3334 MAKE_BT_ENTRY(leaf_pgfree);
3335 MAKE_BT_ENTRY(dup_pgfree);
3336 MAKE_BT_ENTRY(over_pgfree);
3337 break;
3338
3339 case DB_QUEUE:
3340 MAKE_QUEUE_ENTRY(magic);
3341 MAKE_QUEUE_ENTRY(version);
3342 MAKE_QUEUE_ENTRY(nkeys);
3343 MAKE_QUEUE_ENTRY(ndata);
3344 MAKE_QUEUE_ENTRY(pagesize);
Jesus Ceaef9764f2008-05-13 18:45:46 +00003345 MAKE_QUEUE_ENTRY(extentsize);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003346 MAKE_QUEUE_ENTRY(pages);
3347 MAKE_QUEUE_ENTRY(re_len);
3348 MAKE_QUEUE_ENTRY(re_pad);
3349 MAKE_QUEUE_ENTRY(pgfree);
3350#if (DBVER == 31)
3351 MAKE_QUEUE_ENTRY(start);
3352#endif
3353 MAKE_QUEUE_ENTRY(first_recno);
3354 MAKE_QUEUE_ENTRY(cur_recno);
3355 break;
3356
3357 default:
3358 PyErr_SetString(PyExc_TypeError, "Unknown DB type, unable to stat");
3359 Py_DECREF(d);
3360 d = NULL;
3361 }
3362
3363#undef MAKE_HASH_ENTRY
3364#undef MAKE_BT_ENTRY
3365#undef MAKE_QUEUE_ENTRY
3366
3367 free(sp);
3368 return d;
3369}
3370
Jesus Cea6557aac2010-03-22 14:22:26 +00003371static PyObject*
3372DB_stat_print(DBObject* self, PyObject* args, PyObject *kwargs)
3373{
3374 int err;
3375 int flags=0;
3376 static char* kwnames[] = { "flags", NULL };
3377
3378 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:stat_print",
3379 kwnames, &flags))
3380 {
3381 return NULL;
3382 }
3383 CHECK_DB_NOT_CLOSED(self);
3384 MYDB_BEGIN_ALLOW_THREADS;
3385 err = self->db->stat_print(self->db, flags);
3386 MYDB_END_ALLOW_THREADS;
3387 RETURN_IF_ERR();
3388 RETURN_NONE();
3389}
Jesus Cea6557aac2010-03-22 14:22:26 +00003390
3391
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003392static PyObject*
3393DB_sync(DBObject* self, PyObject* args)
3394{
3395 int err;
3396 int flags = 0;
3397
3398 if (!PyArg_ParseTuple(args,"|i:sync", &flags ))
3399 return NULL;
3400 CHECK_DB_NOT_CLOSED(self);
3401
3402 MYDB_BEGIN_ALLOW_THREADS;
3403 err = self->db->sync(self->db, flags);
3404 MYDB_END_ALLOW_THREADS;
3405 RETURN_IF_ERR();
3406 RETURN_NONE();
3407}
3408
3409
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003410static PyObject*
3411DB_truncate(DBObject* self, PyObject* args, PyObject* kwargs)
3412{
3413 int err, flags=0;
3414 u_int32_t count=0;
3415 PyObject* txnobj = NULL;
3416 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003417 static char* kwnames[] = { "txn", "flags", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003418
3419 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Oi:cursor", kwnames,
3420 &txnobj, &flags))
3421 return NULL;
3422 CHECK_DB_NOT_CLOSED(self);
3423 if (!checkTxnObj(txnobj, &txn))
3424 return NULL;
3425
3426 MYDB_BEGIN_ALLOW_THREADS;
3427 err = self->db->truncate(self->db, txn, &count, flags);
3428 MYDB_END_ALLOW_THREADS;
3429 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00003430 return NUMBER_FromLong(count);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003431}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003432
3433
3434static PyObject*
3435DB_upgrade(DBObject* self, PyObject* args)
3436{
3437 int err, flags=0;
3438 char *filename;
3439
3440 if (!PyArg_ParseTuple(args,"s|i:upgrade", &filename, &flags))
3441 return NULL;
3442 CHECK_DB_NOT_CLOSED(self);
3443
3444 MYDB_BEGIN_ALLOW_THREADS;
3445 err = self->db->upgrade(self->db, filename, flags);
3446 MYDB_END_ALLOW_THREADS;
3447 RETURN_IF_ERR();
3448 RETURN_NONE();
3449}
3450
3451
3452static PyObject*
3453DB_verify(DBObject* self, PyObject* args, PyObject* kwargs)
3454{
3455 int err, flags=0;
3456 char* fileName;
3457 char* dbName=NULL;
3458 char* outFileName=NULL;
3459 FILE* outFile=NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003460 static char* kwnames[] = { "filename", "dbname", "outfile", "flags",
Jeremy Hyltonaf68c872005-12-10 18:50:16 +00003461 NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003462
3463 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|zzi:verify", kwnames,
3464 &fileName, &dbName, &outFileName, &flags))
3465 return NULL;
3466
3467 CHECK_DB_NOT_CLOSED(self);
3468 if (outFileName)
3469 outFile = fopen(outFileName, "w");
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003470 /* XXX(nnorwitz): it should probably be an exception if outFile
3471 can't be opened. */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003472
Jesus Ceaef9764f2008-05-13 18:45:46 +00003473 { /* DB.verify acts as a DB handle destructor (like close) */
3474 PyObject *error;
3475
Jesus Cea5cd5f122008-09-23 18:54:08 +00003476 error=DB_close_internal(self, 0, 1);
Jesus Cea6557aac2010-03-22 14:22:26 +00003477 if (error) {
Serhiy Storchakaaffac002015-07-24 08:05:45 +03003478 if (outFile)
3479 fclose(outFile);
3480 return error;
Jesus Ceaef9764f2008-05-13 18:45:46 +00003481 }
Serhiy Storchakaaffac002015-07-24 08:05:45 +03003482 }
Gregory P. Smith41631e82003-09-21 00:08:14 +00003483
Jesus Cea5cd5f122008-09-23 18:54:08 +00003484 MYDB_BEGIN_ALLOW_THREADS;
3485 err = self->db->verify(self->db, fileName, dbName, outFile, flags);
3486 MYDB_END_ALLOW_THREADS;
3487
3488 self->db = NULL; /* Implicit close; related objects already released */
3489
3490 if (outFile)
3491 fclose(outFile);
3492
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003493 RETURN_IF_ERR();
3494 RETURN_NONE();
3495}
3496
3497
3498static PyObject*
3499DB_set_get_returns_none(DBObject* self, PyObject* args)
3500{
3501 int flags=0;
Gregory P. Smith455d46f2003-07-09 04:45:59 +00003502 int oldValue=0;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003503
3504 if (!PyArg_ParseTuple(args,"i:set_get_returns_none", &flags))
3505 return NULL;
3506 CHECK_DB_NOT_CLOSED(self);
3507
Gregory P. Smith455d46f2003-07-09 04:45:59 +00003508 if (self->moduleFlags.getReturnsNone)
3509 ++oldValue;
3510 if (self->moduleFlags.cursorSetReturnsNone)
3511 ++oldValue;
3512 self->moduleFlags.getReturnsNone = (flags >= 1);
3513 self->moduleFlags.cursorSetReturnsNone = (flags >= 2);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00003514 return NUMBER_FromLong(oldValue);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003515}
3516
Barry Warsaw9a0d7792002-12-30 20:53:52 +00003517static PyObject*
3518DB_set_encrypt(DBObject* self, PyObject* args, PyObject* kwargs)
3519{
3520 int err;
3521 u_int32_t flags=0;
3522 char *passwd = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003523 static char* kwnames[] = { "passwd", "flags", NULL };
Barry Warsaw9a0d7792002-12-30 20:53:52 +00003524
3525 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|i:set_encrypt", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003526 &passwd, &flags)) {
3527 return NULL;
Barry Warsaw9a0d7792002-12-30 20:53:52 +00003528 }
3529
3530 MYDB_BEGIN_ALLOW_THREADS;
3531 err = self->db->set_encrypt(self->db, passwd, flags);
3532 MYDB_END_ALLOW_THREADS;
3533
3534 RETURN_IF_ERR();
3535 RETURN_NONE();
3536}
Jesus Cea6557aac2010-03-22 14:22:26 +00003537
Jesus Cea6557aac2010-03-22 14:22:26 +00003538static PyObject*
3539DB_get_encrypt_flags(DBObject* self)
3540{
3541 int err;
3542 u_int32_t flags;
3543
3544 MYDB_BEGIN_ALLOW_THREADS;
3545 err = self->db->get_encrypt_flags(self->db, &flags);
3546 MYDB_END_ALLOW_THREADS;
3547
3548 RETURN_IF_ERR();
3549
3550 return NUMBER_FromLong(flags);
3551}
Jesus Cea6557aac2010-03-22 14:22:26 +00003552
Barry Warsaw9a0d7792002-12-30 20:53:52 +00003553
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003554
3555/*-------------------------------------------------------------- */
3556/* Mapping and Dictionary-like access routines */
3557
Martin v. Löwis70ee3cc2006-06-12 04:26:31 +00003558Py_ssize_t DB_length(PyObject* _self)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003559{
3560 int err;
Gregory P. Smith3c228b12006-06-05 23:59:37 +00003561 Py_ssize_t size = 0;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003562 void* sp;
Martin v. Löwis70ee3cc2006-06-12 04:26:31 +00003563 DBObject* self = (DBObject*)_self;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003564
3565 if (self->db == NULL) {
Thomas Woutersb3153832006-03-08 01:47:19 +00003566 PyObject *t = Py_BuildValue("(is)", 0, "DB object has been closed");
Jesus Ceac5a11fa2008-07-23 11:38:42 +00003567 if (t) {
3568 PyErr_SetObject(DBError, t);
3569 Py_DECREF(t);
3570 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003571 return -1;
3572 }
3573
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003574 MYDB_BEGIN_ALLOW_THREADS;
Jesus Cea6557aac2010-03-22 14:22:26 +00003575 err = self->db->stat(self->db, /*txnid*/ NULL, &sp, 0);
Jesus Cea6557aac2010-03-22 14:22:26 +00003576 MYDB_END_ALLOW_THREADS;
Gregory P. Smith3c228b12006-06-05 23:59:37 +00003577
3578 /* All the stat structures have matching fields upto the ndata field,
3579 so we can use any of them for the type cast */
3580 size = ((DB_BTREE_STAT*)sp)->bt_ndata;
3581
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003582 if (err)
3583 return -1;
3584
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003585 free(sp);
3586 return size;
3587}
3588
3589
3590PyObject* DB_subscript(DBObject* self, PyObject* keyobj)
3591{
3592 int err;
3593 PyObject* retval;
3594 DBT key;
3595 DBT data;
3596
3597 CHECK_DB_NOT_CLOSED(self);
3598 if (!make_key_dbt(self, keyobj, &key, NULL))
3599 return NULL;
3600
3601 CLEAR_DBT(data);
3602 if (CHECK_DBFLAG(self, DB_THREAD)) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00003603 /* Tell Berkeley DB to malloc the return value (thread safe) */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003604 data.flags = DB_DBT_MALLOC;
3605 }
3606 MYDB_BEGIN_ALLOW_THREADS;
3607 err = self->db->get(self->db, NULL, &key, &data, 0);
3608 MYDB_END_ALLOW_THREADS;
3609 if (err == DB_NOTFOUND || err == DB_KEYEMPTY) {
3610 PyErr_SetObject(PyExc_KeyError, keyobj);
3611 retval = NULL;
3612 }
3613 else if (makeDBError(err)) {
3614 retval = NULL;
3615 }
3616 else {
Jesus Ceaef9764f2008-05-13 18:45:46 +00003617 retval = Build_PyString(data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003618 FREE_DBT(data);
3619 }
3620
3621 FREE_DBT(key);
3622 return retval;
3623}
3624
3625
3626static int
3627DB_ass_sub(DBObject* self, PyObject* keyobj, PyObject* dataobj)
3628{
3629 DBT key, data;
3630 int retval;
3631 int flags = 0;
3632
3633 if (self->db == NULL) {
Thomas Woutersb3153832006-03-08 01:47:19 +00003634 PyObject *t = Py_BuildValue("(is)", 0, "DB object has been closed");
Jesus Ceac5a11fa2008-07-23 11:38:42 +00003635 if (t) {
3636 PyErr_SetObject(DBError, t);
3637 Py_DECREF(t);
3638 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003639 return -1;
3640 }
3641
3642 if (!make_key_dbt(self, keyobj, &key, NULL))
3643 return -1;
3644
3645 if (dataobj != NULL) {
3646 if (!make_dbt(dataobj, &data))
3647 retval = -1;
3648 else {
3649 if (self->setflags & (DB_DUP|DB_DUPSORT))
Barry Warsaw9a0d7792002-12-30 20:53:52 +00003650 /* dictionaries shouldn't have duplicate keys */
3651 flags = DB_NOOVERWRITE;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003652 retval = _DB_put(self, NULL, &key, &data, flags);
3653
3654 if ((retval == -1) && (self->setflags & (DB_DUP|DB_DUPSORT))) {
Barry Warsaw9a0d7792002-12-30 20:53:52 +00003655 /* try deleting any old record that matches and then PUT it
3656 * again... */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003657 _DB_delete(self, NULL, &key, 0);
3658 PyErr_Clear();
3659 retval = _DB_put(self, NULL, &key, &data, flags);
3660 }
3661 }
3662 }
3663 else {
3664 /* dataobj == NULL, so delete the key */
3665 retval = _DB_delete(self, NULL, &key, 0);
3666 }
3667 FREE_DBT(key);
3668 return retval;
3669}
3670
3671
3672static PyObject*
Jesus Cea6557aac2010-03-22 14:22:26 +00003673_DB_has_key(DBObject* self, PyObject* keyobj, PyObject* txnobj)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003674{
3675 int err;
Jesus Cea6557aac2010-03-22 14:22:26 +00003676 DBT key;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003677 DB_TXN *txn = NULL;
Jesus Cea4907d272008-08-31 14:00:51 +00003678
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003679 CHECK_DB_NOT_CLOSED(self);
3680 if (!make_key_dbt(self, keyobj, &key, NULL))
3681 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00003682 if (!checkTxnObj(txnobj, &txn)) {
3683 FREE_DBT(key);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003684 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00003685 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003686
Jesus Cea6557aac2010-03-22 14:22:26 +00003687#if (DBVER < 46)
Gregory P. Smith8b7e9172004-12-13 09:51:23 +00003688 /* This causes DB_BUFFER_SMALL to be returned when the db has the key because
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003689 it has a record but can't allocate a buffer for the data. This saves
3690 having to deal with data we won't be using.
3691 */
Jesus Cea6557aac2010-03-22 14:22:26 +00003692 {
3693 DBT data ;
3694 CLEAR_DBT(data);
3695 data.flags = DB_DBT_USERMEM;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003696
Jesus Cea6557aac2010-03-22 14:22:26 +00003697 MYDB_BEGIN_ALLOW_THREADS;
3698 err = self->db->get(self->db, txn, &key, &data, 0);
3699 MYDB_END_ALLOW_THREADS;
3700 }
3701#else
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003702 MYDB_BEGIN_ALLOW_THREADS;
Jesus Cea6557aac2010-03-22 14:22:26 +00003703 err = self->db->exists(self->db, txn, &key, 0);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003704 MYDB_END_ALLOW_THREADS;
Jesus Cea6557aac2010-03-22 14:22:26 +00003705#endif
3706
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003707 FREE_DBT(key);
Gregory P. Smithe9477062005-06-04 06:46:59 +00003708
Jesus Cea6557aac2010-03-22 14:22:26 +00003709 /*
3710 ** DB_BUFFER_SMALL is only used if we use "get".
3711 ** We can drop it when we only use "exists",
Martin Panter8d496ad2016-06-02 10:35:44 +00003712 ** when we drop support for Berkeley DB < 4.6.
Jesus Cea6557aac2010-03-22 14:22:26 +00003713 */
Gregory P. Smithe9477062005-06-04 06:46:59 +00003714 if (err == DB_BUFFER_SMALL || err == 0) {
Jesus Cea6557aac2010-03-22 14:22:26 +00003715 Py_INCREF(Py_True);
3716 return Py_True;
Gregory P. Smithe9477062005-06-04 06:46:59 +00003717 } else if (err == DB_NOTFOUND || err == DB_KEYEMPTY) {
Jesus Cea6557aac2010-03-22 14:22:26 +00003718 Py_INCREF(Py_False);
3719 return Py_False;
Gregory P. Smithe9477062005-06-04 06:46:59 +00003720 }
3721
3722 makeDBError(err);
3723 return NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003724}
3725
Jesus Cea6557aac2010-03-22 14:22:26 +00003726static PyObject*
3727DB_has_key(DBObject* self, PyObject* args, PyObject* kwargs)
3728{
3729 PyObject* keyobj;
3730 PyObject* txnobj = NULL;
3731 static char* kwnames[] = {"key","txn", NULL};
3732
3733 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O:has_key", kwnames,
3734 &keyobj, &txnobj))
3735 return NULL;
3736
3737 return _DB_has_key(self, keyobj, txnobj);
3738}
3739
3740
3741static int DB_contains(DBObject* self, PyObject* keyobj)
3742{
3743 PyObject* result;
3744 int result2 = 0;
3745
3746 result = _DB_has_key(self, keyobj, NULL) ;
3747 if (result == NULL) {
3748 return -1; /* Propague exception */
3749 }
3750 if (result != Py_False) {
3751 result2 = 1;
3752 }
3753
3754 Py_DECREF(result);
3755 return result2;
3756}
3757
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003758
3759#define _KEYS_LIST 1
3760#define _VALUES_LIST 2
3761#define _ITEMS_LIST 3
3762
3763static PyObject*
3764_DB_make_list(DBObject* self, DB_TXN* txn, int type)
3765{
3766 int err, dbtype;
3767 DBT key;
3768 DBT data;
3769 DBC *cursor;
3770 PyObject* list;
3771 PyObject* item = NULL;
3772
3773 CHECK_DB_NOT_CLOSED(self);
3774 CLEAR_DBT(key);
3775 CLEAR_DBT(data);
3776
3777 dbtype = _DB_get_type(self);
3778 if (dbtype == -1)
3779 return NULL;
3780
3781 list = PyList_New(0);
Thomas Woutersb3153832006-03-08 01:47:19 +00003782 if (list == NULL)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003783 return NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003784
3785 /* get a cursor */
3786 MYDB_BEGIN_ALLOW_THREADS;
Gregory P. Smith442c9fc2004-09-04 01:36:59 +00003787 err = self->db->cursor(self->db, txn, &cursor, 0);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003788 MYDB_END_ALLOW_THREADS;
Thomas Woutersb3153832006-03-08 01:47:19 +00003789 if (makeDBError(err)) {
3790 Py_DECREF(list);
3791 return NULL;
3792 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003793
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003794 while (1) { /* use the cursor to traverse the DB, collecting items */
3795 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00003796 err = _DBC_get(cursor, &key, &data, DB_NEXT);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003797 MYDB_END_ALLOW_THREADS;
3798
3799 if (err) {
3800 /* for any error, break out of the loop */
3801 break;
3802 }
3803
3804 switch (type) {
3805 case _KEYS_LIST:
3806 switch(dbtype) {
3807 case DB_BTREE:
3808 case DB_HASH:
3809 default:
Jesus Ceaef9764f2008-05-13 18:45:46 +00003810 item = Build_PyString(key.data, key.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003811 break;
3812 case DB_RECNO:
3813 case DB_QUEUE:
Jesus Ceac5a11fa2008-07-23 11:38:42 +00003814 item = NUMBER_FromLong(*((db_recno_t*)key.data));
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003815 break;
3816 }
3817 break;
3818
3819 case _VALUES_LIST:
Jesus Ceaef9764f2008-05-13 18:45:46 +00003820 item = Build_PyString(data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003821 break;
3822
3823 case _ITEMS_LIST:
3824 switch(dbtype) {
3825 case DB_BTREE:
3826 case DB_HASH:
3827 default:
Jesus Ceaef9764f2008-05-13 18:45:46 +00003828 item = BuildValue_SS(key.data, key.size, data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003829 break;
3830 case DB_RECNO:
3831 case DB_QUEUE:
Jesus Ceaef9764f2008-05-13 18:45:46 +00003832 item = BuildValue_IS(*((db_recno_t*)key.data), data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003833 break;
3834 }
3835 break;
Thomas Woutersb3153832006-03-08 01:47:19 +00003836 default:
3837 PyErr_Format(PyExc_ValueError, "Unknown key type 0x%x", type);
3838 item = NULL;
3839 break;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003840 }
3841 if (item == NULL) {
3842 Py_DECREF(list);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003843 list = NULL;
3844 goto done;
3845 }
Jesus Ceac5a11fa2008-07-23 11:38:42 +00003846 if (PyList_Append(list, item)) {
3847 Py_DECREF(list);
3848 Py_DECREF(item);
3849 list = NULL;
3850 goto done;
3851 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003852 Py_DECREF(item);
3853 }
3854
Gregory P. Smithe9477062005-06-04 06:46:59 +00003855 /* DB_NOTFOUND || DB_KEYEMPTY is okay, it means we got to the end */
3856 if (err != DB_NOTFOUND && err != DB_KEYEMPTY && makeDBError(err)) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003857 Py_DECREF(list);
3858 list = NULL;
3859 }
3860
3861 done:
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003862 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00003863 _DBC_close(cursor);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003864 MYDB_END_ALLOW_THREADS;
3865 return list;
3866}
3867
3868
3869static PyObject*
3870DB_keys(DBObject* self, PyObject* args)
3871{
3872 PyObject* txnobj = NULL;
3873 DB_TXN *txn = NULL;
3874
Georg Brandl96a8c392006-05-29 21:04:52 +00003875 if (!PyArg_UnpackTuple(args, "keys", 0, 1, &txnobj))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003876 return NULL;
3877 if (!checkTxnObj(txnobj, &txn))
3878 return NULL;
3879 return _DB_make_list(self, txn, _KEYS_LIST);
3880}
3881
3882
3883static PyObject*
3884DB_items(DBObject* self, PyObject* args)
3885{
3886 PyObject* txnobj = NULL;
3887 DB_TXN *txn = NULL;
3888
Georg Brandl96a8c392006-05-29 21:04:52 +00003889 if (!PyArg_UnpackTuple(args, "items", 0, 1, &txnobj))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003890 return NULL;
3891 if (!checkTxnObj(txnobj, &txn))
3892 return NULL;
3893 return _DB_make_list(self, txn, _ITEMS_LIST);
3894}
3895
3896
3897static PyObject*
3898DB_values(DBObject* self, PyObject* args)
3899{
3900 PyObject* txnobj = NULL;
3901 DB_TXN *txn = NULL;
3902
Georg Brandl96a8c392006-05-29 21:04:52 +00003903 if (!PyArg_UnpackTuple(args, "values", 0, 1, &txnobj))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003904 return NULL;
3905 if (!checkTxnObj(txnobj, &txn))
3906 return NULL;
3907 return _DB_make_list(self, txn, _VALUES_LIST);
3908}
3909
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003910/* --------------------------------------------------------------------- */
Jesus Cea6557aac2010-03-22 14:22:26 +00003911/* DBLogCursor methods */
3912
3913
3914static PyObject*
3915DBLogCursor_close_internal(DBLogCursorObject* self)
3916{
3917 int err = 0;
3918
3919 if (self->logc != NULL) {
3920 EXTRACT_FROM_DOUBLE_LINKED_LIST(self);
3921
3922 MYDB_BEGIN_ALLOW_THREADS;
3923 err = self->logc->close(self->logc, 0);
3924 MYDB_END_ALLOW_THREADS;
3925 self->logc = NULL;
3926 }
3927 RETURN_IF_ERR();
3928 RETURN_NONE();
3929}
3930
3931static PyObject*
3932DBLogCursor_close(DBLogCursorObject* self)
3933{
3934 return DBLogCursor_close_internal(self);
3935}
3936
3937
3938static PyObject*
3939_DBLogCursor_get(DBLogCursorObject* self, int flag, DB_LSN *lsn2)
3940{
3941 int err;
3942 DBT data;
3943 DB_LSN lsn = {0, 0};
3944 PyObject *dummy, *retval;
3945
3946 CLEAR_DBT(data);
3947 data.flags = DB_DBT_MALLOC; /* Berkeley DB must do the malloc */
3948
3949 CHECK_LOGCURSOR_NOT_CLOSED(self);
3950
3951 if (lsn2)
3952 lsn = *lsn2;
3953
3954 MYDB_BEGIN_ALLOW_THREADS;
3955 err = self->logc->get(self->logc, &lsn, &data, flag);
3956 MYDB_END_ALLOW_THREADS;
3957
3958 if (err == DB_NOTFOUND) {
3959 Py_INCREF(Py_None);
3960 retval = Py_None;
3961 }
3962 else if (makeDBError(err)) {
3963 retval = NULL;
3964 }
3965 else {
3966 retval = dummy = BuildValue_S(data.data, data.size);
3967 if (dummy) {
3968 retval = Py_BuildValue("(ii)O", lsn.file, lsn.offset, dummy);
3969 Py_DECREF(dummy);
3970 }
3971 }
3972
3973 FREE_DBT(data);
3974 return retval;
3975}
3976
3977static PyObject*
3978DBLogCursor_current(DBLogCursorObject* self)
3979{
3980 return _DBLogCursor_get(self, DB_CURRENT, NULL);
3981}
3982
3983static PyObject*
3984DBLogCursor_first(DBLogCursorObject* self)
3985{
3986 return _DBLogCursor_get(self, DB_FIRST, NULL);
3987}
3988
3989static PyObject*
3990DBLogCursor_last(DBLogCursorObject* self)
3991{
3992 return _DBLogCursor_get(self, DB_LAST, NULL);
3993}
3994
3995static PyObject*
3996DBLogCursor_next(DBLogCursorObject* self)
3997{
3998 return _DBLogCursor_get(self, DB_NEXT, NULL);
3999}
4000
4001static PyObject*
4002DBLogCursor_prev(DBLogCursorObject* self)
4003{
4004 return _DBLogCursor_get(self, DB_PREV, NULL);
4005}
4006
4007static PyObject*
4008DBLogCursor_set(DBLogCursorObject* self, PyObject* args)
4009{
4010 DB_LSN lsn;
4011
4012 if (!PyArg_ParseTuple(args, "(ii):set", &lsn.file, &lsn.offset))
4013 return NULL;
4014
4015 return _DBLogCursor_get(self, DB_SET, &lsn);
4016}
4017
4018
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07004019/* --------------------------------------------------------------------- */
4020/* DBSite methods */
4021
4022
4023#if (DBVER >= 52)
4024static PyObject*
4025DBSite_close_internal(DBSiteObject* self)
4026{
4027 int err = 0;
4028
4029 if (self->site != NULL) {
4030 EXTRACT_FROM_DOUBLE_LINKED_LIST(self);
4031
4032 MYDB_BEGIN_ALLOW_THREADS;
4033 err = self->site->close(self->site);
4034 MYDB_END_ALLOW_THREADS;
4035 self->site = NULL;
4036 }
4037 RETURN_IF_ERR();
4038 RETURN_NONE();
4039}
4040
4041static PyObject*
4042DBSite_close(DBSiteObject* self)
4043{
4044 return DBSite_close_internal(self);
4045}
4046
4047static PyObject*
4048DBSite_remove(DBSiteObject* self)
4049{
4050 int err = 0;
4051
4052 CHECK_SITE_NOT_CLOSED(self);
4053
4054 MYDB_BEGIN_ALLOW_THREADS;
4055 err = self->site->remove(self->site);
4056 MYDB_END_ALLOW_THREADS;
4057
4058 RETURN_IF_ERR();
4059 RETURN_NONE();
4060}
4061
4062static PyObject*
4063DBSite_get_eid(DBSiteObject* self)
4064{
4065 int err = 0;
4066 int eid;
4067
4068 CHECK_SITE_NOT_CLOSED(self);
4069
4070 MYDB_BEGIN_ALLOW_THREADS;
4071 err = self->site->get_eid(self->site, &eid);
4072 MYDB_END_ALLOW_THREADS;
4073
4074 RETURN_IF_ERR();
4075 return NUMBER_FromLong(eid);
4076}
4077
4078static PyObject*
4079DBSite_get_address(DBSiteObject* self)
4080{
4081 int err = 0;
4082 const char *host;
4083 u_int port;
4084
4085 CHECK_SITE_NOT_CLOSED(self);
4086
4087 MYDB_BEGIN_ALLOW_THREADS;
4088 err = self->site->get_address(self->site, &host, &port);
4089 MYDB_END_ALLOW_THREADS;
4090
4091 RETURN_IF_ERR();
4092
4093 return Py_BuildValue("(sI)", host, port);
4094}
4095
4096static PyObject*
4097DBSite_get_config(DBSiteObject* self, PyObject* args, PyObject* kwargs)
4098{
4099 int err = 0;
4100 u_int32_t which, value;
4101 static char* kwnames[] = { "which", NULL };
4102
4103 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i:get_config", kwnames,
4104 &which))
4105 return NULL;
4106
4107 CHECK_SITE_NOT_CLOSED(self);
4108
4109 MYDB_BEGIN_ALLOW_THREADS;
4110 err = self->site->get_config(self->site, which, &value);
4111 MYDB_END_ALLOW_THREADS;
4112
4113 RETURN_IF_ERR();
4114
4115 if (value) {
4116 Py_INCREF(Py_True);
4117 return Py_True;
4118 } else {
4119 Py_INCREF(Py_False);
4120 return Py_False;
4121 }
4122}
4123
4124static PyObject*
4125DBSite_set_config(DBSiteObject* self, PyObject* args, PyObject* kwargs)
4126{
4127 int err = 0;
4128 u_int32_t which, value;
4129 PyObject *valueO;
4130 static char* kwnames[] = { "which", "value", NULL };
4131
4132 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "iO:set_config", kwnames,
4133 &which, &valueO))
4134 return NULL;
4135
4136 CHECK_SITE_NOT_CLOSED(self);
4137
4138 value = PyObject_IsTrue(valueO);
4139
4140 MYDB_BEGIN_ALLOW_THREADS;
4141 err = self->site->set_config(self->site, which, value);
4142 MYDB_END_ALLOW_THREADS;
4143
4144 RETURN_IF_ERR();
4145 RETURN_NONE();
4146}
4147#endif
4148
Jesus Cea6557aac2010-03-22 14:22:26 +00004149
4150/* --------------------------------------------------------------------- */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004151/* DBCursor methods */
4152
4153
4154static PyObject*
Jesus Ceaef9764f2008-05-13 18:45:46 +00004155DBC_close_internal(DBCursorObject* self)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004156{
4157 int err = 0;
4158
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004159 if (self->dbc != NULL) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00004160 EXTRACT_FROM_DOUBLE_LINKED_LIST(self);
4161 if (self->txn) {
4162 EXTRACT_FROM_DOUBLE_LINKED_LIST_TXN(self);
4163 self->txn=NULL;
4164 }
4165
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004166 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004167 err = _DBC_close(self->dbc);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004168 MYDB_END_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004169 self->dbc = NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004170 }
4171 RETURN_IF_ERR();
4172 RETURN_NONE();
4173}
4174
Jesus Ceaef9764f2008-05-13 18:45:46 +00004175static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00004176DBC_close(DBCursorObject* self)
Jesus Ceaef9764f2008-05-13 18:45:46 +00004177{
Jesus Ceaef9764f2008-05-13 18:45:46 +00004178 return DBC_close_internal(self);
4179}
4180
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004181
4182static PyObject*
4183DBC_count(DBCursorObject* self, PyObject* args)
4184{
4185 int err = 0;
4186 db_recno_t count;
4187 int flags = 0;
4188
4189 if (!PyArg_ParseTuple(args, "|i:count", &flags))
4190 return NULL;
4191
4192 CHECK_CURSOR_NOT_CLOSED(self);
4193
4194 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004195 err = _DBC_count(self->dbc, &count, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004196 MYDB_END_ALLOW_THREADS;
4197 RETURN_IF_ERR();
4198
Jesus Ceac5a11fa2008-07-23 11:38:42 +00004199 return NUMBER_FromLong(count);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004200}
4201
4202
4203static PyObject*
4204DBC_current(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4205{
4206 return _DBCursor_get(self,DB_CURRENT,args,kwargs,"|iii:current");
4207}
4208
4209
4210static PyObject*
4211DBC_delete(DBCursorObject* self, PyObject* args)
4212{
4213 int err, flags=0;
4214
4215 if (!PyArg_ParseTuple(args, "|i:delete", &flags))
4216 return NULL;
4217
4218 CHECK_CURSOR_NOT_CLOSED(self);
4219
4220 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004221 err = _DBC_del(self->dbc, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004222 MYDB_END_ALLOW_THREADS;
4223 RETURN_IF_ERR();
4224
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004225 RETURN_NONE();
4226}
4227
4228
4229static PyObject*
4230DBC_dup(DBCursorObject* self, PyObject* args)
4231{
4232 int err, flags =0;
4233 DBC* dbc = NULL;
4234
4235 if (!PyArg_ParseTuple(args, "|i:dup", &flags))
4236 return NULL;
4237
4238 CHECK_CURSOR_NOT_CLOSED(self);
4239
4240 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004241 err = _DBC_dup(self->dbc, &dbc, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004242 MYDB_END_ALLOW_THREADS;
4243 RETURN_IF_ERR();
4244
Jesus Ceaef9764f2008-05-13 18:45:46 +00004245 return (PyObject*) newDBCursorObject(dbc, self->txn, self->mydb);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004246}
4247
4248static PyObject*
4249DBC_first(DBCursorObject* self, PyObject* args, PyObject* kwargs)
4250{
4251 return _DBCursor_get(self,DB_FIRST,args,kwargs,"|iii:first");
4252}
4253
4254
4255static PyObject*
4256DBC_get(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4257{
Martin v. Löwisb2c7aff2002-11-23 11:26:07 +00004258 int err, flags=0;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004259 PyObject* keyobj = NULL;
4260 PyObject* dataobj = NULL;
4261 PyObject* retval = NULL;
4262 int dlen = -1;
4263 int doff = -1;
4264 DBT key, data;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00004265 static char* kwnames[] = { "key","data", "flags", "dlen", "doff",
Jeremy Hyltonaf68c872005-12-10 18:50:16 +00004266 NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004267
4268 CLEAR_DBT(key);
4269 CLEAR_DBT(data);
4270 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|ii:get", &kwnames[2],
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004271 &flags, &dlen, &doff))
Barry Warsaw9a0d7792002-12-30 20:53:52 +00004272 {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004273 PyErr_Clear();
Barry Warsaw9a0d7792002-12-30 20:53:52 +00004274 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Oi|ii:get",
Jesus Cea4907d272008-08-31 14:00:51 +00004275 &kwnames[1],
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004276 &keyobj, &flags, &dlen, &doff))
Barry Warsaw9a0d7792002-12-30 20:53:52 +00004277 {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004278 PyErr_Clear();
Barry Warsaw9a0d7792002-12-30 20:53:52 +00004279 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OOi|ii:get",
4280 kwnames, &keyobj, &dataobj,
4281 &flags, &dlen, &doff))
4282 {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004283 return NULL;
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004284 }
4285 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004286 }
4287
4288 CHECK_CURSOR_NOT_CLOSED(self);
4289
4290 if (keyobj && !make_key_dbt(self->mydb, keyobj, &key, NULL))
4291 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004292 if ( (dataobj && !make_dbt(dataobj, &data)) ||
4293 (!add_partial_dbt(&data, dlen, doff)) )
4294 {
Jesus Ceaef9764f2008-05-13 18:45:46 +00004295 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004296 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004297 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004298
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004299 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004300 err = _DBC_get(self->dbc, &key, &data, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004301 MYDB_END_ALLOW_THREADS;
4302
Gregory P. Smithe9477062005-06-04 06:46:59 +00004303 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004304 && self->mydb->moduleFlags.getReturnsNone) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004305 Py_INCREF(Py_None);
4306 retval = Py_None;
4307 }
4308 else if (makeDBError(err)) {
4309 retval = NULL;
4310 }
4311 else {
4312 switch (_DB_get_type(self->mydb)) {
4313 case -1:
4314 retval = NULL;
4315 break;
4316 case DB_BTREE:
4317 case DB_HASH:
4318 default:
Jesus Ceaef9764f2008-05-13 18:45:46 +00004319 retval = BuildValue_SS(key.data, key.size, data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004320 break;
4321 case DB_RECNO:
4322 case DB_QUEUE:
Jesus Ceaef9764f2008-05-13 18:45:46 +00004323 retval = BuildValue_IS(*((db_recno_t*)key.data), data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004324 break;
4325 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004326 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00004327 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004328 return retval;
4329}
4330
Gregory P. Smith19699a92004-06-28 04:06:49 +00004331static PyObject*
4332DBC_pget(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4333{
4334 int err, flags=0;
4335 PyObject* keyobj = NULL;
4336 PyObject* dataobj = NULL;
4337 PyObject* retval = NULL;
4338 int dlen = -1;
4339 int doff = -1;
4340 DBT key, pkey, data;
Gregory P. Smith372b5832006-06-05 18:48:21 +00004341 static char* kwnames_keyOnly[] = { "key", "flags", "dlen", "doff", NULL };
4342 static char* kwnames[] = { "key", "data", "flags", "dlen", "doff", NULL };
Gregory P. Smith19699a92004-06-28 04:06:49 +00004343
4344 CLEAR_DBT(key);
4345 CLEAR_DBT(data);
4346 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|ii:pget", &kwnames[2],
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004347 &flags, &dlen, &doff))
Gregory P. Smith19699a92004-06-28 04:06:49 +00004348 {
4349 PyErr_Clear();
4350 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Oi|ii:pget",
Jesus Cea6557aac2010-03-22 14:22:26 +00004351 kwnames_keyOnly,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004352 &keyobj, &flags, &dlen, &doff))
Gregory P. Smith19699a92004-06-28 04:06:49 +00004353 {
4354 PyErr_Clear();
4355 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OOi|ii:pget",
4356 kwnames, &keyobj, &dataobj,
4357 &flags, &dlen, &doff))
4358 {
4359 return NULL;
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004360 }
4361 }
Gregory P. Smith19699a92004-06-28 04:06:49 +00004362 }
4363
4364 CHECK_CURSOR_NOT_CLOSED(self);
4365
4366 if (keyobj && !make_key_dbt(self->mydb, keyobj, &key, NULL))
4367 return NULL;
4368 if ( (dataobj && !make_dbt(dataobj, &data)) ||
4369 (!add_partial_dbt(&data, dlen, doff)) ) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00004370 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Gregory P. Smith19699a92004-06-28 04:06:49 +00004371 return NULL;
4372 }
4373
Gregory P. Smith19699a92004-06-28 04:06:49 +00004374 CLEAR_DBT(pkey);
4375 pkey.flags = DB_DBT_MALLOC;
4376
4377 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004378 err = _DBC_pget(self->dbc, &key, &pkey, &data, flags);
Gregory P. Smith19699a92004-06-28 04:06:49 +00004379 MYDB_END_ALLOW_THREADS;
4380
Gregory P. Smithe9477062005-06-04 06:46:59 +00004381 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004382 && self->mydb->moduleFlags.getReturnsNone) {
Gregory P. Smith19699a92004-06-28 04:06:49 +00004383 Py_INCREF(Py_None);
4384 retval = Py_None;
4385 }
4386 else if (makeDBError(err)) {
4387 retval = NULL;
4388 }
4389 else {
4390 PyObject *pkeyObj;
4391 PyObject *dataObj;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004392 dataObj = Build_PyString(data.data, data.size);
Gregory P. Smith19699a92004-06-28 04:06:49 +00004393
4394 if (self->mydb->primaryDBType == DB_RECNO ||
4395 self->mydb->primaryDBType == DB_QUEUE)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00004396 pkeyObj = NUMBER_FromLong(*(int *)pkey.data);
Gregory P. Smith19699a92004-06-28 04:06:49 +00004397 else
Jesus Ceaef9764f2008-05-13 18:45:46 +00004398 pkeyObj = Build_PyString(pkey.data, pkey.size);
Gregory P. Smith19699a92004-06-28 04:06:49 +00004399
Gregory P. Smith4e414d82006-01-24 19:55:02 +00004400 if (key.data && key.size) /* return key, pkey and data */
Gregory P. Smith19699a92004-06-28 04:06:49 +00004401 {
4402 PyObject *keyObj;
4403 int type = _DB_get_type(self->mydb);
4404 if (type == DB_RECNO || type == DB_QUEUE)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00004405 keyObj = NUMBER_FromLong(*(int *)key.data);
Gregory P. Smith19699a92004-06-28 04:06:49 +00004406 else
Jesus Ceaef9764f2008-05-13 18:45:46 +00004407 keyObj = Build_PyString(key.data, key.size);
Gregory P. Smith4e414d82006-01-24 19:55:02 +00004408 retval = PyTuple_Pack(3, keyObj, pkeyObj, dataObj);
Thomas Woutersb3153832006-03-08 01:47:19 +00004409 Py_DECREF(keyObj);
Jesus Ceaef9764f2008-05-13 18:45:46 +00004410 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Gregory P. Smith19699a92004-06-28 04:06:49 +00004411 }
4412 else /* return just the pkey and data */
4413 {
Gregory P. Smith4e414d82006-01-24 19:55:02 +00004414 retval = PyTuple_Pack(2, pkeyObj, dataObj);
Gregory P. Smith19699a92004-06-28 04:06:49 +00004415 }
Thomas Woutersb3153832006-03-08 01:47:19 +00004416 Py_DECREF(dataObj);
4417 Py_DECREF(pkeyObj);
Gregory P. Smith19699a92004-06-28 04:06:49 +00004418 FREE_DBT(pkey);
Gregory P. Smith19699a92004-06-28 04:06:49 +00004419 }
4420 /* the only time REALLOC should be set is if we used an integer
4421 * key that make_key_dbt malloc'd for us. always free these. */
Jesus Ceaef9764f2008-05-13 18:45:46 +00004422 if (key.flags & DB_DBT_REALLOC) { /* 'make_key_dbt' could do a 'malloc' */
Gregory P. Smith19699a92004-06-28 04:06:49 +00004423 FREE_DBT(key);
4424 }
4425 return retval;
4426}
4427
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004428
4429static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00004430DBC_get_recno(DBCursorObject* self)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004431{
4432 int err;
4433 db_recno_t recno;
4434 DBT key;
4435 DBT data;
4436
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004437 CHECK_CURSOR_NOT_CLOSED(self);
4438
4439 CLEAR_DBT(key);
4440 CLEAR_DBT(data);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004441
4442 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004443 err = _DBC_get(self->dbc, &key, &data, DB_GET_RECNO);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004444 MYDB_END_ALLOW_THREADS;
4445 RETURN_IF_ERR();
4446
4447 recno = *((db_recno_t*)data.data);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00004448 return NUMBER_FromLong(recno);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004449}
4450
4451
4452static PyObject*
4453DBC_last(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4454{
4455 return _DBCursor_get(self,DB_LAST,args,kwargs,"|iii:last");
4456}
4457
4458
4459static PyObject*
4460DBC_next(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4461{
4462 return _DBCursor_get(self,DB_NEXT,args,kwargs,"|iii:next");
4463}
4464
4465
4466static PyObject*
4467DBC_prev(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4468{
4469 return _DBCursor_get(self,DB_PREV,args,kwargs,"|iii:prev");
4470}
4471
4472
4473static PyObject*
4474DBC_put(DBCursorObject* self, PyObject* args, PyObject* kwargs)
4475{
4476 int err, flags = 0;
4477 PyObject* keyobj, *dataobj;
4478 DBT key, data;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00004479 static char* kwnames[] = { "key", "data", "flags", "dlen", "doff",
Jeremy Hyltonaf68c872005-12-10 18:50:16 +00004480 NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004481 int dlen = -1;
4482 int doff = -1;
4483
4484 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|iii:put", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004485 &keyobj, &dataobj, &flags, &dlen, &doff))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004486 return NULL;
4487
4488 CHECK_CURSOR_NOT_CLOSED(self);
4489
4490 if (!make_key_dbt(self->mydb, keyobj, &key, NULL))
4491 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004492 if (!make_dbt(dataobj, &data) ||
4493 !add_partial_dbt(&data, dlen, doff) )
4494 {
Jesus Ceaef9764f2008-05-13 18:45:46 +00004495 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004496 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004497 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004498
4499 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004500 err = _DBC_put(self->dbc, &key, &data, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004501 MYDB_END_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004502 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004503 RETURN_IF_ERR();
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004504 RETURN_NONE();
4505}
4506
4507
4508static PyObject*
4509DBC_set(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4510{
4511 int err, flags = 0;
4512 DBT key, data;
4513 PyObject* retval, *keyobj;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00004514 static char* kwnames[] = { "key", "flags", "dlen", "doff", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004515 int dlen = -1;
4516 int doff = -1;
4517
4518 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|iii:set", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004519 &keyobj, &flags, &dlen, &doff))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004520 return NULL;
4521
4522 CHECK_CURSOR_NOT_CLOSED(self);
4523
4524 if (!make_key_dbt(self->mydb, keyobj, &key, NULL))
4525 return NULL;
4526
4527 CLEAR_DBT(data);
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004528 if (!add_partial_dbt(&data, dlen, doff)) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00004529 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004530 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004531 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004532
4533 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004534 err = _DBC_get(self->dbc, &key, &data, flags|DB_SET);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004535 MYDB_END_ALLOW_THREADS;
Gregory P. Smithe9477062005-06-04 06:46:59 +00004536 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004537 && self->mydb->moduleFlags.cursorSetReturnsNone) {
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004538 Py_INCREF(Py_None);
4539 retval = Py_None;
4540 }
4541 else if (makeDBError(err)) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004542 retval = NULL;
4543 }
4544 else {
4545 switch (_DB_get_type(self->mydb)) {
4546 case -1:
4547 retval = NULL;
4548 break;
4549 case DB_BTREE:
4550 case DB_HASH:
4551 default:
Jesus Ceaef9764f2008-05-13 18:45:46 +00004552 retval = BuildValue_SS(key.data, key.size, data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004553 break;
4554 case DB_RECNO:
4555 case DB_QUEUE:
Jesus Ceaef9764f2008-05-13 18:45:46 +00004556 retval = BuildValue_IS(*((db_recno_t*)key.data), data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004557 break;
4558 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00004559 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004560 }
Gregory P. Smith19699a92004-06-28 04:06:49 +00004561 /* the only time REALLOC should be set is if we used an integer
4562 * key that make_key_dbt malloc'd for us. always free these. */
4563 if (key.flags & DB_DBT_REALLOC) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00004564 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Gregory P. Smith19699a92004-06-28 04:06:49 +00004565 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004566
4567 return retval;
4568}
4569
4570
4571static PyObject*
4572DBC_set_range(DBCursorObject* self, PyObject* args, PyObject* kwargs)
4573{
4574 int err, flags = 0;
4575 DBT key, data;
4576 PyObject* retval, *keyobj;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00004577 static char* kwnames[] = { "key", "flags", "dlen", "doff", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004578 int dlen = -1;
4579 int doff = -1;
4580
4581 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|iii:set_range", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004582 &keyobj, &flags, &dlen, &doff))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004583 return NULL;
4584
4585 CHECK_CURSOR_NOT_CLOSED(self);
4586
4587 if (!make_key_dbt(self->mydb, keyobj, &key, NULL))
4588 return NULL;
4589
4590 CLEAR_DBT(data);
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004591 if (!add_partial_dbt(&data, dlen, doff)) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00004592 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004593 return NULL;
4594 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004595 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004596 err = _DBC_get(self->dbc, &key, &data, flags|DB_SET_RANGE);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004597 MYDB_END_ALLOW_THREADS;
Gregory P. Smithe9477062005-06-04 06:46:59 +00004598 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004599 && self->mydb->moduleFlags.cursorSetReturnsNone) {
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004600 Py_INCREF(Py_None);
4601 retval = Py_None;
4602 }
4603 else if (makeDBError(err)) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004604 retval = NULL;
4605 }
4606 else {
4607 switch (_DB_get_type(self->mydb)) {
4608 case -1:
4609 retval = NULL;
4610 break;
4611 case DB_BTREE:
4612 case DB_HASH:
4613 default:
Jesus Ceaef9764f2008-05-13 18:45:46 +00004614 retval = BuildValue_SS(key.data, key.size, data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004615 break;
4616 case DB_RECNO:
4617 case DB_QUEUE:
Jesus Ceaef9764f2008-05-13 18:45:46 +00004618 retval = BuildValue_IS(*((db_recno_t*)key.data), data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004619 break;
4620 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00004621 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004622 }
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004623 /* the only time REALLOC should be set is if we used an integer
Gregory P. Smith19699a92004-06-28 04:06:49 +00004624 * key that make_key_dbt malloc'd for us. always free these. */
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004625 if (key.flags & DB_DBT_REALLOC) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00004626 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004627 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004628
4629 return retval;
4630}
4631
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004632static PyObject*
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004633_DBC_get_set_both(DBCursorObject* self, PyObject* keyobj, PyObject* dataobj,
4634 int flags, unsigned int returnsNone)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004635{
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004636 int err;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004637 DBT key, data;
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004638 PyObject* retval;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004639
Gregory P. Smith7441e652003-11-03 21:35:31 +00004640 /* the caller did this: CHECK_CURSOR_NOT_CLOSED(self); */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004641 if (!make_key_dbt(self->mydb, keyobj, &key, NULL))
4642 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004643 if (!make_dbt(dataobj, &data)) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00004644 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004645 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004646 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004647
4648 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004649 err = _DBC_get(self->dbc, &key, &data, flags|DB_GET_BOTH);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004650 MYDB_END_ALLOW_THREADS;
Gregory P. Smithe9477062005-06-04 06:46:59 +00004651 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY) && returnsNone) {
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004652 Py_INCREF(Py_None);
4653 retval = Py_None;
4654 }
4655 else if (makeDBError(err)) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004656 retval = NULL;
4657 }
4658 else {
4659 switch (_DB_get_type(self->mydb)) {
4660 case -1:
4661 retval = NULL;
4662 break;
4663 case DB_BTREE:
4664 case DB_HASH:
4665 default:
Jesus Ceaef9764f2008-05-13 18:45:46 +00004666 retval = BuildValue_SS(key.data, key.size, data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004667 break;
4668 case DB_RECNO:
4669 case DB_QUEUE:
Jesus Ceaef9764f2008-05-13 18:45:46 +00004670 retval = BuildValue_IS(*((db_recno_t*)key.data), data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004671 break;
4672 }
4673 }
4674
Jesus Ceaef9764f2008-05-13 18:45:46 +00004675 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004676 return retval;
4677}
4678
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004679static PyObject*
4680DBC_get_both(DBCursorObject* self, PyObject* args)
4681{
4682 int flags=0;
4683 PyObject *keyobj, *dataobj;
4684
4685 if (!PyArg_ParseTuple(args, "OO|i:get_both", &keyobj, &dataobj, &flags))
4686 return NULL;
4687
Gregory P. Smith7441e652003-11-03 21:35:31 +00004688 /* if the cursor is closed, self->mydb may be invalid */
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004689 CHECK_CURSOR_NOT_CLOSED(self);
4690
4691 return _DBC_get_set_both(self, keyobj, dataobj, flags,
4692 self->mydb->moduleFlags.getReturnsNone);
4693}
4694
Gregory P. Smithbe0db8b2003-10-01 06:48:51 +00004695/* Return size of entry */
4696static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00004697DBC_get_current_size(DBCursorObject* self)
Gregory P. Smithbe0db8b2003-10-01 06:48:51 +00004698{
4699 int err, flags=DB_CURRENT;
4700 PyObject* retval = NULL;
4701 DBT key, data;
4702
Gregory P. Smithbe0db8b2003-10-01 06:48:51 +00004703 CHECK_CURSOR_NOT_CLOSED(self);
4704 CLEAR_DBT(key);
4705 CLEAR_DBT(data);
4706
Gregory P. Smith8b7e9172004-12-13 09:51:23 +00004707 /* We don't allocate any memory, forcing a DB_BUFFER_SMALL error and thus
Gregory P. Smithbe0db8b2003-10-01 06:48:51 +00004708 getting the record size. */
4709 data.flags = DB_DBT_USERMEM;
4710 data.ulen = 0;
4711 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004712 err = _DBC_get(self->dbc, &key, &data, flags);
Gregory P. Smithbe0db8b2003-10-01 06:48:51 +00004713 MYDB_END_ALLOW_THREADS;
Gregory P. Smith8b7e9172004-12-13 09:51:23 +00004714 if (err == DB_BUFFER_SMALL || !err) {
4715 /* DB_BUFFER_SMALL means positive size, !err means zero length value */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00004716 retval = NUMBER_FromLong((long)data.size);
Gregory P. Smithbe0db8b2003-10-01 06:48:51 +00004717 err = 0;
4718 }
4719
Gregory P. Smithbe0db8b2003-10-01 06:48:51 +00004720 RETURN_IF_ERR();
4721 return retval;
4722}
4723
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004724static PyObject*
4725DBC_set_both(DBCursorObject* self, PyObject* args)
4726{
4727 int flags=0;
4728 PyObject *keyobj, *dataobj;
4729
4730 if (!PyArg_ParseTuple(args, "OO|i:set_both", &keyobj, &dataobj, &flags))
4731 return NULL;
4732
Gregory P. Smith7441e652003-11-03 21:35:31 +00004733 /* if the cursor is closed, self->mydb may be invalid */
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004734 CHECK_CURSOR_NOT_CLOSED(self);
4735
4736 return _DBC_get_set_both(self, keyobj, dataobj, flags,
4737 self->mydb->moduleFlags.cursorSetReturnsNone);
4738}
4739
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004740
4741static PyObject*
4742DBC_set_recno(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4743{
4744 int err, irecno, flags=0;
4745 db_recno_t recno;
4746 DBT key, data;
4747 PyObject* retval;
4748 int dlen = -1;
4749 int doff = -1;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00004750 static char* kwnames[] = { "recno","flags", "dlen", "doff", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004751
4752 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|iii:set_recno", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004753 &irecno, &flags, &dlen, &doff))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004754 return NULL;
4755
4756 CHECK_CURSOR_NOT_CLOSED(self);
4757
4758 CLEAR_DBT(key);
4759 recno = (db_recno_t) irecno;
Barry Warsaw9a0d7792002-12-30 20:53:52 +00004760 /* use allocated space so DB will be able to realloc room for the real
4761 * key */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004762 key.data = malloc(sizeof(db_recno_t));
4763 if (key.data == NULL) {
4764 PyErr_SetString(PyExc_MemoryError, "Key memory allocation failed");
4765 return NULL;
4766 }
4767 key.size = sizeof(db_recno_t);
4768 key.ulen = key.size;
4769 memcpy(key.data, &recno, sizeof(db_recno_t));
4770 key.flags = DB_DBT_REALLOC;
4771
4772 CLEAR_DBT(data);
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004773 if (!add_partial_dbt(&data, dlen, doff)) {
4774 FREE_DBT(key);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004775 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004776 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004777
4778 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004779 err = _DBC_get(self->dbc, &key, &data, flags|DB_SET_RECNO);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004780 MYDB_END_ALLOW_THREADS;
Gregory P. Smithe9477062005-06-04 06:46:59 +00004781 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004782 && self->mydb->moduleFlags.cursorSetReturnsNone) {
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004783 Py_INCREF(Py_None);
4784 retval = Py_None;
4785 }
4786 else if (makeDBError(err)) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004787 retval = NULL;
4788 }
4789 else { /* Can only be used for BTrees, so no need to return int key */
Jesus Ceaef9764f2008-05-13 18:45:46 +00004790 retval = BuildValue_SS(key.data, key.size, data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004791 }
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004792 FREE_DBT(key);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004793
4794 return retval;
4795}
4796
4797
4798static PyObject*
4799DBC_consume(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4800{
4801 return _DBCursor_get(self,DB_CONSUME,args,kwargs,"|iii:consume");
4802}
4803
4804
4805static PyObject*
4806DBC_next_dup(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4807{
4808 return _DBCursor_get(self,DB_NEXT_DUP,args,kwargs,"|iii:next_dup");
4809}
4810
4811
4812static PyObject*
4813DBC_next_nodup(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4814{
4815 return _DBCursor_get(self,DB_NEXT_NODUP,args,kwargs,"|iii:next_nodup");
4816}
4817
Jesus Cea6557aac2010-03-22 14:22:26 +00004818#if (DBVER >= 46)
4819static PyObject*
4820DBC_prev_dup(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4821{
4822 return _DBCursor_get(self,DB_PREV_DUP,args,kwargs,"|iii:prev_dup");
4823}
4824#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004825
4826static PyObject*
4827DBC_prev_nodup(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4828{
4829 return _DBCursor_get(self,DB_PREV_NODUP,args,kwargs,"|iii:prev_nodup");
4830}
4831
4832
4833static PyObject*
4834DBC_join_item(DBCursorObject* self, PyObject* args)
4835{
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004836 int err, flags=0;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004837 DBT key, data;
4838 PyObject* retval;
4839
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004840 if (!PyArg_ParseTuple(args, "|i:join_item", &flags))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004841 return NULL;
4842
4843 CHECK_CURSOR_NOT_CLOSED(self);
4844
4845 CLEAR_DBT(key);
4846 CLEAR_DBT(data);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004847
4848 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004849 err = _DBC_get(self->dbc, &key, &data, flags | DB_JOIN_ITEM);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004850 MYDB_END_ALLOW_THREADS;
Gregory P. Smithe9477062005-06-04 06:46:59 +00004851 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004852 && self->mydb->moduleFlags.getReturnsNone) {
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004853 Py_INCREF(Py_None);
4854 retval = Py_None;
4855 }
4856 else if (makeDBError(err)) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004857 retval = NULL;
4858 }
4859 else {
Jesus Ceaef9764f2008-05-13 18:45:46 +00004860 retval = BuildValue_S(key.data, key.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004861 }
4862
4863 return retval;
4864}
4865
4866
Jesus Cea6557aac2010-03-22 14:22:26 +00004867#if (DBVER >= 46)
4868static PyObject*
4869DBC_set_priority(DBCursorObject* self, PyObject* args, PyObject* kwargs)
4870{
4871 int err, priority;
4872 static char* kwnames[] = { "priority", NULL };
4873
4874 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i:set_priority", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004875 &priority))
Jesus Cea6557aac2010-03-22 14:22:26 +00004876 return NULL;
4877
4878 CHECK_CURSOR_NOT_CLOSED(self);
4879
4880 MYDB_BEGIN_ALLOW_THREADS;
4881 err = self->dbc->set_priority(self->dbc, priority);
4882 MYDB_END_ALLOW_THREADS;
4883 RETURN_IF_ERR();
4884 RETURN_NONE();
4885}
4886
4887
4888static PyObject*
4889DBC_get_priority(DBCursorObject* self)
4890{
4891 int err;
4892 DB_CACHE_PRIORITY priority;
4893
4894 CHECK_CURSOR_NOT_CLOSED(self);
4895
4896 MYDB_BEGIN_ALLOW_THREADS;
4897 err = self->dbc->get_priority(self->dbc, &priority);
4898 MYDB_END_ALLOW_THREADS;
4899 RETURN_IF_ERR();
4900 return NUMBER_FromLong(priority);
4901}
4902#endif
4903
4904
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004905
4906/* --------------------------------------------------------------------- */
4907/* DBEnv methods */
4908
4909
4910static PyObject*
Jesus Ceaef9764f2008-05-13 18:45:46 +00004911DBEnv_close_internal(DBEnvObject* self, int flags)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004912{
Jesus Ceaef9764f2008-05-13 18:45:46 +00004913 PyObject *dummy;
4914 int err;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004915
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004916 if (!self->closed) { /* Don't close more than once */
Jesus Ceaef9764f2008-05-13 18:45:46 +00004917 while(self->children_txns) {
Jesus Cea6557aac2010-03-22 14:22:26 +00004918 dummy = DBTxn_abort_discard_internal(self->children_txns, 0);
4919 Py_XDECREF(dummy);
Jesus Ceaef9764f2008-05-13 18:45:46 +00004920 }
4921 while(self->children_dbs) {
Jesus Cea6557aac2010-03-22 14:22:26 +00004922 dummy = DB_close_internal(self->children_dbs, 0, 0);
4923 Py_XDECREF(dummy);
4924 }
4925 while(self->children_logcursors) {
4926 dummy = DBLogCursor_close_internal(self->children_logcursors);
4927 Py_XDECREF(dummy);
Jesus Ceaef9764f2008-05-13 18:45:46 +00004928 }
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07004929#if (DBVER >= 52)
4930 while(self->children_sites) {
4931 dummy = DBSite_close_internal(self->children_sites);
4932 Py_XDECREF(dummy);
4933 }
4934#endif
Jesus Ceaac25fab2008-09-03 17:50:32 +00004935 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00004936
Jesus Ceaac25fab2008-09-03 17:50:32 +00004937 self->closed = 1;
4938 if (self->db_env) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004939 MYDB_BEGIN_ALLOW_THREADS;
4940 err = self->db_env->close(self->db_env, flags);
4941 MYDB_END_ALLOW_THREADS;
4942 /* after calling DBEnv->close, regardless of error, this DBEnv
Jesus Ceaef9764f2008-05-13 18:45:46 +00004943 * may not be accessed again (Berkeley DB docs). */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004944 self->db_env = NULL;
4945 RETURN_IF_ERR();
4946 }
4947 RETURN_NONE();
4948}
4949
Jesus Ceaef9764f2008-05-13 18:45:46 +00004950static PyObject*
4951DBEnv_close(DBEnvObject* self, PyObject* args)
4952{
4953 int flags = 0;
4954
4955 if (!PyArg_ParseTuple(args, "|i:close", &flags))
4956 return NULL;
Jesus Cea5cd5f122008-09-23 18:54:08 +00004957 return DBEnv_close_internal(self, flags);
Jesus Ceaef9764f2008-05-13 18:45:46 +00004958}
4959
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004960
4961static PyObject*
4962DBEnv_open(DBEnvObject* self, PyObject* args)
4963{
4964 int err, flags=0, mode=0660;
4965 char *db_home;
4966
4967 if (!PyArg_ParseTuple(args, "z|ii:open", &db_home, &flags, &mode))
4968 return NULL;
4969
4970 CHECK_ENV_NOT_CLOSED(self);
4971
4972 MYDB_BEGIN_ALLOW_THREADS;
4973 err = self->db_env->open(self->db_env, db_home, flags, mode);
4974 MYDB_END_ALLOW_THREADS;
4975 RETURN_IF_ERR();
4976 self->closed = 0;
4977 self->flags = flags;
4978 RETURN_NONE();
4979}
4980
4981
4982static PyObject*
Jesus Cea6557aac2010-03-22 14:22:26 +00004983DBEnv_memp_stat(DBEnvObject* self, PyObject* args, PyObject *kwargs)
4984{
4985 int err;
4986 DB_MPOOL_STAT *gsp;
4987 DB_MPOOL_FSTAT **fsp, **fsp2;
4988 PyObject* d = NULL, *d2, *d3, *r;
4989 u_int32_t flags = 0;
4990 static char* kwnames[] = { "flags", NULL };
4991
4992 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:memp_stat",
4993 kwnames, &flags))
4994 return NULL;
4995
4996 CHECK_ENV_NOT_CLOSED(self);
4997
4998 MYDB_BEGIN_ALLOW_THREADS;
4999 err = self->db_env->memp_stat(self->db_env, &gsp, &fsp, flags);
5000 MYDB_END_ALLOW_THREADS;
5001 RETURN_IF_ERR();
5002
5003 /* Turn the stat structure into a dictionary */
5004 d = PyDict_New();
5005 if (d == NULL) {
5006 if (gsp)
5007 free(gsp);
5008 return NULL;
5009 }
5010
5011#define MAKE_ENTRY(name) _addIntToDict(d, #name, gsp->st_##name)
5012
5013 MAKE_ENTRY(gbytes);
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07005014 MAKE_ENTRY(bytes);
Jesus Cea6557aac2010-03-22 14:22:26 +00005015 MAKE_ENTRY(ncache);
5016#if (DBVER >= 46)
5017 MAKE_ENTRY(max_ncache);
5018#endif
5019 MAKE_ENTRY(regsize);
Jesus Cea6557aac2010-03-22 14:22:26 +00005020 MAKE_ENTRY(mmapsize);
5021 MAKE_ENTRY(maxopenfd);
5022 MAKE_ENTRY(maxwrite);
5023 MAKE_ENTRY(maxwrite_sleep);
Jesus Cea6557aac2010-03-22 14:22:26 +00005024 MAKE_ENTRY(map);
5025 MAKE_ENTRY(cache_hit);
5026 MAKE_ENTRY(cache_miss);
5027 MAKE_ENTRY(page_create);
5028 MAKE_ENTRY(page_in);
5029 MAKE_ENTRY(page_out);
5030 MAKE_ENTRY(ro_evict);
5031 MAKE_ENTRY(rw_evict);
5032 MAKE_ENTRY(page_trickle);
5033 MAKE_ENTRY(pages);
5034 MAKE_ENTRY(page_clean);
5035 MAKE_ENTRY(page_dirty);
5036 MAKE_ENTRY(hash_buckets);
5037 MAKE_ENTRY(hash_searches);
5038 MAKE_ENTRY(hash_longest);
5039 MAKE_ENTRY(hash_examined);
5040 MAKE_ENTRY(hash_nowait);
5041 MAKE_ENTRY(hash_wait);
5042#if (DBVER >= 45)
5043 MAKE_ENTRY(hash_max_nowait);
5044#endif
5045 MAKE_ENTRY(hash_max_wait);
5046 MAKE_ENTRY(region_wait);
5047 MAKE_ENTRY(region_nowait);
5048#if (DBVER >= 45)
5049 MAKE_ENTRY(mvcc_frozen);
5050 MAKE_ENTRY(mvcc_thawed);
5051 MAKE_ENTRY(mvcc_freed);
5052#endif
5053 MAKE_ENTRY(alloc);
5054 MAKE_ENTRY(alloc_buckets);
5055 MAKE_ENTRY(alloc_max_buckets);
5056 MAKE_ENTRY(alloc_pages);
5057 MAKE_ENTRY(alloc_max_pages);
5058#if (DBVER >= 45)
5059 MAKE_ENTRY(io_wait);
5060#endif
5061#if (DBVER >= 48)
5062 MAKE_ENTRY(sync_interrupted);
5063#endif
5064
5065#undef MAKE_ENTRY
5066 free(gsp);
5067
5068 d2 = PyDict_New();
5069 if (d2 == NULL) {
5070 Py_DECREF(d);
5071 if (fsp)
5072 free(fsp);
5073 return NULL;
5074 }
5075#define MAKE_ENTRY(name) _addIntToDict(d3, #name, (*fsp2)->st_##name)
5076 for(fsp2=fsp;*fsp2; fsp2++) {
5077 d3 = PyDict_New();
5078 if (d3 == NULL) {
5079 Py_DECREF(d);
5080 Py_DECREF(d2);
5081 if (fsp)
5082 free(fsp);
5083 return NULL;
5084 }
5085 MAKE_ENTRY(pagesize);
5086 MAKE_ENTRY(cache_hit);
5087 MAKE_ENTRY(cache_miss);
5088 MAKE_ENTRY(map);
5089 MAKE_ENTRY(page_create);
5090 MAKE_ENTRY(page_in);
5091 MAKE_ENTRY(page_out);
5092 if(PyDict_SetItemString(d2, (*fsp2)->file_name, d3)) {
5093 Py_DECREF(d);
5094 Py_DECREF(d2);
5095 Py_DECREF(d3);
5096 if (fsp)
5097 free(fsp);
5098 return NULL;
5099 }
5100 Py_DECREF(d3);
5101 }
5102
5103#undef MAKE_ENTRY
5104 free(fsp);
5105
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07005106 r = PyTuple_Pack(2, d, d2);
Jesus Cea6557aac2010-03-22 14:22:26 +00005107 Py_DECREF(d);
5108 Py_DECREF(d2);
5109 return r;
5110}
5111
Jesus Cea6557aac2010-03-22 14:22:26 +00005112static PyObject*
5113DBEnv_memp_stat_print(DBEnvObject* self, PyObject* args, PyObject *kwargs)
5114{
5115 int err;
5116 int flags=0;
5117 static char* kwnames[] = { "flags", NULL };
5118
5119 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:memp_stat_print",
5120 kwnames, &flags))
5121 {
5122 return NULL;
5123 }
5124 CHECK_ENV_NOT_CLOSED(self);
5125 MYDB_BEGIN_ALLOW_THREADS;
5126 err = self->db_env->memp_stat_print(self->db_env, flags);
5127 MYDB_END_ALLOW_THREADS;
5128 RETURN_IF_ERR();
5129 RETURN_NONE();
5130}
Jesus Cea6557aac2010-03-22 14:22:26 +00005131
5132
5133static PyObject*
5134DBEnv_memp_trickle(DBEnvObject* self, PyObject* args)
5135{
5136 int err, percent, nwrotep;
5137
5138 if (!PyArg_ParseTuple(args, "i:memp_trickle", &percent))
5139 return NULL;
5140 CHECK_ENV_NOT_CLOSED(self);
5141 MYDB_BEGIN_ALLOW_THREADS;
5142 err = self->db_env->memp_trickle(self->db_env, percent, &nwrotep);
5143 MYDB_END_ALLOW_THREADS;
5144 RETURN_IF_ERR();
5145 return NUMBER_FromLong(nwrotep);
5146}
5147
5148static PyObject*
5149DBEnv_memp_sync(DBEnvObject* self, PyObject* args)
5150{
5151 int err;
5152 DB_LSN lsn = {0, 0};
5153 DB_LSN *lsn_p = NULL;
5154
5155 if (!PyArg_ParseTuple(args, "|(ii):memp_sync", &lsn.file, &lsn.offset))
5156 return NULL;
5157 if ((lsn.file!=0) || (lsn.offset!=0)) {
5158 lsn_p = &lsn;
5159 }
5160 CHECK_ENV_NOT_CLOSED(self);
5161 MYDB_BEGIN_ALLOW_THREADS;
5162 err = self->db_env->memp_sync(self->db_env, lsn_p);
5163 MYDB_END_ALLOW_THREADS;
5164 RETURN_IF_ERR();
5165 RETURN_NONE();
5166}
5167
5168static PyObject*
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005169DBEnv_remove(DBEnvObject* self, PyObject* args)
5170{
5171 int err, flags=0;
5172 char *db_home;
5173
5174 if (!PyArg_ParseTuple(args, "s|i:remove", &db_home, &flags))
5175 return NULL;
5176 CHECK_ENV_NOT_CLOSED(self);
5177 MYDB_BEGIN_ALLOW_THREADS;
5178 err = self->db_env->remove(self->db_env, db_home, flags);
5179 MYDB_END_ALLOW_THREADS;
5180 RETURN_IF_ERR();
5181 RETURN_NONE();
5182}
5183
Barry Warsaw9a0d7792002-12-30 20:53:52 +00005184static PyObject*
5185DBEnv_dbremove(DBEnvObject* self, PyObject* args, PyObject* kwargs)
5186{
5187 int err;
5188 u_int32_t flags=0;
5189 char *file = NULL;
5190 char *database = NULL;
5191 PyObject *txnobj = NULL;
5192 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00005193 static char* kwnames[] = { "file", "database", "txn", "flags",
Jeremy Hyltonaf68c872005-12-10 18:50:16 +00005194 NULL };
Barry Warsaw9a0d7792002-12-30 20:53:52 +00005195
Gregory P. Smith641cddf2006-07-28 01:35:25 +00005196 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|zOi:dbremove", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00005197 &file, &database, &txnobj, &flags)) {
5198 return NULL;
Barry Warsaw9a0d7792002-12-30 20:53:52 +00005199 }
5200 if (!checkTxnObj(txnobj, &txn)) {
5201 return NULL;
5202 }
5203 CHECK_ENV_NOT_CLOSED(self);
5204 MYDB_BEGIN_ALLOW_THREADS;
5205 err = self->db_env->dbremove(self->db_env, txn, file, database, flags);
5206 MYDB_END_ALLOW_THREADS;
5207 RETURN_IF_ERR();
5208 RETURN_NONE();
5209}
5210
5211static PyObject*
5212DBEnv_dbrename(DBEnvObject* self, PyObject* args, PyObject* kwargs)
5213{
5214 int err;
5215 u_int32_t flags=0;
5216 char *file = NULL;
5217 char *database = NULL;
5218 char *newname = NULL;
5219 PyObject *txnobj = NULL;
5220 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00005221 static char* kwnames[] = { "file", "database", "newname", "txn",
Jeremy Hyltonaf68c872005-12-10 18:50:16 +00005222 "flags", NULL };
Barry Warsaw9a0d7792002-12-30 20:53:52 +00005223
Gregory P. Smith641cddf2006-07-28 01:35:25 +00005224 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "szs|Oi:dbrename", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00005225 &file, &database, &newname, &txnobj, &flags)) {
5226 return NULL;
Barry Warsaw9a0d7792002-12-30 20:53:52 +00005227 }
5228 if (!checkTxnObj(txnobj, &txn)) {
5229 return NULL;
5230 }
5231 CHECK_ENV_NOT_CLOSED(self);
5232 MYDB_BEGIN_ALLOW_THREADS;
5233 err = self->db_env->dbrename(self->db_env, txn, file, database, newname,
5234 flags);
5235 MYDB_END_ALLOW_THREADS;
5236 RETURN_IF_ERR();
5237 RETURN_NONE();
5238}
5239
Jesus Cea6557aac2010-03-22 14:22:26 +00005240
5241
Barry Warsaw9a0d7792002-12-30 20:53:52 +00005242static PyObject*
5243DBEnv_set_encrypt(DBEnvObject* self, PyObject* args, PyObject* kwargs)
5244{
5245 int err;
5246 u_int32_t flags=0;
5247 char *passwd = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00005248 static char* kwnames[] = { "passwd", "flags", NULL };
Barry Warsaw9a0d7792002-12-30 20:53:52 +00005249
5250 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|i:set_encrypt", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00005251 &passwd, &flags)) {
5252 return NULL;
Barry Warsaw9a0d7792002-12-30 20:53:52 +00005253 }
5254
5255 MYDB_BEGIN_ALLOW_THREADS;
5256 err = self->db_env->set_encrypt(self->db_env, passwd, flags);
5257 MYDB_END_ALLOW_THREADS;
5258
5259 RETURN_IF_ERR();
5260 RETURN_NONE();
5261}
Jesus Cea6557aac2010-03-22 14:22:26 +00005262
Jesus Cea6557aac2010-03-22 14:22:26 +00005263static PyObject*
5264DBEnv_get_encrypt_flags(DBEnvObject* self)
5265{
5266 int err;
5267 u_int32_t flags;
5268
5269 CHECK_ENV_NOT_CLOSED(self);
5270
5271 MYDB_BEGIN_ALLOW_THREADS;
5272 err = self->db_env->get_encrypt_flags(self->db_env, &flags);
5273 MYDB_END_ALLOW_THREADS;
5274
5275 RETURN_IF_ERR();
5276
5277 return NUMBER_FromLong(flags);
5278}
5279
5280static PyObject*
5281DBEnv_get_timeout(DBEnvObject* self, PyObject* args, PyObject* kwargs)
5282{
5283 int err;
5284 int flag;
5285 u_int32_t timeout;
5286 static char* kwnames[] = {"flag", NULL };
5287
5288 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i:get_timeout", kwnames,
5289 &flag)) {
5290 return NULL;
5291 }
5292 CHECK_ENV_NOT_CLOSED(self);
5293
5294 MYDB_BEGIN_ALLOW_THREADS;
5295 err = self->db_env->get_timeout(self->db_env, &timeout, flag);
5296 MYDB_END_ALLOW_THREADS;
5297 RETURN_IF_ERR();
5298 return NUMBER_FromLong(timeout);
5299}
Jesus Cea6557aac2010-03-22 14:22:26 +00005300
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005301
Gregory P. Smithfe11d3e2003-03-27 17:23:29 +00005302static PyObject*
5303DBEnv_set_timeout(DBEnvObject* self, PyObject* args, PyObject* kwargs)
5304{
5305 int err;
5306 u_int32_t flags=0;
5307 u_int32_t timeout = 0;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00005308 static char* kwnames[] = { "timeout", "flags", NULL };
Gregory P. Smithfe11d3e2003-03-27 17:23:29 +00005309
5310 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ii:set_timeout", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00005311 &timeout, &flags)) {
5312 return NULL;
Gregory P. Smithfe11d3e2003-03-27 17:23:29 +00005313 }
5314
5315 MYDB_BEGIN_ALLOW_THREADS;
5316 err = self->db_env->set_timeout(self->db_env, (db_timeout_t)timeout, flags);
5317 MYDB_END_ALLOW_THREADS;
5318
5319 RETURN_IF_ERR();
5320 RETURN_NONE();
5321}
Gregory P. Smithfe11d3e2003-03-27 17:23:29 +00005322
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005323static PyObject*
Gregory P. Smith6676f6e2003-08-28 21:50:30 +00005324DBEnv_set_shm_key(DBEnvObject* self, PyObject* args)
5325{
5326 int err;
5327 long shm_key = 0;
5328
5329 if (!PyArg_ParseTuple(args, "l:set_shm_key", &shm_key))
5330 return NULL;
5331 CHECK_ENV_NOT_CLOSED(self);
5332
5333 err = self->db_env->set_shm_key(self->db_env, shm_key);
5334 RETURN_IF_ERR();
5335 RETURN_NONE();
5336}
5337
Jesus Cea6557aac2010-03-22 14:22:26 +00005338static PyObject*
5339DBEnv_get_shm_key(DBEnvObject* self)
5340{
5341 int err;
5342 long shm_key;
5343
5344 CHECK_ENV_NOT_CLOSED(self);
5345
5346 MYDB_BEGIN_ALLOW_THREADS;
5347 err = self->db_env->get_shm_key(self->db_env, &shm_key);
5348 MYDB_END_ALLOW_THREADS;
5349
5350 RETURN_IF_ERR();
5351
5352 return NUMBER_FromLong(shm_key);
5353}
Jesus Cea6557aac2010-03-22 14:22:26 +00005354
5355#if (DBVER >= 46)
5356static PyObject*
5357DBEnv_set_cache_max(DBEnvObject* self, PyObject* args)
5358{
5359 int err, gbytes, bytes;
5360
5361 if (!PyArg_ParseTuple(args, "ii:set_cache_max",
5362 &gbytes, &bytes))
5363 return NULL;
5364 CHECK_ENV_NOT_CLOSED(self);
5365
5366 MYDB_BEGIN_ALLOW_THREADS;
5367 err = self->db_env->set_cache_max(self->db_env, gbytes, bytes);
5368 MYDB_END_ALLOW_THREADS;
5369 RETURN_IF_ERR();
5370 RETURN_NONE();
5371}
5372
5373static PyObject*
5374DBEnv_get_cache_max(DBEnvObject* self)
5375{
5376 int err;
5377 u_int32_t gbytes, bytes;
5378
5379 CHECK_ENV_NOT_CLOSED(self);
5380
5381 MYDB_BEGIN_ALLOW_THREADS;
5382 err = self->db_env->get_cache_max(self->db_env, &gbytes, &bytes);
5383 MYDB_END_ALLOW_THREADS;
5384
5385 RETURN_IF_ERR();
5386
5387 return Py_BuildValue("(ii)", gbytes, bytes);
5388}
5389#endif
5390
5391#if (DBVER >= 46)
5392static PyObject*
5393DBEnv_set_thread_count(DBEnvObject* self, PyObject* args)
5394{
5395 int err;
5396 u_int32_t count;
5397
5398 if (!PyArg_ParseTuple(args, "i:set_thread_count", &count))
5399 return NULL;
5400 CHECK_ENV_NOT_CLOSED(self);
5401
5402 MYDB_BEGIN_ALLOW_THREADS;
5403 err = self->db_env->set_thread_count(self->db_env, count);
5404 MYDB_END_ALLOW_THREADS;
5405 RETURN_IF_ERR();
5406 RETURN_NONE();
5407}
5408
5409static PyObject*
5410DBEnv_get_thread_count(DBEnvObject* self)
5411{
5412 int err;
5413 u_int32_t count;
5414
5415 CHECK_ENV_NOT_CLOSED(self);
5416
5417 MYDB_BEGIN_ALLOW_THREADS;
5418 err = self->db_env->get_thread_count(self->db_env, &count);
5419 MYDB_END_ALLOW_THREADS;
5420 RETURN_IF_ERR();
5421 return NUMBER_FromLong(count);
5422}
5423#endif
5424
Gregory P. Smith6676f6e2003-08-28 21:50:30 +00005425static PyObject*
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005426DBEnv_set_cachesize(DBEnvObject* self, PyObject* args)
5427{
5428 int err, gbytes=0, bytes=0, ncache=0;
5429
5430 if (!PyArg_ParseTuple(args, "ii|i:set_cachesize",
5431 &gbytes, &bytes, &ncache))
5432 return NULL;
5433 CHECK_ENV_NOT_CLOSED(self);
5434
5435 MYDB_BEGIN_ALLOW_THREADS;
5436 err = self->db_env->set_cachesize(self->db_env, gbytes, bytes, ncache);
5437 MYDB_END_ALLOW_THREADS;
5438 RETURN_IF_ERR();
5439 RETURN_NONE();
5440}
5441
Jesus Cea6557aac2010-03-22 14:22:26 +00005442static PyObject*
5443DBEnv_get_cachesize(DBEnvObject* self)
5444{
5445 int err;
5446 u_int32_t gbytes, bytes;
5447 int ncache;
5448
5449 CHECK_ENV_NOT_CLOSED(self);
5450
5451 MYDB_BEGIN_ALLOW_THREADS;
5452 err = self->db_env->get_cachesize(self->db_env, &gbytes, &bytes, &ncache);
5453 MYDB_END_ALLOW_THREADS;
5454
5455 RETURN_IF_ERR();
5456
5457 return Py_BuildValue("(iii)", gbytes, bytes, ncache);
5458}
Jesus Cea6557aac2010-03-22 14:22:26 +00005459
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005460
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005461static PyObject*
5462DBEnv_set_flags(DBEnvObject* self, PyObject* args)
5463{
5464 int err, flags=0, onoff=0;
5465
5466 if (!PyArg_ParseTuple(args, "ii:set_flags",
5467 &flags, &onoff))
5468 return NULL;
5469 CHECK_ENV_NOT_CLOSED(self);
5470
5471 MYDB_BEGIN_ALLOW_THREADS;
5472 err = self->db_env->set_flags(self->db_env, flags, onoff);
5473 MYDB_END_ALLOW_THREADS;
5474 RETURN_IF_ERR();
5475 RETURN_NONE();
5476}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005477
Jesus Cea6557aac2010-03-22 14:22:26 +00005478static PyObject*
5479DBEnv_get_flags(DBEnvObject* self)
5480{
5481 int err;
5482 u_int32_t flags;
5483
5484 CHECK_ENV_NOT_CLOSED(self);
5485
5486 MYDB_BEGIN_ALLOW_THREADS;
5487 err = self->db_env->get_flags(self->db_env, &flags);
5488 MYDB_END_ALLOW_THREADS;
5489 RETURN_IF_ERR();
5490 return NUMBER_FromLong(flags);
5491}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005492
Jesus Ceaca3939c2008-05-22 15:27:38 +00005493#if (DBVER >= 47)
5494static PyObject*
5495DBEnv_log_set_config(DBEnvObject* self, PyObject* args)
5496{
5497 int err, flags, onoff;
5498
5499 if (!PyArg_ParseTuple(args, "ii:log_set_config",
5500 &flags, &onoff))
5501 return NULL;
5502 CHECK_ENV_NOT_CLOSED(self);
5503
5504 MYDB_BEGIN_ALLOW_THREADS;
5505 err = self->db_env->log_set_config(self->db_env, flags, onoff);
5506 MYDB_END_ALLOW_THREADS;
5507 RETURN_IF_ERR();
5508 RETURN_NONE();
5509}
Jesus Cea6557aac2010-03-22 14:22:26 +00005510
5511static PyObject*
5512DBEnv_log_get_config(DBEnvObject* self, PyObject* args)
5513{
5514 int err, flag, onoff;
5515
5516 if (!PyArg_ParseTuple(args, "i:log_get_config", &flag))
5517 return NULL;
5518 CHECK_ENV_NOT_CLOSED(self);
5519
5520 MYDB_BEGIN_ALLOW_THREADS;
5521 err = self->db_env->log_get_config(self->db_env, flag, &onoff);
5522 MYDB_END_ALLOW_THREADS;
5523 RETURN_IF_ERR();
5524 return PyBool_FromLong(onoff);
5525}
Jesus Ceaca3939c2008-05-22 15:27:38 +00005526#endif /* DBVER >= 47 */
5527
Jesus Cea6557aac2010-03-22 14:22:26 +00005528#if (DBVER >= 44)
5529static PyObject*
5530DBEnv_mutex_set_max(DBEnvObject* self, PyObject* args)
5531{
5532 int err;
5533 int value;
5534
5535 if (!PyArg_ParseTuple(args, "i:mutex_set_max", &value))
5536 return NULL;
5537
5538 CHECK_ENV_NOT_CLOSED(self);
5539
5540 MYDB_BEGIN_ALLOW_THREADS;
5541 err = self->db_env->mutex_set_max(self->db_env, value);
5542 MYDB_END_ALLOW_THREADS;
5543
5544 RETURN_IF_ERR();
5545 RETURN_NONE();
5546}
5547
5548static PyObject*
5549DBEnv_mutex_get_max(DBEnvObject* self)
5550{
5551 int err;
5552 u_int32_t value;
5553
5554 CHECK_ENV_NOT_CLOSED(self);
5555
5556 MYDB_BEGIN_ALLOW_THREADS;
5557 err = self->db_env->mutex_get_max(self->db_env, &value);
5558 MYDB_END_ALLOW_THREADS;
5559
5560 RETURN_IF_ERR();
5561
5562 return NUMBER_FromLong(value);
5563}
5564
5565static PyObject*
5566DBEnv_mutex_set_align(DBEnvObject* self, PyObject* args)
5567{
5568 int err;
5569 int align;
5570
5571 if (!PyArg_ParseTuple(args, "i:mutex_set_align", &align))
5572 return NULL;
5573
5574 CHECK_ENV_NOT_CLOSED(self);
5575
5576 MYDB_BEGIN_ALLOW_THREADS;
5577 err = self->db_env->mutex_set_align(self->db_env, align);
5578 MYDB_END_ALLOW_THREADS;
5579
5580 RETURN_IF_ERR();
5581 RETURN_NONE();
5582}
5583
5584static PyObject*
5585DBEnv_mutex_get_align(DBEnvObject* self)
5586{
5587 int err;
5588 u_int32_t align;
5589
5590 CHECK_ENV_NOT_CLOSED(self);
5591
5592 MYDB_BEGIN_ALLOW_THREADS;
5593 err = self->db_env->mutex_get_align(self->db_env, &align);
5594 MYDB_END_ALLOW_THREADS;
5595
5596 RETURN_IF_ERR();
5597
5598 return NUMBER_FromLong(align);
5599}
5600
5601static PyObject*
5602DBEnv_mutex_set_increment(DBEnvObject* self, PyObject* args)
5603{
5604 int err;
5605 int increment;
5606
5607 if (!PyArg_ParseTuple(args, "i:mutex_set_increment", &increment))
5608 return NULL;
5609
5610 CHECK_ENV_NOT_CLOSED(self);
5611
5612 MYDB_BEGIN_ALLOW_THREADS;
5613 err = self->db_env->mutex_set_increment(self->db_env, increment);
5614 MYDB_END_ALLOW_THREADS;
5615
5616 RETURN_IF_ERR();
5617 RETURN_NONE();
5618}
5619
5620static PyObject*
5621DBEnv_mutex_get_increment(DBEnvObject* self)
5622{
5623 int err;
5624 u_int32_t increment;
5625
5626 CHECK_ENV_NOT_CLOSED(self);
5627
5628 MYDB_BEGIN_ALLOW_THREADS;
5629 err = self->db_env->mutex_get_increment(self->db_env, &increment);
5630 MYDB_END_ALLOW_THREADS;
5631
5632 RETURN_IF_ERR();
5633
5634 return NUMBER_FromLong(increment);
5635}
5636
5637static PyObject*
5638DBEnv_mutex_set_tas_spins(DBEnvObject* self, PyObject* args)
5639{
5640 int err;
5641 int tas_spins;
5642
5643 if (!PyArg_ParseTuple(args, "i:mutex_set_tas_spins", &tas_spins))
5644 return NULL;
5645
5646 CHECK_ENV_NOT_CLOSED(self);
5647
5648 MYDB_BEGIN_ALLOW_THREADS;
5649 err = self->db_env->mutex_set_tas_spins(self->db_env, tas_spins);
5650 MYDB_END_ALLOW_THREADS;
5651
5652 RETURN_IF_ERR();
5653 RETURN_NONE();
5654}
5655
5656static PyObject*
5657DBEnv_mutex_get_tas_spins(DBEnvObject* self)
5658{
5659 int err;
5660 u_int32_t tas_spins;
5661
5662 CHECK_ENV_NOT_CLOSED(self);
5663
5664 MYDB_BEGIN_ALLOW_THREADS;
5665 err = self->db_env->mutex_get_tas_spins(self->db_env, &tas_spins);
5666 MYDB_END_ALLOW_THREADS;
5667
5668 RETURN_IF_ERR();
5669
5670 return NUMBER_FromLong(tas_spins);
5671}
5672#endif
Jesus Ceaca3939c2008-05-22 15:27:38 +00005673
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005674static PyObject*
5675DBEnv_set_data_dir(DBEnvObject* self, PyObject* args)
5676{
5677 int err;
5678 char *dir;
5679
5680 if (!PyArg_ParseTuple(args, "s:set_data_dir", &dir))
5681 return NULL;
5682 CHECK_ENV_NOT_CLOSED(self);
5683
5684 MYDB_BEGIN_ALLOW_THREADS;
5685 err = self->db_env->set_data_dir(self->db_env, dir);
5686 MYDB_END_ALLOW_THREADS;
5687 RETURN_IF_ERR();
5688 RETURN_NONE();
5689}
5690
Jesus Cea6557aac2010-03-22 14:22:26 +00005691static PyObject*
5692DBEnv_get_data_dirs(DBEnvObject* self)
5693{
5694 int err;
5695 PyObject *tuple;
5696 PyObject *item;
5697 const char **dirpp;
5698 int size, i;
5699
5700 CHECK_ENV_NOT_CLOSED(self);
5701
5702 MYDB_BEGIN_ALLOW_THREADS;
5703 err = self->db_env->get_data_dirs(self->db_env, &dirpp);
5704 MYDB_END_ALLOW_THREADS;
5705
5706 RETURN_IF_ERR();
5707
5708 /*
5709 ** Calculate size. Python C API
5710 ** actually allows for tuple resizing,
5711 ** but this is simple enough.
5712 */
5713 for (size=0; *(dirpp+size) ; size++);
5714
5715 tuple = PyTuple_New(size);
5716 if (!tuple)
5717 return NULL;
5718
5719 for (i=0; i<size; i++) {
5720 item = PyBytes_FromString (*(dirpp+i));
5721 if (item == NULL) {
5722 Py_DECREF(tuple);
5723 tuple = NULL;
5724 break;
5725 }
5726 PyTuple_SET_ITEM(tuple, i, item);
5727 }
5728 return tuple;
5729}
Jesus Cea6557aac2010-03-22 14:22:26 +00005730
5731#if (DBVER >= 44)
5732static PyObject*
5733DBEnv_set_lg_filemode(DBEnvObject* self, PyObject* args)
5734{
5735 int err, filemode;
5736
5737 if (!PyArg_ParseTuple(args, "i:set_lg_filemode", &filemode))
5738 return NULL;
5739 CHECK_ENV_NOT_CLOSED(self);
5740
5741 MYDB_BEGIN_ALLOW_THREADS;
5742 err = self->db_env->set_lg_filemode(self->db_env, filemode);
5743 MYDB_END_ALLOW_THREADS;
5744 RETURN_IF_ERR();
5745 RETURN_NONE();
5746}
5747
5748static PyObject*
5749DBEnv_get_lg_filemode(DBEnvObject* self)
5750{
5751 int err, filemode;
5752
5753 CHECK_ENV_NOT_CLOSED(self);
5754
5755 MYDB_BEGIN_ALLOW_THREADS;
5756 err = self->db_env->get_lg_filemode(self->db_env, &filemode);
5757 MYDB_END_ALLOW_THREADS;
5758 RETURN_IF_ERR();
5759 return NUMBER_FromLong(filemode);
5760}
5761#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005762
5763static PyObject*
5764DBEnv_set_lg_bsize(DBEnvObject* self, PyObject* args)
5765{
5766 int err, lg_bsize;
5767
5768 if (!PyArg_ParseTuple(args, "i:set_lg_bsize", &lg_bsize))
5769 return NULL;
5770 CHECK_ENV_NOT_CLOSED(self);
5771
5772 MYDB_BEGIN_ALLOW_THREADS;
5773 err = self->db_env->set_lg_bsize(self->db_env, lg_bsize);
5774 MYDB_END_ALLOW_THREADS;
5775 RETURN_IF_ERR();
5776 RETURN_NONE();
5777}
5778
Jesus Cea6557aac2010-03-22 14:22:26 +00005779static PyObject*
5780DBEnv_get_lg_bsize(DBEnvObject* self)
5781{
5782 int err;
5783 u_int32_t lg_bsize;
5784
5785 CHECK_ENV_NOT_CLOSED(self);
5786
5787 MYDB_BEGIN_ALLOW_THREADS;
5788 err = self->db_env->get_lg_bsize(self->db_env, &lg_bsize);
5789 MYDB_END_ALLOW_THREADS;
5790 RETURN_IF_ERR();
5791 return NUMBER_FromLong(lg_bsize);
5792}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005793
5794static PyObject*
5795DBEnv_set_lg_dir(DBEnvObject* self, PyObject* args)
5796{
5797 int err;
5798 char *dir;
5799
5800 if (!PyArg_ParseTuple(args, "s:set_lg_dir", &dir))
5801 return NULL;
5802 CHECK_ENV_NOT_CLOSED(self);
5803
5804 MYDB_BEGIN_ALLOW_THREADS;
5805 err = self->db_env->set_lg_dir(self->db_env, dir);
5806 MYDB_END_ALLOW_THREADS;
5807 RETURN_IF_ERR();
5808 RETURN_NONE();
5809}
5810
Jesus Cea6557aac2010-03-22 14:22:26 +00005811static PyObject*
5812DBEnv_get_lg_dir(DBEnvObject* self)
5813{
5814 int err;
5815 const char *dirp;
5816
5817 CHECK_ENV_NOT_CLOSED(self);
5818
5819 MYDB_BEGIN_ALLOW_THREADS;
5820 err = self->db_env->get_lg_dir(self->db_env, &dirp);
5821 MYDB_END_ALLOW_THREADS;
5822 RETURN_IF_ERR();
5823 return PyBytes_FromString(dirp);
5824}
Jesus Cea6557aac2010-03-22 14:22:26 +00005825
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005826static PyObject*
5827DBEnv_set_lg_max(DBEnvObject* self, PyObject* args)
5828{
5829 int err, lg_max;
5830
5831 if (!PyArg_ParseTuple(args, "i:set_lg_max", &lg_max))
5832 return NULL;
5833 CHECK_ENV_NOT_CLOSED(self);
5834
5835 MYDB_BEGIN_ALLOW_THREADS;
5836 err = self->db_env->set_lg_max(self->db_env, lg_max);
5837 MYDB_END_ALLOW_THREADS;
5838 RETURN_IF_ERR();
5839 RETURN_NONE();
5840}
5841
Jesus Ceaef9764f2008-05-13 18:45:46 +00005842static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00005843DBEnv_get_lg_max(DBEnvObject* self)
Jesus Ceaef9764f2008-05-13 18:45:46 +00005844{
5845 int err;
5846 u_int32_t lg_max;
5847
Jesus Ceaef9764f2008-05-13 18:45:46 +00005848 CHECK_ENV_NOT_CLOSED(self);
5849
5850 MYDB_BEGIN_ALLOW_THREADS;
5851 err = self->db_env->get_lg_max(self->db_env, &lg_max);
5852 MYDB_END_ALLOW_THREADS;
5853 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00005854 return NUMBER_FromLong(lg_max);
Jesus Ceaef9764f2008-05-13 18:45:46 +00005855}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005856
5857static PyObject*
Gregory P. Smithe9477062005-06-04 06:46:59 +00005858DBEnv_set_lg_regionmax(DBEnvObject* self, PyObject* args)
5859{
5860 int err, lg_max;
5861
5862 if (!PyArg_ParseTuple(args, "i:set_lg_regionmax", &lg_max))
5863 return NULL;
5864 CHECK_ENV_NOT_CLOSED(self);
5865
5866 MYDB_BEGIN_ALLOW_THREADS;
5867 err = self->db_env->set_lg_regionmax(self->db_env, lg_max);
5868 MYDB_END_ALLOW_THREADS;
5869 RETURN_IF_ERR();
5870 RETURN_NONE();
5871}
5872
Jesus Cea6557aac2010-03-22 14:22:26 +00005873static PyObject*
5874DBEnv_get_lg_regionmax(DBEnvObject* self)
5875{
5876 int err;
5877 u_int32_t lg_regionmax;
5878
5879 CHECK_ENV_NOT_CLOSED(self);
5880
5881 MYDB_BEGIN_ALLOW_THREADS;
5882 err = self->db_env->get_lg_regionmax(self->db_env, &lg_regionmax);
5883 MYDB_END_ALLOW_THREADS;
5884 RETURN_IF_ERR();
5885 return NUMBER_FromLong(lg_regionmax);
5886}
Jesus Cea6557aac2010-03-22 14:22:26 +00005887
5888#if (DBVER >= 47)
5889static PyObject*
5890DBEnv_set_lk_partitions(DBEnvObject* self, PyObject* args)
5891{
5892 int err, lk_partitions;
5893
5894 if (!PyArg_ParseTuple(args, "i:set_lk_partitions", &lk_partitions))
5895 return NULL;
5896 CHECK_ENV_NOT_CLOSED(self);
5897
5898 MYDB_BEGIN_ALLOW_THREADS;
5899 err = self->db_env->set_lk_partitions(self->db_env, lk_partitions);
5900 MYDB_END_ALLOW_THREADS;
5901 RETURN_IF_ERR();
5902 RETURN_NONE();
5903}
5904
5905static PyObject*
5906DBEnv_get_lk_partitions(DBEnvObject* self)
5907{
5908 int err;
5909 u_int32_t lk_partitions;
5910
5911 CHECK_ENV_NOT_CLOSED(self);
5912
5913 MYDB_BEGIN_ALLOW_THREADS;
5914 err = self->db_env->get_lk_partitions(self->db_env, &lk_partitions);
5915 MYDB_END_ALLOW_THREADS;
5916 RETURN_IF_ERR();
5917 return NUMBER_FromLong(lk_partitions);
5918}
5919#endif
Gregory P. Smithe9477062005-06-04 06:46:59 +00005920
5921static PyObject*
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005922DBEnv_set_lk_detect(DBEnvObject* self, PyObject* args)
5923{
5924 int err, lk_detect;
5925
5926 if (!PyArg_ParseTuple(args, "i:set_lk_detect", &lk_detect))
5927 return NULL;
5928 CHECK_ENV_NOT_CLOSED(self);
5929
5930 MYDB_BEGIN_ALLOW_THREADS;
5931 err = self->db_env->set_lk_detect(self->db_env, lk_detect);
5932 MYDB_END_ALLOW_THREADS;
5933 RETURN_IF_ERR();
5934 RETURN_NONE();
5935}
5936
Jesus Cea6557aac2010-03-22 14:22:26 +00005937static PyObject*
5938DBEnv_get_lk_detect(DBEnvObject* self)
5939{
5940 int err;
5941 u_int32_t lk_detect;
5942
5943 CHECK_ENV_NOT_CLOSED(self);
5944
5945 MYDB_BEGIN_ALLOW_THREADS;
5946 err = self->db_env->get_lk_detect(self->db_env, &lk_detect);
5947 MYDB_END_ALLOW_THREADS;
5948 RETURN_IF_ERR();
5949 return NUMBER_FromLong(lk_detect);
5950}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005951
Gregory P. Smith8b96a352007-01-05 01:59:42 +00005952#if (DBVER < 45)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005953static PyObject*
5954DBEnv_set_lk_max(DBEnvObject* self, PyObject* args)
5955{
5956 int err, max;
5957
5958 if (!PyArg_ParseTuple(args, "i:set_lk_max", &max))
5959 return NULL;
5960 CHECK_ENV_NOT_CLOSED(self);
5961
5962 MYDB_BEGIN_ALLOW_THREADS;
5963 err = self->db_env->set_lk_max(self->db_env, max);
5964 MYDB_END_ALLOW_THREADS;
5965 RETURN_IF_ERR();
5966 RETURN_NONE();
5967}
Gregory P. Smith8b96a352007-01-05 01:59:42 +00005968#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005969
5970
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005971
5972static PyObject*
5973DBEnv_set_lk_max_locks(DBEnvObject* self, PyObject* args)
5974{
5975 int err, max;
5976
5977 if (!PyArg_ParseTuple(args, "i:set_lk_max_locks", &max))
5978 return NULL;
5979 CHECK_ENV_NOT_CLOSED(self);
5980
5981 MYDB_BEGIN_ALLOW_THREADS;
5982 err = self->db_env->set_lk_max_locks(self->db_env, max);
5983 MYDB_END_ALLOW_THREADS;
5984 RETURN_IF_ERR();
5985 RETURN_NONE();
5986}
5987
Jesus Cea6557aac2010-03-22 14:22:26 +00005988static PyObject*
5989DBEnv_get_lk_max_locks(DBEnvObject* self)
5990{
5991 int err;
5992 u_int32_t lk_max;
5993
5994 CHECK_ENV_NOT_CLOSED(self);
5995
5996 MYDB_BEGIN_ALLOW_THREADS;
5997 err = self->db_env->get_lk_max_locks(self->db_env, &lk_max);
5998 MYDB_END_ALLOW_THREADS;
5999 RETURN_IF_ERR();
6000 return NUMBER_FromLong(lk_max);
6001}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006002
6003static PyObject*
6004DBEnv_set_lk_max_lockers(DBEnvObject* self, PyObject* args)
6005{
6006 int err, max;
6007
6008 if (!PyArg_ParseTuple(args, "i:set_lk_max_lockers", &max))
6009 return NULL;
6010 CHECK_ENV_NOT_CLOSED(self);
6011
6012 MYDB_BEGIN_ALLOW_THREADS;
6013 err = self->db_env->set_lk_max_lockers(self->db_env, max);
6014 MYDB_END_ALLOW_THREADS;
6015 RETURN_IF_ERR();
6016 RETURN_NONE();
6017}
6018
Jesus Cea6557aac2010-03-22 14:22:26 +00006019static PyObject*
6020DBEnv_get_lk_max_lockers(DBEnvObject* self)
6021{
6022 int err;
6023 u_int32_t lk_max;
6024
6025 CHECK_ENV_NOT_CLOSED(self);
6026
6027 MYDB_BEGIN_ALLOW_THREADS;
6028 err = self->db_env->get_lk_max_lockers(self->db_env, &lk_max);
6029 MYDB_END_ALLOW_THREADS;
6030 RETURN_IF_ERR();
6031 return NUMBER_FromLong(lk_max);
6032}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006033
6034static PyObject*
6035DBEnv_set_lk_max_objects(DBEnvObject* self, PyObject* args)
6036{
6037 int err, max;
6038
6039 if (!PyArg_ParseTuple(args, "i:set_lk_max_objects", &max))
6040 return NULL;
6041 CHECK_ENV_NOT_CLOSED(self);
6042
6043 MYDB_BEGIN_ALLOW_THREADS;
6044 err = self->db_env->set_lk_max_objects(self->db_env, max);
6045 MYDB_END_ALLOW_THREADS;
6046 RETURN_IF_ERR();
6047 RETURN_NONE();
6048}
6049
Jesus Cea6557aac2010-03-22 14:22:26 +00006050static PyObject*
6051DBEnv_get_lk_max_objects(DBEnvObject* self)
6052{
6053 int err;
6054 u_int32_t lk_max;
6055
6056 CHECK_ENV_NOT_CLOSED(self);
6057
6058 MYDB_BEGIN_ALLOW_THREADS;
6059 err = self->db_env->get_lk_max_objects(self->db_env, &lk_max);
6060 MYDB_END_ALLOW_THREADS;
6061 RETURN_IF_ERR();
6062 return NUMBER_FromLong(lk_max);
6063}
Jesus Cea6557aac2010-03-22 14:22:26 +00006064
Jesus Cea6557aac2010-03-22 14:22:26 +00006065static PyObject*
6066DBEnv_get_mp_mmapsize(DBEnvObject* self)
6067{
6068 int err;
6069 size_t mmapsize;
6070
6071 CHECK_ENV_NOT_CLOSED(self);
6072
6073 MYDB_BEGIN_ALLOW_THREADS;
6074 err = self->db_env->get_mp_mmapsize(self->db_env, &mmapsize);
6075 MYDB_END_ALLOW_THREADS;
6076 RETURN_IF_ERR();
6077 return NUMBER_FromLong(mmapsize);
6078}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006079
6080static PyObject*
6081DBEnv_set_mp_mmapsize(DBEnvObject* self, PyObject* args)
6082{
6083 int err, mp_mmapsize;
6084
6085 if (!PyArg_ParseTuple(args, "i:set_mp_mmapsize", &mp_mmapsize))
6086 return NULL;
6087 CHECK_ENV_NOT_CLOSED(self);
6088
6089 MYDB_BEGIN_ALLOW_THREADS;
6090 err = self->db_env->set_mp_mmapsize(self->db_env, mp_mmapsize);
6091 MYDB_END_ALLOW_THREADS;
6092 RETURN_IF_ERR();
6093 RETURN_NONE();
6094}
6095
6096
6097static PyObject*
6098DBEnv_set_tmp_dir(DBEnvObject* self, PyObject* args)
6099{
6100 int err;
6101 char *dir;
6102
6103 if (!PyArg_ParseTuple(args, "s:set_tmp_dir", &dir))
6104 return NULL;
6105 CHECK_ENV_NOT_CLOSED(self);
6106
6107 MYDB_BEGIN_ALLOW_THREADS;
6108 err = self->db_env->set_tmp_dir(self->db_env, dir);
6109 MYDB_END_ALLOW_THREADS;
6110 RETURN_IF_ERR();
6111 RETURN_NONE();
6112}
6113
Jesus Cea6557aac2010-03-22 14:22:26 +00006114static PyObject*
6115DBEnv_get_tmp_dir(DBEnvObject* self)
6116{
6117 int err;
6118 const char *dirpp;
6119
6120 CHECK_ENV_NOT_CLOSED(self);
6121
6122 MYDB_BEGIN_ALLOW_THREADS;
6123 err = self->db_env->get_tmp_dir(self->db_env, &dirpp);
6124 MYDB_END_ALLOW_THREADS;
6125
6126 RETURN_IF_ERR();
6127
6128 return PyBytes_FromString(dirpp);
6129}
Jesus Cea6557aac2010-03-22 14:22:26 +00006130
Jesus Ceaef9764f2008-05-13 18:45:46 +00006131static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00006132DBEnv_txn_recover(DBEnvObject* self)
Jesus Ceaef9764f2008-05-13 18:45:46 +00006133{
6134 int flags = DB_FIRST;
6135 int err, i;
6136 PyObject *list, *tuple, *gid;
6137 DBTxnObject *txn;
6138#define PREPLIST_LEN 16
6139 DB_PREPLIST preplist[PREPLIST_LEN];
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07006140#if (DBVER < 48) || (DBVER >= 52)
Jesus Ceaef9764f2008-05-13 18:45:46 +00006141 long retp;
Matthias Klose54cc5392010-03-15 12:46:18 +00006142#else
6143 u_int32_t retp;
6144#endif
Jesus Ceaef9764f2008-05-13 18:45:46 +00006145
Jesus Ceaef9764f2008-05-13 18:45:46 +00006146 CHECK_ENV_NOT_CLOSED(self);
6147
6148 list=PyList_New(0);
6149 if (!list)
6150 return NULL;
6151 while (!0) {
6152 MYDB_BEGIN_ALLOW_THREADS
6153 err=self->db_env->txn_recover(self->db_env,
6154 preplist, PREPLIST_LEN, &retp, flags);
6155#undef PREPLIST_LEN
6156 MYDB_END_ALLOW_THREADS
6157 if (err) {
6158 Py_DECREF(list);
6159 RETURN_IF_ERR();
6160 }
6161 if (!retp) break;
6162 flags=DB_NEXT; /* Prepare for next loop pass */
6163 for (i=0; i<retp; i++) {
Christian Heimes593daf52008-05-26 12:51:38 +00006164 gid=PyBytes_FromStringAndSize((char *)(preplist[i].gid),
Matthias Klose54cc5392010-03-15 12:46:18 +00006165 DB_GID_SIZE);
Jesus Ceaef9764f2008-05-13 18:45:46 +00006166 if (!gid) {
6167 Py_DECREF(list);
6168 return NULL;
6169 }
Jesus Cea6557aac2010-03-22 14:22:26 +00006170 txn=newDBTxnObject(self, NULL, preplist[i].txn, 0);
Jesus Ceaef9764f2008-05-13 18:45:46 +00006171 if (!txn) {
6172 Py_DECREF(list);
6173 Py_DECREF(gid);
6174 return NULL;
6175 }
6176 txn->flag_prepare=1; /* Recover state */
6177 tuple=PyTuple_New(2);
6178 if (!tuple) {
6179 Py_DECREF(list);
6180 Py_DECREF(gid);
6181 Py_DECREF(txn);
6182 return NULL;
6183 }
6184 if (PyTuple_SetItem(tuple, 0, gid)) {
6185 Py_DECREF(list);
6186 Py_DECREF(gid);
6187 Py_DECREF(txn);
6188 Py_DECREF(tuple);
6189 return NULL;
6190 }
6191 if (PyTuple_SetItem(tuple, 1, (PyObject *)txn)) {
6192 Py_DECREF(list);
6193 Py_DECREF(txn);
6194 Py_DECREF(tuple); /* This delete the "gid" also */
6195 return NULL;
6196 }
6197 if (PyList_Append(list, tuple)) {
6198 Py_DECREF(list);
6199 Py_DECREF(tuple);/* This delete the "gid" and the "txn" also */
6200 return NULL;
6201 }
6202 Py_DECREF(tuple);
6203 }
6204 }
6205 return list;
6206}
Jesus Ceaef9764f2008-05-13 18:45:46 +00006207
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006208static PyObject*
6209DBEnv_txn_begin(DBEnvObject* self, PyObject* args, PyObject* kwargs)
6210{
6211 int flags = 0;
6212 PyObject* txnobj = NULL;
6213 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00006214 static char* kwnames[] = { "parent", "flags", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006215
6216 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Oi:txn_begin", kwnames,
6217 &txnobj, &flags))
6218 return NULL;
6219
6220 if (!checkTxnObj(txnobj, &txn))
6221 return NULL;
6222 CHECK_ENV_NOT_CLOSED(self);
6223
Jesus Ceaef9764f2008-05-13 18:45:46 +00006224 return (PyObject*)newDBTxnObject(self, (DBTxnObject *)txnobj, NULL, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006225}
6226
6227
6228static PyObject*
6229DBEnv_txn_checkpoint(DBEnvObject* self, PyObject* args)
6230{
6231 int err, kbyte=0, min=0, flags=0;
6232
6233 if (!PyArg_ParseTuple(args, "|iii:txn_checkpoint", &kbyte, &min, &flags))
6234 return NULL;
6235 CHECK_ENV_NOT_CLOSED(self);
6236
6237 MYDB_BEGIN_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006238 err = self->db_env->txn_checkpoint(self->db_env, kbyte, min, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006239 MYDB_END_ALLOW_THREADS;
6240 RETURN_IF_ERR();
6241 RETURN_NONE();
6242}
6243
Jesus Cea6557aac2010-03-22 14:22:26 +00006244static PyObject*
6245DBEnv_get_tx_max(DBEnvObject* self)
6246{
6247 int err;
6248 u_int32_t max;
6249
6250 CHECK_ENV_NOT_CLOSED(self);
6251
6252 MYDB_BEGIN_ALLOW_THREADS;
6253 err = self->db_env->get_tx_max(self->db_env, &max);
6254 MYDB_END_ALLOW_THREADS;
6255 RETURN_IF_ERR();
6256 return PyLong_FromUnsignedLong(max);
6257}
Jesus Cea6557aac2010-03-22 14:22:26 +00006258
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006259static PyObject*
6260DBEnv_set_tx_max(DBEnvObject* self, PyObject* args)
6261{
6262 int err, max;
6263
6264 if (!PyArg_ParseTuple(args, "i:set_tx_max", &max))
6265 return NULL;
6266 CHECK_ENV_NOT_CLOSED(self);
6267
Jesus Cea6557aac2010-03-22 14:22:26 +00006268 MYDB_BEGIN_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006269 err = self->db_env->set_tx_max(self->db_env, max);
Jesus Cea6557aac2010-03-22 14:22:26 +00006270 MYDB_END_ALLOW_THREADS;
Gregory P. Smith8a474042006-01-27 07:05:40 +00006271 RETURN_IF_ERR();
6272 RETURN_NONE();
6273}
6274
Jesus Cea6557aac2010-03-22 14:22:26 +00006275static PyObject*
6276DBEnv_get_tx_timestamp(DBEnvObject* self)
6277{
6278 int err;
6279 time_t timestamp;
6280
6281 CHECK_ENV_NOT_CLOSED(self);
6282
6283 MYDB_BEGIN_ALLOW_THREADS;
6284 err = self->db_env->get_tx_timestamp(self->db_env, &timestamp);
6285 MYDB_END_ALLOW_THREADS;
6286 RETURN_IF_ERR();
6287 return NUMBER_FromLong(timestamp);
6288}
Jesus Cea6557aac2010-03-22 14:22:26 +00006289
Gregory P. Smith8a474042006-01-27 07:05:40 +00006290static PyObject*
6291DBEnv_set_tx_timestamp(DBEnvObject* self, PyObject* args)
6292{
6293 int err;
Thomas Wouters9d63cca2006-03-01 01:01:55 +00006294 long stamp;
6295 time_t timestamp;
Gregory P. Smith8a474042006-01-27 07:05:40 +00006296
Thomas Wouters9d63cca2006-03-01 01:01:55 +00006297 if (!PyArg_ParseTuple(args, "l:set_tx_timestamp", &stamp))
Gregory P. Smith8a474042006-01-27 07:05:40 +00006298 return NULL;
6299 CHECK_ENV_NOT_CLOSED(self);
Thomas Wouters9d63cca2006-03-01 01:01:55 +00006300 timestamp = (time_t)stamp;
Jesus Cea6557aac2010-03-22 14:22:26 +00006301 MYDB_BEGIN_ALLOW_THREADS;
Thomas Wouters9d63cca2006-03-01 01:01:55 +00006302 err = self->db_env->set_tx_timestamp(self->db_env, &timestamp);
Jesus Cea6557aac2010-03-22 14:22:26 +00006303 MYDB_END_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006304 RETURN_IF_ERR();
6305 RETURN_NONE();
6306}
6307
6308
6309static PyObject*
6310DBEnv_lock_detect(DBEnvObject* self, PyObject* args)
6311{
6312 int err, atype, flags=0;
6313 int aborted = 0;
6314
6315 if (!PyArg_ParseTuple(args, "i|i:lock_detect", &atype, &flags))
6316 return NULL;
6317 CHECK_ENV_NOT_CLOSED(self);
6318
6319 MYDB_BEGIN_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006320 err = self->db_env->lock_detect(self->db_env, flags, atype, &aborted);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006321 MYDB_END_ALLOW_THREADS;
6322 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00006323 return NUMBER_FromLong(aborted);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006324}
6325
6326
6327static PyObject*
6328DBEnv_lock_get(DBEnvObject* self, PyObject* args)
6329{
6330 int flags=0;
6331 int locker, lock_mode;
6332 DBT obj;
6333 PyObject* objobj;
6334
6335 if (!PyArg_ParseTuple(args, "iOi|i:lock_get", &locker, &objobj, &lock_mode, &flags))
6336 return NULL;
6337
6338
6339 if (!make_dbt(objobj, &obj))
6340 return NULL;
6341
6342 return (PyObject*)newDBLockObject(self, locker, &obj, lock_mode, flags);
6343}
6344
6345
6346static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00006347DBEnv_lock_id(DBEnvObject* self)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006348{
6349 int err;
6350 u_int32_t theID;
6351
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006352 CHECK_ENV_NOT_CLOSED(self);
6353 MYDB_BEGIN_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006354 err = self->db_env->lock_id(self->db_env, &theID);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006355 MYDB_END_ALLOW_THREADS;
6356 RETURN_IF_ERR();
6357
Jesus Ceac5a11fa2008-07-23 11:38:42 +00006358 return NUMBER_FromLong((long)theID);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006359}
6360
Gregory P. Smithac11e022007-11-05 02:56:31 +00006361static PyObject*
6362DBEnv_lock_id_free(DBEnvObject* self, PyObject* args)
6363{
6364 int err;
6365 u_int32_t theID;
6366
6367 if (!PyArg_ParseTuple(args, "I:lock_id_free", &theID))
6368 return NULL;
6369
6370 CHECK_ENV_NOT_CLOSED(self);
6371 MYDB_BEGIN_ALLOW_THREADS;
6372 err = self->db_env->lock_id_free(self->db_env, theID);
6373 MYDB_END_ALLOW_THREADS;
6374 RETURN_IF_ERR();
6375 RETURN_NONE();
6376}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006377
6378static PyObject*
6379DBEnv_lock_put(DBEnvObject* self, PyObject* args)
6380{
6381 int err;
6382 DBLockObject* dblockobj;
6383
6384 if (!PyArg_ParseTuple(args, "O!:lock_put", &DBLock_Type, &dblockobj))
6385 return NULL;
6386
6387 CHECK_ENV_NOT_CLOSED(self);
6388 MYDB_BEGIN_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006389 err = self->db_env->lock_put(self->db_env, &dblockobj->lock);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006390 MYDB_END_ALLOW_THREADS;
6391 RETURN_IF_ERR();
6392 RETURN_NONE();
6393}
6394
Gregory P. Smithdb8a8072006-06-05 01:56:15 +00006395#if (DBVER >= 44)
6396static PyObject*
Jesus Cea6557aac2010-03-22 14:22:26 +00006397DBEnv_fileid_reset(DBEnvObject* self, PyObject* args, PyObject* kwargs)
6398{
6399 int err;
6400 char *file;
6401 u_int32_t flags = 0;
6402 static char* kwnames[] = { "file", "flags", NULL};
6403
6404 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "z|i:fileid_reset", kwnames,
6405 &file, &flags))
6406 return NULL;
6407 CHECK_ENV_NOT_CLOSED(self);
6408
6409 MYDB_BEGIN_ALLOW_THREADS;
6410 err = self->db_env->fileid_reset(self->db_env, file, flags);
6411 MYDB_END_ALLOW_THREADS;
6412 RETURN_IF_ERR();
6413 RETURN_NONE();
6414}
6415
6416static PyObject*
Gregory P. Smithdb8a8072006-06-05 01:56:15 +00006417DBEnv_lsn_reset(DBEnvObject* self, PyObject* args, PyObject* kwargs)
6418{
6419 int err;
6420 char *file;
6421 u_int32_t flags = 0;
6422 static char* kwnames[] = { "file", "flags", NULL};
6423
6424 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "z|i:lsn_reset", kwnames,
6425 &file, &flags))
6426 return NULL;
6427 CHECK_ENV_NOT_CLOSED(self);
6428
6429 MYDB_BEGIN_ALLOW_THREADS;
6430 err = self->db_env->lsn_reset(self->db_env, file, flags);
6431 MYDB_END_ALLOW_THREADS;
6432 RETURN_IF_ERR();
6433 RETURN_NONE();
6434}
6435#endif /* DBVER >= 4.4 */
6436
Jesus Cea6557aac2010-03-22 14:22:26 +00006437
Jesus Cea6557aac2010-03-22 14:22:26 +00006438static PyObject*
6439DBEnv_stat_print(DBEnvObject* self, PyObject* args, PyObject *kwargs)
6440{
6441 int err;
6442 int flags=0;
6443 static char* kwnames[] = { "flags", NULL };
6444
6445 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:stat_print",
6446 kwnames, &flags))
6447 {
6448 return NULL;
6449 }
6450 CHECK_ENV_NOT_CLOSED(self);
6451 MYDB_BEGIN_ALLOW_THREADS;
6452 err = self->db_env->stat_print(self->db_env, flags);
6453 MYDB_END_ALLOW_THREADS;
6454 RETURN_IF_ERR();
6455 RETURN_NONE();
6456}
Jesus Cea6557aac2010-03-22 14:22:26 +00006457
6458
Gregory P. Smith76a82e82006-06-05 01:39:52 +00006459static PyObject*
6460DBEnv_log_stat(DBEnvObject* self, PyObject* args)
6461{
6462 int err;
6463 DB_LOG_STAT* statp = NULL;
6464 PyObject* d = NULL;
6465 u_int32_t flags = 0;
6466
6467 if (!PyArg_ParseTuple(args, "|i:log_stat", &flags))
6468 return NULL;
6469 CHECK_ENV_NOT_CLOSED(self);
6470
6471 MYDB_BEGIN_ALLOW_THREADS;
6472 err = self->db_env->log_stat(self->db_env, &statp, flags);
6473 MYDB_END_ALLOW_THREADS;
6474 RETURN_IF_ERR();
6475
6476 /* Turn the stat structure into a dictionary */
6477 d = PyDict_New();
6478 if (d == NULL) {
6479 if (statp)
6480 free(statp);
6481 return NULL;
6482 }
6483
6484#define MAKE_ENTRY(name) _addIntToDict(d, #name, statp->st_##name)
6485
6486 MAKE_ENTRY(magic);
6487 MAKE_ENTRY(version);
6488 MAKE_ENTRY(mode);
6489 MAKE_ENTRY(lg_bsize);
6490#if (DBVER >= 44)
6491 MAKE_ENTRY(lg_size);
6492 MAKE_ENTRY(record);
6493#endif
Gregory P. Smith76a82e82006-06-05 01:39:52 +00006494 MAKE_ENTRY(w_mbytes);
6495 MAKE_ENTRY(w_bytes);
6496 MAKE_ENTRY(wc_mbytes);
6497 MAKE_ENTRY(wc_bytes);
6498 MAKE_ENTRY(wcount);
6499 MAKE_ENTRY(wcount_fill);
6500#if (DBVER >= 44)
6501 MAKE_ENTRY(rcount);
6502#endif
6503 MAKE_ENTRY(scount);
6504 MAKE_ENTRY(cur_file);
6505 MAKE_ENTRY(cur_offset);
6506 MAKE_ENTRY(disk_file);
6507 MAKE_ENTRY(disk_offset);
6508 MAKE_ENTRY(maxcommitperflush);
6509 MAKE_ENTRY(mincommitperflush);
6510 MAKE_ENTRY(regsize);
6511 MAKE_ENTRY(region_wait);
6512 MAKE_ENTRY(region_nowait);
6513
6514#undef MAKE_ENTRY
6515 free(statp);
6516 return d;
6517} /* DBEnv_log_stat */
Gregory P. Smith76a82e82006-06-05 01:39:52 +00006518
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006519
Jesus Cea6557aac2010-03-22 14:22:26 +00006520static PyObject*
6521DBEnv_log_stat_print(DBEnvObject* self, PyObject* args, PyObject *kwargs)
6522{
6523 int err;
6524 int flags=0;
6525 static char* kwnames[] = { "flags", NULL };
6526
6527 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:log_stat_print",
6528 kwnames, &flags))
6529 {
6530 return NULL;
6531 }
6532 CHECK_ENV_NOT_CLOSED(self);
6533 MYDB_BEGIN_ALLOW_THREADS;
6534 err = self->db_env->log_stat_print(self->db_env, flags);
6535 MYDB_END_ALLOW_THREADS;
6536 RETURN_IF_ERR();
6537 RETURN_NONE();
6538}
Jesus Cea6557aac2010-03-22 14:22:26 +00006539
6540
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006541static PyObject*
6542DBEnv_lock_stat(DBEnvObject* self, PyObject* args)
6543{
6544 int err;
6545 DB_LOCK_STAT* sp;
6546 PyObject* d = NULL;
Martin v. Löwisb2c7aff2002-11-23 11:26:07 +00006547 u_int32_t flags = 0;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006548
6549 if (!PyArg_ParseTuple(args, "|i:lock_stat", &flags))
6550 return NULL;
6551 CHECK_ENV_NOT_CLOSED(self);
6552
6553 MYDB_BEGIN_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006554 err = self->db_env->lock_stat(self->db_env, &sp, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006555 MYDB_END_ALLOW_THREADS;
6556 RETURN_IF_ERR();
6557
6558 /* Turn the stat structure into a dictionary */
6559 d = PyDict_New();
6560 if (d == NULL) {
6561 free(sp);
6562 return NULL;
6563 }
6564
6565#define MAKE_ENTRY(name) _addIntToDict(d, #name, sp->st_##name)
6566
Jesus Ceaef9764f2008-05-13 18:45:46 +00006567 MAKE_ENTRY(id);
6568 MAKE_ENTRY(cur_maxid);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006569 MAKE_ENTRY(nmodes);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006570 MAKE_ENTRY(maxlocks);
6571 MAKE_ENTRY(maxlockers);
6572 MAKE_ENTRY(maxobjects);
6573 MAKE_ENTRY(nlocks);
6574 MAKE_ENTRY(maxnlocks);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006575 MAKE_ENTRY(nlockers);
6576 MAKE_ENTRY(maxnlockers);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006577 MAKE_ENTRY(nobjects);
6578 MAKE_ENTRY(maxnobjects);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006579 MAKE_ENTRY(nrequests);
6580 MAKE_ENTRY(nreleases);
Jesus Ceaef9764f2008-05-13 18:45:46 +00006581#if (DBVER >= 44)
6582 MAKE_ENTRY(nupgrade);
6583 MAKE_ENTRY(ndowngrade);
6584#endif
Gregory P. Smith29602d22006-01-24 09:46:48 +00006585#if (DBVER < 44)
6586 MAKE_ENTRY(nnowaits); /* these were renamed in 4.4 */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006587 MAKE_ENTRY(nconflicts);
Gregory P. Smith29602d22006-01-24 09:46:48 +00006588#else
6589 MAKE_ENTRY(lock_nowait);
6590 MAKE_ENTRY(lock_wait);
6591#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006592 MAKE_ENTRY(ndeadlocks);
Jesus Ceaef9764f2008-05-13 18:45:46 +00006593 MAKE_ENTRY(locktimeout);
6594 MAKE_ENTRY(txntimeout);
Jesus Ceaef9764f2008-05-13 18:45:46 +00006595 MAKE_ENTRY(nlocktimeouts);
6596 MAKE_ENTRY(ntxntimeouts);
Jesus Ceaef9764f2008-05-13 18:45:46 +00006597#if (DBVER >= 46)
6598 MAKE_ENTRY(objs_wait);
6599 MAKE_ENTRY(objs_nowait);
6600 MAKE_ENTRY(lockers_wait);
6601 MAKE_ENTRY(lockers_nowait);
Jesus Ceaca3939c2008-05-22 15:27:38 +00006602#if (DBVER >= 47)
6603 MAKE_ENTRY(lock_wait);
6604 MAKE_ENTRY(lock_nowait);
6605#else
Jesus Ceaef9764f2008-05-13 18:45:46 +00006606 MAKE_ENTRY(locks_wait);
6607 MAKE_ENTRY(locks_nowait);
Jesus Ceaca3939c2008-05-22 15:27:38 +00006608#endif
Jesus Ceaef9764f2008-05-13 18:45:46 +00006609 MAKE_ENTRY(hash_len);
6610#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006611 MAKE_ENTRY(regsize);
6612 MAKE_ENTRY(region_wait);
6613 MAKE_ENTRY(region_nowait);
6614
6615#undef MAKE_ENTRY
6616 free(sp);
6617 return d;
6618}
6619
Jesus Cea6557aac2010-03-22 14:22:26 +00006620static PyObject*
6621DBEnv_lock_stat_print(DBEnvObject* self, PyObject* args, PyObject *kwargs)
6622{
6623 int err;
6624 int flags=0;
6625 static char* kwnames[] = { "flags", NULL };
6626
6627 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:lock_stat_print",
6628 kwnames, &flags))
6629 {
6630 return NULL;
6631 }
6632 CHECK_ENV_NOT_CLOSED(self);
6633 MYDB_BEGIN_ALLOW_THREADS;
6634 err = self->db_env->lock_stat_print(self->db_env, flags);
6635 MYDB_END_ALLOW_THREADS;
6636 RETURN_IF_ERR();
6637 RETURN_NONE();
6638}
Jesus Cea6557aac2010-03-22 14:22:26 +00006639
6640
6641static PyObject*
6642DBEnv_log_cursor(DBEnvObject* self)
6643{
6644 int err;
6645 DB_LOGC* dblogc;
6646
6647 CHECK_ENV_NOT_CLOSED(self);
6648
6649 MYDB_BEGIN_ALLOW_THREADS;
6650 err = self->db_env->log_cursor(self->db_env, &dblogc, 0);
6651 MYDB_END_ALLOW_THREADS;
6652 RETURN_IF_ERR();
6653 return (PyObject*) newDBLogCursorObject(dblogc, self);
6654}
6655
6656
Jesus Ceaef9764f2008-05-13 18:45:46 +00006657static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00006658DBEnv_log_flush(DBEnvObject* self)
Jesus Ceaef9764f2008-05-13 18:45:46 +00006659{
6660 int err;
6661
Jesus Ceaef9764f2008-05-13 18:45:46 +00006662 CHECK_ENV_NOT_CLOSED(self);
6663
6664 MYDB_BEGIN_ALLOW_THREADS
6665 err = self->db_env->log_flush(self->db_env, NULL);
6666 MYDB_END_ALLOW_THREADS
6667
6668 RETURN_IF_ERR();
6669 RETURN_NONE();
6670}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006671
6672static PyObject*
Jesus Cea6557aac2010-03-22 14:22:26 +00006673DBEnv_log_file(DBEnvObject* self, PyObject* args)
6674{
6675 int err;
6676 DB_LSN lsn = {0, 0};
6677 int size = 20;
6678 char *name = NULL;
6679 PyObject *retval;
6680
6681 if (!PyArg_ParseTuple(args, "(ii):log_file", &lsn.file, &lsn.offset))
6682 return NULL;
6683
6684 CHECK_ENV_NOT_CLOSED(self);
6685
6686 do {
6687 name = malloc(size);
6688 if (!name) {
6689 PyErr_NoMemory();
6690 return NULL;
6691 }
6692 MYDB_BEGIN_ALLOW_THREADS;
6693 err = self->db_env->log_file(self->db_env, &lsn, name, size);
6694 MYDB_END_ALLOW_THREADS;
6695 if (err == EINVAL) {
6696 free(name);
6697 size *= 2;
6698 } else if (err) {
6699 free(name);
6700 RETURN_IF_ERR();
6701 assert(0); /* Unreachable... supposely */
6702 return NULL;
6703 }
6704/*
6705** If the final buffer we try is too small, we will
6706** get this exception:
6707** DBInvalidArgError:
6708** (22, 'Invalid argument -- DB_ENV->log_file: name buffer is too short')
6709*/
6710 } while ((err == EINVAL) && (size<(1<<17)));
6711
6712 RETURN_IF_ERR(); /* Maybe the size is not the problem */
6713
6714 retval = Py_BuildValue("s", name);
6715 free(name);
6716 return retval;
6717}
6718
6719
6720#if (DBVER >= 44)
6721static PyObject*
6722DBEnv_log_printf(DBEnvObject* self, PyObject* args, PyObject *kwargs)
6723{
6724 int err;
6725 char *string;
6726 PyObject *txnobj = NULL;
6727 DB_TXN *txn = NULL;
6728 static char* kwnames[] = {"string", "txn", NULL };
6729
6730 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|O:log_printf", kwnames,
6731 &string, &txnobj))
6732 return NULL;
6733
6734 CHECK_ENV_NOT_CLOSED(self);
6735
6736 if (!checkTxnObj(txnobj, &txn))
6737 return NULL;
6738
6739 /*
6740 ** Do not use the format string directly, to avoid attacks.
6741 */
6742 MYDB_BEGIN_ALLOW_THREADS;
6743 err = self->db_env->log_printf(self->db_env, txn, "%s", string);
6744 MYDB_END_ALLOW_THREADS;
6745
6746 RETURN_IF_ERR();
6747 RETURN_NONE();
6748}
6749#endif
6750
6751
6752static PyObject*
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006753DBEnv_log_archive(DBEnvObject* self, PyObject* args)
6754{
6755 int flags=0;
6756 int err;
Gregory P. Smith3dd20022006-06-05 00:31:01 +00006757 char **log_list = NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006758 PyObject* list;
6759 PyObject* item = NULL;
6760
6761 if (!PyArg_ParseTuple(args, "|i:log_archive", &flags))
6762 return NULL;
6763
6764 CHECK_ENV_NOT_CLOSED(self);
6765 MYDB_BEGIN_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006766 err = self->db_env->log_archive(self->db_env, &log_list, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006767 MYDB_END_ALLOW_THREADS;
6768 RETURN_IF_ERR();
6769
Gregory P. Smithbad47452006-06-05 00:33:35 +00006770 list = PyList_New(0);
6771 if (list == NULL) {
6772 if (log_list)
6773 free(log_list);
6774 return NULL;
6775 }
6776
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006777 if (log_list) {
Gregory P. Smith3dd20022006-06-05 00:31:01 +00006778 char **log_list_start;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006779 for (log_list_start = log_list; *log_list != NULL; ++log_list) {
Christian Heimes593daf52008-05-26 12:51:38 +00006780 item = PyBytes_FromString (*log_list);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006781 if (item == NULL) {
6782 Py_DECREF(list);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006783 list = NULL;
6784 break;
6785 }
Jesus Ceac5a11fa2008-07-23 11:38:42 +00006786 if (PyList_Append(list, item)) {
6787 Py_DECREF(list);
6788 list = NULL;
6789 Py_DECREF(item);
6790 break;
6791 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006792 Py_DECREF(item);
6793 }
6794 free(log_list_start);
6795 }
6796 return list;
6797}
6798
6799
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07006800#if (DBVER >= 52)
6801static PyObject*
6802DBEnv_repmgr_site(DBEnvObject* self, PyObject* args, PyObject *kwargs)
6803{
6804 int err;
6805 DB_SITE* site;
6806 char *host;
6807 u_int port;
6808 static char* kwnames[] = {"host", "port", NULL};
6809
6810 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "si:repmgr_site", kwnames,
6811 &host, &port))
6812 return NULL;
6813
6814 CHECK_ENV_NOT_CLOSED(self);
6815
6816 MYDB_BEGIN_ALLOW_THREADS;
6817 err = self->db_env->repmgr_site(self->db_env, host, port, &site, 0);
6818 MYDB_END_ALLOW_THREADS;
6819 RETURN_IF_ERR();
6820 return (PyObject*) newDBSiteObject(site, self);
6821}
6822
6823static PyObject*
6824DBEnv_repmgr_site_by_eid(DBEnvObject* self, PyObject* args, PyObject *kwargs)
6825{
6826 int err;
6827 DB_SITE* site;
6828 int eid;
6829 static char* kwnames[] = {"eid", NULL};
6830
6831 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i:repmgr_site_by_eid",
6832 kwnames, &eid))
6833 return NULL;
6834
6835 CHECK_ENV_NOT_CLOSED(self);
6836
6837 MYDB_BEGIN_ALLOW_THREADS;
6838 err = self->db_env->repmgr_site_by_eid(self->db_env, eid, &site);
6839 MYDB_END_ALLOW_THREADS;
6840 RETURN_IF_ERR();
6841 return (PyObject*) newDBSiteObject(site, self);
6842}
6843#endif
6844
6845
Jesus Cea6557aac2010-03-22 14:22:26 +00006846#if (DBVER >= 44)
6847static PyObject*
6848DBEnv_mutex_stat(DBEnvObject* self, PyObject* args)
6849{
6850 int err;
6851 DB_MUTEX_STAT* statp = NULL;
6852 PyObject* d = NULL;
6853 u_int32_t flags = 0;
6854
6855 if (!PyArg_ParseTuple(args, "|i:mutex_stat", &flags))
6856 return NULL;
6857 CHECK_ENV_NOT_CLOSED(self);
6858
6859 MYDB_BEGIN_ALLOW_THREADS;
6860 err = self->db_env->mutex_stat(self->db_env, &statp, flags);
6861 MYDB_END_ALLOW_THREADS;
6862 RETURN_IF_ERR();
6863
6864 /* Turn the stat structure into a dictionary */
6865 d = PyDict_New();
6866 if (d == NULL) {
6867 if (statp)
6868 free(statp);
6869 return NULL;
6870 }
6871
6872#define MAKE_ENTRY(name) _addIntToDict(d, #name, statp->st_##name)
6873
6874 MAKE_ENTRY(mutex_align);
6875 MAKE_ENTRY(mutex_tas_spins);
6876 MAKE_ENTRY(mutex_cnt);
6877 MAKE_ENTRY(mutex_free);
6878 MAKE_ENTRY(mutex_inuse);
6879 MAKE_ENTRY(mutex_inuse_max);
6880 MAKE_ENTRY(regsize);
6881 MAKE_ENTRY(region_wait);
6882 MAKE_ENTRY(region_nowait);
6883
6884#undef MAKE_ENTRY
6885 free(statp);
6886 return d;
6887}
6888#endif
6889
6890
6891#if (DBVER >= 44)
6892static PyObject*
6893DBEnv_mutex_stat_print(DBEnvObject* self, PyObject* args, PyObject *kwargs)
6894{
6895 int err;
6896 int flags=0;
6897 static char* kwnames[] = { "flags", NULL };
6898
6899 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:mutex_stat_print",
6900 kwnames, &flags))
6901 {
6902 return NULL;
6903 }
6904 CHECK_ENV_NOT_CLOSED(self);
6905 MYDB_BEGIN_ALLOW_THREADS;
6906 err = self->db_env->mutex_stat_print(self->db_env, flags);
6907 MYDB_END_ALLOW_THREADS;
6908 RETURN_IF_ERR();
6909 RETURN_NONE();
6910}
6911#endif
6912
6913
Jesus Cea6557aac2010-03-22 14:22:26 +00006914static PyObject*
6915DBEnv_txn_stat_print(DBEnvObject* self, PyObject* args, PyObject *kwargs)
6916{
6917 int err;
6918 int flags=0;
6919 static char* kwnames[] = { "flags", NULL };
6920
6921 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:stat_print",
6922 kwnames, &flags))
6923 {
6924 return NULL;
6925 }
6926
6927 CHECK_ENV_NOT_CLOSED(self);
6928
6929 MYDB_BEGIN_ALLOW_THREADS;
6930 err = self->db_env->txn_stat_print(self->db_env, flags);
6931 MYDB_END_ALLOW_THREADS;
6932 RETURN_IF_ERR();
6933 RETURN_NONE();
6934}
Jesus Cea6557aac2010-03-22 14:22:26 +00006935
6936
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006937static PyObject*
6938DBEnv_txn_stat(DBEnvObject* self, PyObject* args)
6939{
6940 int err;
6941 DB_TXN_STAT* sp;
6942 PyObject* d = NULL;
Martin v. Löwisb2c7aff2002-11-23 11:26:07 +00006943 u_int32_t flags=0;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006944
6945 if (!PyArg_ParseTuple(args, "|i:txn_stat", &flags))
6946 return NULL;
6947 CHECK_ENV_NOT_CLOSED(self);
6948
6949 MYDB_BEGIN_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006950 err = self->db_env->txn_stat(self->db_env, &sp, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006951 MYDB_END_ALLOW_THREADS;
6952 RETURN_IF_ERR();
6953
6954 /* Turn the stat structure into a dictionary */
6955 d = PyDict_New();
6956 if (d == NULL) {
6957 free(sp);
6958 return NULL;
6959 }
6960
Jesus Ceaef9764f2008-05-13 18:45:46 +00006961#define MAKE_ENTRY(name) _addIntToDict(d, #name, sp->st_##name)
6962#define MAKE_TIME_T_ENTRY(name) _addTimeTToDict(d, #name, sp->st_##name)
6963#define MAKE_DB_LSN_ENTRY(name) _addDB_lsnToDict(d, #name, sp->st_##name)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006964
Jesus Ceaef9764f2008-05-13 18:45:46 +00006965 MAKE_DB_LSN_ENTRY(last_ckp);
Kristján Valur Jónssonbd77c032007-04-26 15:24:54 +00006966 MAKE_TIME_T_ENTRY(time_ckp);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006967 MAKE_ENTRY(last_txnid);
6968 MAKE_ENTRY(maxtxns);
6969 MAKE_ENTRY(nactive);
6970 MAKE_ENTRY(maxnactive);
Jesus Ceaef9764f2008-05-13 18:45:46 +00006971#if (DBVER >= 45)
6972 MAKE_ENTRY(nsnapshot);
6973 MAKE_ENTRY(maxnsnapshot);
6974#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006975 MAKE_ENTRY(nbegins);
6976 MAKE_ENTRY(naborts);
6977 MAKE_ENTRY(ncommits);
Jesus Ceaef9764f2008-05-13 18:45:46 +00006978 MAKE_ENTRY(nrestores);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006979 MAKE_ENTRY(regsize);
6980 MAKE_ENTRY(region_wait);
6981 MAKE_ENTRY(region_nowait);
6982
Jesus Ceaef9764f2008-05-13 18:45:46 +00006983#undef MAKE_DB_LSN_ENTRY
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006984#undef MAKE_ENTRY
Kristján Valur Jónssonbd77c032007-04-26 15:24:54 +00006985#undef MAKE_TIME_T_ENTRY
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006986 free(sp);
6987 return d;
6988}
6989
6990
6991static PyObject*
6992DBEnv_set_get_returns_none(DBEnvObject* self, PyObject* args)
6993{
6994 int flags=0;
Gregory P. Smith455d46f2003-07-09 04:45:59 +00006995 int oldValue=0;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006996
6997 if (!PyArg_ParseTuple(args,"i:set_get_returns_none", &flags))
6998 return NULL;
6999 CHECK_ENV_NOT_CLOSED(self);
7000
Gregory P. Smith455d46f2003-07-09 04:45:59 +00007001 if (self->moduleFlags.getReturnsNone)
7002 ++oldValue;
7003 if (self->moduleFlags.cursorSetReturnsNone)
7004 ++oldValue;
7005 self->moduleFlags.getReturnsNone = (flags >= 1);
7006 self->moduleFlags.cursorSetReturnsNone = (flags >= 2);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007007 return NUMBER_FromLong(oldValue);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00007008}
7009
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007010static PyObject*
7011DBEnv_get_private(DBEnvObject* self)
7012{
7013 /* We can give out the private field even if dbenv is closed */
Jesus Cea4907d272008-08-31 14:00:51 +00007014 Py_INCREF(self->private_obj);
7015 return self->private_obj;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007016}
7017
7018static PyObject*
Jesus Cea4907d272008-08-31 14:00:51 +00007019DBEnv_set_private(DBEnvObject* self, PyObject* private_obj)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007020{
7021 /* We can set the private field even if dbenv is closed */
Jesus Cea4907d272008-08-31 14:00:51 +00007022 Py_INCREF(private_obj);
Serhiy Storchaka763a61c2016-04-10 18:05:12 +03007023 Py_SETREF(self->private_obj, private_obj);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007024 RETURN_NONE();
7025}
7026
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07007027#if (DBVER >= 47)
7028static PyObject*
7029DBEnv_set_intermediate_dir_mode(DBEnvObject* self, PyObject* args)
7030{
7031 int err;
7032 const char *mode;
7033
7034 if (!PyArg_ParseTuple(args,"s:set_intermediate_dir_mode", &mode))
7035 return NULL;
7036
7037 CHECK_ENV_NOT_CLOSED(self);
7038
7039 MYDB_BEGIN_ALLOW_THREADS;
7040 err = self->db_env->set_intermediate_dir_mode(self->db_env, mode);
7041 MYDB_END_ALLOW_THREADS;
7042 RETURN_IF_ERR();
7043 RETURN_NONE();
7044}
7045
7046static PyObject*
7047DBEnv_get_intermediate_dir_mode(DBEnvObject* self)
7048{
7049 int err;
7050 const char *mode;
7051
7052 CHECK_ENV_NOT_CLOSED(self);
7053
7054 MYDB_BEGIN_ALLOW_THREADS;
7055 err = self->db_env->get_intermediate_dir_mode(self->db_env, &mode);
7056 MYDB_END_ALLOW_THREADS;
7057 RETURN_IF_ERR();
7058 return Py_BuildValue("s", mode);
7059}
7060#endif
7061
7062#if (DBVER < 47)
7063static PyObject*
7064DBEnv_set_intermediate_dir(DBEnvObject* self, PyObject* args)
7065{
7066 int err;
7067 int mode;
7068 u_int32_t flags;
7069
7070 if (!PyArg_ParseTuple(args, "iI:set_intermediate_dir", &mode, &flags))
7071 return NULL;
7072
7073 CHECK_ENV_NOT_CLOSED(self);
7074
7075 MYDB_BEGIN_ALLOW_THREADS;
7076 err = self->db_env->set_intermediate_dir(self->db_env, mode, flags);
7077 MYDB_END_ALLOW_THREADS;
7078 RETURN_IF_ERR();
7079 RETURN_NONE();
7080}
7081#endif
7082
7083static PyObject*
7084DBEnv_get_open_flags(DBEnvObject* self)
7085{
7086 int err;
7087 unsigned int flags;
7088
7089 CHECK_ENV_NOT_CLOSED(self);
7090
7091 MYDB_BEGIN_ALLOW_THREADS;
7092 err = self->db_env->get_open_flags(self->db_env, &flags);
7093 MYDB_END_ALLOW_THREADS;
7094 RETURN_IF_ERR();
7095 return NUMBER_FromLong(flags);
7096}
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007097
Matthias Klose54cc5392010-03-15 12:46:18 +00007098#if (DBVER < 48)
Jesus Ceaef9764f2008-05-13 18:45:46 +00007099static PyObject*
Jesus Ceaca3939c2008-05-22 15:27:38 +00007100DBEnv_set_rpc_server(DBEnvObject* self, PyObject* args, PyObject* kwargs)
7101{
7102 int err;
7103 char *host;
7104 long cl_timeout=0, sv_timeout=0;
7105
7106 static char* kwnames[] = { "host", "cl_timeout", "sv_timeout", NULL};
7107
7108 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|ll:set_rpc_server", kwnames,
7109 &host, &cl_timeout, &sv_timeout))
7110 return NULL;
7111 CHECK_ENV_NOT_CLOSED(self);
7112
7113 MYDB_BEGIN_ALLOW_THREADS;
7114 err = self->db_env->set_rpc_server(self->db_env, NULL, host, cl_timeout,
7115 sv_timeout, 0);
7116 MYDB_END_ALLOW_THREADS;
7117 RETURN_IF_ERR();
7118 RETURN_NONE();
7119}
Matthias Klose54cc5392010-03-15 12:46:18 +00007120#endif
Jesus Ceaca3939c2008-05-22 15:27:38 +00007121
Jesus Cea6557aac2010-03-22 14:22:26 +00007122static PyObject*
7123DBEnv_set_mp_max_openfd(DBEnvObject* self, PyObject* args)
7124{
7125 int err;
7126 int maxopenfd;
7127
7128 if (!PyArg_ParseTuple(args, "i:set_mp_max_openfd", &maxopenfd)) {
7129 return NULL;
7130 }
7131 CHECK_ENV_NOT_CLOSED(self);
7132 MYDB_BEGIN_ALLOW_THREADS;
7133 err = self->db_env->set_mp_max_openfd(self->db_env, maxopenfd);
7134 MYDB_END_ALLOW_THREADS;
7135 RETURN_IF_ERR();
7136 RETURN_NONE();
7137}
7138
7139static PyObject*
7140DBEnv_get_mp_max_openfd(DBEnvObject* self)
7141{
7142 int err;
7143 int maxopenfd;
7144
7145 CHECK_ENV_NOT_CLOSED(self);
7146
7147 MYDB_BEGIN_ALLOW_THREADS;
7148 err = self->db_env->get_mp_max_openfd(self->db_env, &maxopenfd);
7149 MYDB_END_ALLOW_THREADS;
7150 RETURN_IF_ERR();
7151 return NUMBER_FromLong(maxopenfd);
7152}
7153
7154
7155static PyObject*
7156DBEnv_set_mp_max_write(DBEnvObject* self, PyObject* args)
7157{
7158 int err;
7159 int maxwrite, maxwrite_sleep;
7160
7161 if (!PyArg_ParseTuple(args, "ii:set_mp_max_write", &maxwrite,
7162 &maxwrite_sleep)) {
7163 return NULL;
7164 }
7165 CHECK_ENV_NOT_CLOSED(self);
7166 MYDB_BEGIN_ALLOW_THREADS;
7167 err = self->db_env->set_mp_max_write(self->db_env, maxwrite,
7168 maxwrite_sleep);
7169 MYDB_END_ALLOW_THREADS;
7170 RETURN_IF_ERR();
7171 RETURN_NONE();
7172}
7173
7174static PyObject*
7175DBEnv_get_mp_max_write(DBEnvObject* self)
7176{
7177 int err;
7178 int maxwrite;
7179#if (DBVER >= 46)
7180 db_timeout_t maxwrite_sleep;
7181#else
7182 int maxwrite_sleep;
7183#endif
7184
7185 CHECK_ENV_NOT_CLOSED(self);
7186
7187 MYDB_BEGIN_ALLOW_THREADS;
7188 err = self->db_env->get_mp_max_write(self->db_env, &maxwrite,
7189 &maxwrite_sleep);
7190 MYDB_END_ALLOW_THREADS;
7191 RETURN_IF_ERR();
7192
7193 return Py_BuildValue("(ii)", maxwrite, (int)maxwrite_sleep);
7194}
Jesus Cea6557aac2010-03-22 14:22:26 +00007195
7196
Jesus Ceaca3939c2008-05-22 15:27:38 +00007197static PyObject*
Jesus Ceaef9764f2008-05-13 18:45:46 +00007198DBEnv_set_verbose(DBEnvObject* self, PyObject* args)
7199{
7200 int err;
7201 int which, onoff;
7202
7203 if (!PyArg_ParseTuple(args, "ii:set_verbose", &which, &onoff)) {
7204 return NULL;
7205 }
7206 CHECK_ENV_NOT_CLOSED(self);
7207 MYDB_BEGIN_ALLOW_THREADS;
7208 err = self->db_env->set_verbose(self->db_env, which, onoff);
7209 MYDB_END_ALLOW_THREADS;
7210 RETURN_IF_ERR();
7211 RETURN_NONE();
7212}
7213
Jesus Ceaef9764f2008-05-13 18:45:46 +00007214static PyObject*
7215DBEnv_get_verbose(DBEnvObject* self, PyObject* args)
7216{
7217 int err;
7218 int which;
7219 int verbose;
7220
7221 if (!PyArg_ParseTuple(args, "i:get_verbose", &which)) {
7222 return NULL;
7223 }
7224 CHECK_ENV_NOT_CLOSED(self);
7225 MYDB_BEGIN_ALLOW_THREADS;
7226 err = self->db_env->get_verbose(self->db_env, which, &verbose);
7227 MYDB_END_ALLOW_THREADS;
7228 RETURN_IF_ERR();
7229 return PyBool_FromLong(verbose);
7230}
Jesus Ceaef9764f2008-05-13 18:45:46 +00007231
7232#if (DBVER >= 45)
7233static void
7234_dbenv_event_notifyCallback(DB_ENV* db_env, u_int32_t event, void *event_info)
7235{
7236 DBEnvObject *dbenv;
7237 PyObject* callback;
7238 PyObject* args;
7239 PyObject* result = NULL;
7240
7241 MYDB_BEGIN_BLOCK_THREADS;
7242 dbenv = (DBEnvObject *)db_env->app_private;
7243 callback = dbenv->event_notifyCallback;
7244 if (callback) {
7245 if (event == DB_EVENT_REP_NEWMASTER) {
7246 args = Py_BuildValue("(Oii)", dbenv, event, *((int *)event_info));
7247 } else {
7248 args = Py_BuildValue("(OiO)", dbenv, event, Py_None);
7249 }
7250 if (args) {
7251 result = PyEval_CallObject(callback, args);
7252 }
7253 if ((!args) || (!result)) {
7254 PyErr_Print();
7255 }
7256 Py_XDECREF(args);
7257 Py_XDECREF(result);
7258 }
7259 MYDB_END_BLOCK_THREADS;
7260}
7261#endif
7262
7263#if (DBVER >= 45)
7264static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007265DBEnv_set_event_notify(DBEnvObject* self, PyObject* notifyFunc)
Jesus Ceaef9764f2008-05-13 18:45:46 +00007266{
7267 int err;
Jesus Ceaef9764f2008-05-13 18:45:46 +00007268
7269 CHECK_ENV_NOT_CLOSED(self);
7270
7271 if (!PyCallable_Check(notifyFunc)) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00007272 makeTypeError("Callable", notifyFunc);
7273 return NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00007274 }
7275
Jesus Ceaef9764f2008-05-13 18:45:46 +00007276 Py_INCREF(notifyFunc);
Serhiy Storchakabc62af12016-04-06 09:51:18 +03007277 Py_XSETREF(self->event_notifyCallback, notifyFunc);
Jesus Ceaef9764f2008-05-13 18:45:46 +00007278
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007279 /* This is to workaround a problem with un-initialized threads (see
7280 comment in DB_associate) */
7281#ifdef WITH_THREAD
7282 PyEval_InitThreads();
7283#endif
7284
Jesus Ceaef9764f2008-05-13 18:45:46 +00007285 MYDB_BEGIN_ALLOW_THREADS;
7286 err = self->db_env->set_event_notify(self->db_env, _dbenv_event_notifyCallback);
7287 MYDB_END_ALLOW_THREADS;
7288
7289 if (err) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00007290 Py_DECREF(notifyFunc);
7291 self->event_notifyCallback = NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00007292 }
7293
7294 RETURN_IF_ERR();
7295 RETURN_NONE();
7296}
7297#endif
7298
7299
7300/* --------------------------------------------------------------------- */
7301/* REPLICATION METHODS: Base Replication */
7302
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007303
7304static PyObject*
7305DBEnv_rep_process_message(DBEnvObject* self, PyObject* args)
7306{
7307 int err;
7308 PyObject *control_py, *rec_py;
7309 DBT control, rec;
7310 int envid;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007311 DB_LSN lsn;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007312
7313 if (!PyArg_ParseTuple(args, "OOi:rep_process_message", &control_py,
7314 &rec_py, &envid))
7315 return NULL;
7316 CHECK_ENV_NOT_CLOSED(self);
7317
7318 if (!make_dbt(control_py, &control))
7319 return NULL;
7320 if (!make_dbt(rec_py, &rec))
7321 return NULL;
7322
7323 MYDB_BEGIN_ALLOW_THREADS;
7324#if (DBVER >= 46)
7325 err = self->db_env->rep_process_message(self->db_env, &control, &rec,
7326 envid, &lsn);
7327#else
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007328 err = self->db_env->rep_process_message(self->db_env, &control, &rec,
7329 &envid, &lsn);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007330#endif
7331 MYDB_END_ALLOW_THREADS;
7332 switch (err) {
7333 case DB_REP_NEWMASTER :
7334 return Py_BuildValue("(iO)", envid, Py_None);
7335 break;
7336
7337 case DB_REP_DUPMASTER :
7338 case DB_REP_HOLDELECTION :
7339#if (DBVER >= 44)
7340 case DB_REP_IGNORE :
7341 case DB_REP_JOIN_FAILURE :
7342#endif
7343 return Py_BuildValue("(iO)", err, Py_None);
7344 break;
7345 case DB_REP_NEWSITE :
Jesus Cea4907d272008-08-31 14:00:51 +00007346 {
7347 PyObject *tmp, *r;
7348
7349 if (!(tmp = PyBytes_FromStringAndSize(rec.data, rec.size))) {
7350 return NULL;
7351 }
7352
7353 r = Py_BuildValue("(iO)", err, tmp);
7354 Py_DECREF(tmp);
7355 return r;
7356 break;
7357 }
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007358 case DB_REP_NOTPERM :
7359 case DB_REP_ISPERM :
7360 return Py_BuildValue("(i(ll))", err, lsn.file, lsn.offset);
7361 break;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007362 }
7363 RETURN_IF_ERR();
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07007364 return PyTuple_Pack(2, Py_None, Py_None);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007365}
7366
7367static int
7368_DBEnv_rep_transportCallback(DB_ENV* db_env, const DBT* control, const DBT* rec,
7369 const DB_LSN *lsn, int envid, u_int32_t flags)
7370{
7371 DBEnvObject *dbenv;
7372 PyObject* rep_transport;
7373 PyObject* args;
Jesus Cea4907d272008-08-31 14:00:51 +00007374 PyObject *a, *b;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007375 PyObject* result = NULL;
7376 int ret=0;
7377
7378 MYDB_BEGIN_BLOCK_THREADS;
7379 dbenv = (DBEnvObject *)db_env->app_private;
7380 rep_transport = dbenv->rep_transport;
7381
Jesus Cea4907d272008-08-31 14:00:51 +00007382 /*
7383 ** The errors in 'a' or 'b' are detected in "Py_BuildValue".
7384 */
7385 a = PyBytes_FromStringAndSize(control->data, control->size);
7386 b = PyBytes_FromStringAndSize(rec->data, rec->size);
7387
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007388 args = Py_BuildValue(
Jesus Cea4907d272008-08-31 14:00:51 +00007389 "(OOO(ll)iI)",
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007390 dbenv,
Jesus Cea4907d272008-08-31 14:00:51 +00007391 a, b,
7392 lsn->file, lsn->offset, envid, flags);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007393 if (args) {
7394 result = PyEval_CallObject(rep_transport, args);
7395 }
7396
7397 if ((!args) || (!result)) {
7398 PyErr_Print();
7399 ret = -1;
7400 }
Jesus Cea4907d272008-08-31 14:00:51 +00007401 Py_XDECREF(a);
7402 Py_XDECREF(b);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007403 Py_XDECREF(args);
7404 Py_XDECREF(result);
7405 MYDB_END_BLOCK_THREADS;
7406 return ret;
7407}
7408
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007409static PyObject*
7410DBEnv_rep_set_transport(DBEnvObject* self, PyObject* args)
7411{
7412 int err;
7413 int envid;
7414 PyObject *rep_transport;
7415
7416 if (!PyArg_ParseTuple(args, "iO:rep_set_transport", &envid, &rep_transport))
7417 return NULL;
7418 CHECK_ENV_NOT_CLOSED(self);
7419 if (!PyCallable_Check(rep_transport)) {
7420 makeTypeError("Callable", rep_transport);
7421 return NULL;
7422 }
7423
7424 MYDB_BEGIN_ALLOW_THREADS;
7425#if (DBVER >=45)
7426 err = self->db_env->rep_set_transport(self->db_env, envid,
7427 &_DBEnv_rep_transportCallback);
7428#else
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007429 err = self->db_env->set_rep_transport(self->db_env, envid,
7430 &_DBEnv_rep_transportCallback);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007431#endif
7432 MYDB_END_ALLOW_THREADS;
7433 RETURN_IF_ERR();
7434
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007435 Py_INCREF(rep_transport);
Serhiy Storchaka763a61c2016-04-10 18:05:12 +03007436 Py_SETREF(self->rep_transport, rep_transport);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007437 RETURN_NONE();
7438}
7439
7440#if (DBVER >= 47)
7441static PyObject*
7442DBEnv_rep_set_request(DBEnvObject* self, PyObject* args)
7443{
7444 int err;
7445 unsigned int minimum, maximum;
7446
7447 if (!PyArg_ParseTuple(args,"II:rep_set_request", &minimum, &maximum))
7448 return NULL;
7449 CHECK_ENV_NOT_CLOSED(self);
7450
7451 MYDB_BEGIN_ALLOW_THREADS;
7452 err = self->db_env->rep_set_request(self->db_env, minimum, maximum);
7453 MYDB_END_ALLOW_THREADS;
7454 RETURN_IF_ERR();
7455 RETURN_NONE();
7456}
7457
7458static PyObject*
7459DBEnv_rep_get_request(DBEnvObject* self)
7460{
7461 int err;
7462 u_int32_t minimum, maximum;
7463
7464 CHECK_ENV_NOT_CLOSED(self);
7465 MYDB_BEGIN_ALLOW_THREADS;
7466 err = self->db_env->rep_get_request(self->db_env, &minimum, &maximum);
7467 MYDB_END_ALLOW_THREADS;
7468 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007469 return Py_BuildValue("II", minimum, maximum);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007470}
7471#endif
7472
7473#if (DBVER >= 45)
7474static PyObject*
7475DBEnv_rep_set_limit(DBEnvObject* self, PyObject* args)
7476{
7477 int err;
7478 int limit;
7479
7480 if (!PyArg_ParseTuple(args,"i:rep_set_limit", &limit))
7481 return NULL;
7482 CHECK_ENV_NOT_CLOSED(self);
7483
7484 MYDB_BEGIN_ALLOW_THREADS;
7485 err = self->db_env->rep_set_limit(self->db_env, 0, limit);
7486 MYDB_END_ALLOW_THREADS;
7487 RETURN_IF_ERR();
7488 RETURN_NONE();
7489}
7490
7491static PyObject*
7492DBEnv_rep_get_limit(DBEnvObject* self)
7493{
7494 int err;
7495 u_int32_t gbytes, bytes;
7496
7497 CHECK_ENV_NOT_CLOSED(self);
7498 MYDB_BEGIN_ALLOW_THREADS;
7499 err = self->db_env->rep_get_limit(self->db_env, &gbytes, &bytes);
7500 MYDB_END_ALLOW_THREADS;
7501 RETURN_IF_ERR();
7502 return NUMBER_FromLong(bytes);
7503}
7504#endif
7505
7506#if (DBVER >= 44)
7507static PyObject*
7508DBEnv_rep_set_config(DBEnvObject* self, PyObject* args)
7509{
7510 int err;
7511 int which;
7512 int onoff;
7513
7514 if (!PyArg_ParseTuple(args,"ii:rep_set_config", &which, &onoff))
7515 return NULL;
7516 CHECK_ENV_NOT_CLOSED(self);
7517
7518 MYDB_BEGIN_ALLOW_THREADS;
7519 err = self->db_env->rep_set_config(self->db_env, which, onoff);
7520 MYDB_END_ALLOW_THREADS;
7521 RETURN_IF_ERR();
7522 RETURN_NONE();
7523}
7524
7525static PyObject*
7526DBEnv_rep_get_config(DBEnvObject* self, PyObject* args)
7527{
7528 int err;
7529 int which;
7530 int onoff;
7531
7532 if (!PyArg_ParseTuple(args, "i:rep_get_config", &which)) {
7533 return NULL;
7534 }
7535 CHECK_ENV_NOT_CLOSED(self);
7536 MYDB_BEGIN_ALLOW_THREADS;
7537 err = self->db_env->rep_get_config(self->db_env, which, &onoff);
7538 MYDB_END_ALLOW_THREADS;
7539 RETURN_IF_ERR();
7540 return PyBool_FromLong(onoff);
7541}
7542#endif
7543
7544#if (DBVER >= 46)
7545static PyObject*
7546DBEnv_rep_elect(DBEnvObject* self, PyObject* args)
7547{
7548 int err;
7549 u_int32_t nsites, nvotes;
7550
7551 if (!PyArg_ParseTuple(args, "II:rep_elect", &nsites, &nvotes)) {
7552 return NULL;
7553 }
7554 CHECK_ENV_NOT_CLOSED(self);
7555 MYDB_BEGIN_ALLOW_THREADS;
Jesus Cea2ab4a912012-01-16 23:57:34 +01007556 err = self->db_env->rep_elect(self->db_env, nsites, nvotes, 0);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007557 MYDB_END_ALLOW_THREADS;
7558 RETURN_IF_ERR();
7559 RETURN_NONE();
7560}
7561#endif
7562
7563static PyObject*
7564DBEnv_rep_start(DBEnvObject* self, PyObject* args, PyObject* kwargs)
7565{
7566 int err;
7567 PyObject *cdata_py = Py_None;
7568 DBT cdata;
7569 int flags;
7570 static char* kwnames[] = {"flags","cdata", NULL};
7571
7572 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
7573 "i|O:rep_start", kwnames, &flags, &cdata_py))
7574 {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00007575 return NULL;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007576 }
7577 CHECK_ENV_NOT_CLOSED(self);
7578
7579 if (!make_dbt(cdata_py, &cdata))
7580 return NULL;
7581
7582 MYDB_BEGIN_ALLOW_THREADS;
7583 err = self->db_env->rep_start(self->db_env, cdata.size ? &cdata : NULL,
7584 flags);
7585 MYDB_END_ALLOW_THREADS;
7586 RETURN_IF_ERR();
7587 RETURN_NONE();
7588}
7589
7590#if (DBVER >= 44)
7591static PyObject*
7592DBEnv_rep_sync(DBEnvObject* self)
7593{
7594 int err;
7595
7596 CHECK_ENV_NOT_CLOSED(self);
7597 MYDB_BEGIN_ALLOW_THREADS;
7598 err = self->db_env->rep_sync(self->db_env, 0);
7599 MYDB_END_ALLOW_THREADS;
7600 RETURN_IF_ERR();
7601 RETURN_NONE();
7602}
7603#endif
7604
7605
Jesus Ceaef9764f2008-05-13 18:45:46 +00007606#if (DBVER >= 45)
7607static PyObject*
7608DBEnv_rep_set_nsites(DBEnvObject* self, PyObject* args)
7609{
7610 int err;
7611 int nsites;
7612
7613 if (!PyArg_ParseTuple(args, "i:rep_set_nsites", &nsites)) {
7614 return NULL;
7615 }
7616 CHECK_ENV_NOT_CLOSED(self);
7617 MYDB_BEGIN_ALLOW_THREADS;
7618 err = self->db_env->rep_set_nsites(self->db_env, nsites);
7619 MYDB_END_ALLOW_THREADS;
7620 RETURN_IF_ERR();
7621 RETURN_NONE();
7622}
7623
7624static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007625DBEnv_rep_get_nsites(DBEnvObject* self)
Jesus Ceaef9764f2008-05-13 18:45:46 +00007626{
7627 int err;
Jesus Ceaca3939c2008-05-22 15:27:38 +00007628#if (DBVER >= 47)
7629 u_int32_t nsites;
7630#else
Jesus Ceaef9764f2008-05-13 18:45:46 +00007631 int nsites;
Jesus Ceaca3939c2008-05-22 15:27:38 +00007632#endif
Jesus Ceaef9764f2008-05-13 18:45:46 +00007633
Jesus Ceaef9764f2008-05-13 18:45:46 +00007634 CHECK_ENV_NOT_CLOSED(self);
7635 MYDB_BEGIN_ALLOW_THREADS;
7636 err = self->db_env->rep_get_nsites(self->db_env, &nsites);
7637 MYDB_END_ALLOW_THREADS;
7638 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007639 return NUMBER_FromLong(nsites);
Jesus Ceaef9764f2008-05-13 18:45:46 +00007640}
7641
7642static PyObject*
7643DBEnv_rep_set_priority(DBEnvObject* self, PyObject* args)
7644{
7645 int err;
7646 int priority;
7647
7648 if (!PyArg_ParseTuple(args, "i:rep_set_priority", &priority)) {
7649 return NULL;
7650 }
7651 CHECK_ENV_NOT_CLOSED(self);
7652 MYDB_BEGIN_ALLOW_THREADS;
7653 err = self->db_env->rep_set_priority(self->db_env, priority);
7654 MYDB_END_ALLOW_THREADS;
7655 RETURN_IF_ERR();
7656 RETURN_NONE();
7657}
7658
7659static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007660DBEnv_rep_get_priority(DBEnvObject* self)
Jesus Ceaef9764f2008-05-13 18:45:46 +00007661{
7662 int err;
Jesus Ceaca3939c2008-05-22 15:27:38 +00007663#if (DBVER >= 47)
7664 u_int32_t priority;
7665#else
Jesus Ceaef9764f2008-05-13 18:45:46 +00007666 int priority;
Jesus Ceaca3939c2008-05-22 15:27:38 +00007667#endif
Jesus Ceaef9764f2008-05-13 18:45:46 +00007668
Jesus Ceaef9764f2008-05-13 18:45:46 +00007669 CHECK_ENV_NOT_CLOSED(self);
7670 MYDB_BEGIN_ALLOW_THREADS;
7671 err = self->db_env->rep_get_priority(self->db_env, &priority);
7672 MYDB_END_ALLOW_THREADS;
7673 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007674 return NUMBER_FromLong(priority);
Jesus Ceaef9764f2008-05-13 18:45:46 +00007675}
7676
7677static PyObject*
7678DBEnv_rep_set_timeout(DBEnvObject* self, PyObject* args)
7679{
7680 int err;
7681 int which, timeout;
7682
7683 if (!PyArg_ParseTuple(args, "ii:rep_set_timeout", &which, &timeout)) {
7684 return NULL;
7685 }
7686 CHECK_ENV_NOT_CLOSED(self);
7687 MYDB_BEGIN_ALLOW_THREADS;
7688 err = self->db_env->rep_set_timeout(self->db_env, which, timeout);
7689 MYDB_END_ALLOW_THREADS;
7690 RETURN_IF_ERR();
7691 RETURN_NONE();
7692}
7693
7694static PyObject*
7695DBEnv_rep_get_timeout(DBEnvObject* self, PyObject* args)
7696{
7697 int err;
7698 int which;
7699 u_int32_t timeout;
7700
7701 if (!PyArg_ParseTuple(args, "i:rep_get_timeout", &which)) {
7702 return NULL;
7703 }
7704 CHECK_ENV_NOT_CLOSED(self);
7705 MYDB_BEGIN_ALLOW_THREADS;
7706 err = self->db_env->rep_get_timeout(self->db_env, which, &timeout);
7707 MYDB_END_ALLOW_THREADS;
7708 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007709 return NUMBER_FromLong(timeout);
Jesus Ceaef9764f2008-05-13 18:45:46 +00007710}
7711#endif
7712
Jesus Cea6557aac2010-03-22 14:22:26 +00007713
7714#if (DBVER >= 47)
7715static PyObject*
7716DBEnv_rep_set_clockskew(DBEnvObject* self, PyObject* args)
7717{
7718 int err;
7719 unsigned int fast, slow;
7720
Jesus Cea6557aac2010-03-22 14:22:26 +00007721 if (!PyArg_ParseTuple(args,"II:rep_set_clockskew", &fast, &slow))
7722 return NULL;
Jesus Cea6557aac2010-03-22 14:22:26 +00007723
7724 CHECK_ENV_NOT_CLOSED(self);
7725
7726 MYDB_BEGIN_ALLOW_THREADS;
7727 err = self->db_env->rep_set_clockskew(self->db_env, fast, slow);
7728 MYDB_END_ALLOW_THREADS;
7729 RETURN_IF_ERR();
7730 RETURN_NONE();
7731}
7732
7733static PyObject*
7734DBEnv_rep_get_clockskew(DBEnvObject* self)
7735{
7736 int err;
7737 unsigned int fast, slow;
7738
7739 CHECK_ENV_NOT_CLOSED(self);
7740 MYDB_BEGIN_ALLOW_THREADS;
7741 err = self->db_env->rep_get_clockskew(self->db_env, &fast, &slow);
7742 MYDB_END_ALLOW_THREADS;
7743 RETURN_IF_ERR();
Jesus Cea6557aac2010-03-22 14:22:26 +00007744 return Py_BuildValue("(II)", fast, slow);
Jesus Cea6557aac2010-03-22 14:22:26 +00007745}
7746#endif
7747
Jesus Cea6557aac2010-03-22 14:22:26 +00007748static PyObject*
7749DBEnv_rep_stat_print(DBEnvObject* self, PyObject* args, PyObject *kwargs)
7750{
7751 int err;
7752 int flags=0;
7753 static char* kwnames[] = { "flags", NULL };
7754
7755 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:rep_stat_print",
7756 kwnames, &flags))
7757 {
7758 return NULL;
7759 }
7760 CHECK_ENV_NOT_CLOSED(self);
7761 MYDB_BEGIN_ALLOW_THREADS;
7762 err = self->db_env->rep_stat_print(self->db_env, flags);
7763 MYDB_END_ALLOW_THREADS;
7764 RETURN_IF_ERR();
7765 RETURN_NONE();
7766}
Jesus Cea6557aac2010-03-22 14:22:26 +00007767
7768static PyObject*
7769DBEnv_rep_stat(DBEnvObject* self, PyObject* args, PyObject *kwargs)
7770{
7771 int err;
7772 int flags=0;
7773 DB_REP_STAT *statp;
7774 PyObject *stats;
7775 static char* kwnames[] = { "flags", NULL };
7776
7777 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:rep_stat",
7778 kwnames, &flags))
7779 {
7780 return NULL;
7781 }
7782 CHECK_ENV_NOT_CLOSED(self);
7783 MYDB_BEGIN_ALLOW_THREADS;
7784 err = self->db_env->rep_stat(self->db_env, &statp, flags);
7785 MYDB_END_ALLOW_THREADS;
7786 RETURN_IF_ERR();
7787
7788 stats=PyDict_New();
7789 if (stats == NULL) {
7790 free(statp);
7791 return NULL;
7792 }
7793
7794#define MAKE_ENTRY(name) _addIntToDict(stats, #name, statp->st_##name)
7795#define MAKE_DB_LSN_ENTRY(name) _addDB_lsnToDict(stats , #name, statp->st_##name)
7796
7797#if (DBVER >= 44)
7798 MAKE_ENTRY(bulk_fills);
7799 MAKE_ENTRY(bulk_overflows);
7800 MAKE_ENTRY(bulk_records);
7801 MAKE_ENTRY(bulk_transfers);
7802 MAKE_ENTRY(client_rerequests);
7803 MAKE_ENTRY(client_svc_miss);
7804 MAKE_ENTRY(client_svc_req);
7805#endif
7806 MAKE_ENTRY(dupmasters);
Jesus Cea6557aac2010-03-22 14:22:26 +00007807 MAKE_ENTRY(egen);
7808 MAKE_ENTRY(election_nvotes);
7809 MAKE_ENTRY(startup_complete);
7810 MAKE_ENTRY(pg_duplicated);
7811 MAKE_ENTRY(pg_records);
7812 MAKE_ENTRY(pg_requested);
7813 MAKE_ENTRY(next_pg);
7814 MAKE_ENTRY(waiting_pg);
Jesus Cea6557aac2010-03-22 14:22:26 +00007815 MAKE_ENTRY(election_cur_winner);
7816 MAKE_ENTRY(election_gen);
7817 MAKE_DB_LSN_ENTRY(election_lsn);
7818 MAKE_ENTRY(election_nsites);
7819 MAKE_ENTRY(election_priority);
7820#if (DBVER >= 44)
7821 MAKE_ENTRY(election_sec);
7822 MAKE_ENTRY(election_usec);
7823#endif
7824 MAKE_ENTRY(election_status);
7825 MAKE_ENTRY(election_tiebreaker);
7826 MAKE_ENTRY(election_votes);
7827 MAKE_ENTRY(elections);
7828 MAKE_ENTRY(elections_won);
7829 MAKE_ENTRY(env_id);
7830 MAKE_ENTRY(env_priority);
7831 MAKE_ENTRY(gen);
7832 MAKE_ENTRY(log_duplicated);
7833 MAKE_ENTRY(log_queued);
7834 MAKE_ENTRY(log_queued_max);
7835 MAKE_ENTRY(log_queued_total);
7836 MAKE_ENTRY(log_records);
7837 MAKE_ENTRY(log_requested);
7838 MAKE_ENTRY(master);
7839 MAKE_ENTRY(master_changes);
7840#if (DBVER >= 47)
7841 MAKE_ENTRY(max_lease_sec);
7842 MAKE_ENTRY(max_lease_usec);
7843 MAKE_DB_LSN_ENTRY(max_perm_lsn);
7844#endif
7845 MAKE_ENTRY(msgs_badgen);
7846 MAKE_ENTRY(msgs_processed);
7847 MAKE_ENTRY(msgs_recover);
7848 MAKE_ENTRY(msgs_send_failures);
7849 MAKE_ENTRY(msgs_sent);
7850 MAKE_ENTRY(newsites);
7851 MAKE_DB_LSN_ENTRY(next_lsn);
7852 MAKE_ENTRY(nsites);
7853 MAKE_ENTRY(nthrottles);
7854 MAKE_ENTRY(outdated);
7855#if (DBVER >= 46)
7856 MAKE_ENTRY(startsync_delayed);
7857#endif
7858 MAKE_ENTRY(status);
7859 MAKE_ENTRY(txns_applied);
7860 MAKE_DB_LSN_ENTRY(waiting_lsn);
7861
7862#undef MAKE_DB_LSN_ENTRY
7863#undef MAKE_ENTRY
7864
7865 free(statp);
7866 return stats;
7867}
7868
Jesus Ceaef9764f2008-05-13 18:45:46 +00007869/* --------------------------------------------------------------------- */
7870/* REPLICATION METHODS: Replication Manager */
7871
7872#if (DBVER >= 45)
7873static PyObject*
7874DBEnv_repmgr_start(DBEnvObject* self, PyObject* args, PyObject*
7875 kwargs)
7876{
7877 int err;
7878 int nthreads, flags;
7879 static char* kwnames[] = {"nthreads","flags", NULL};
7880
7881 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
7882 "ii:repmgr_start", kwnames, &nthreads, &flags))
7883 {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00007884 return NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00007885 }
7886 CHECK_ENV_NOT_CLOSED(self);
7887 MYDB_BEGIN_ALLOW_THREADS;
7888 err = self->db_env->repmgr_start(self->db_env, nthreads, flags);
7889 MYDB_END_ALLOW_THREADS;
7890 RETURN_IF_ERR();
7891 RETURN_NONE();
7892}
7893
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07007894#if (DBVER < 52)
Jesus Ceaef9764f2008-05-13 18:45:46 +00007895static PyObject*
7896DBEnv_repmgr_set_local_site(DBEnvObject* self, PyObject* args, PyObject*
7897 kwargs)
7898{
7899 int err;
7900 char *host;
7901 int port;
7902 int flags = 0;
7903 static char* kwnames[] = {"host", "port", "flags", NULL};
7904
7905 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
7906 "si|i:repmgr_set_local_site", kwnames, &host, &port, &flags))
7907 {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00007908 return NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00007909 }
7910 CHECK_ENV_NOT_CLOSED(self);
7911 MYDB_BEGIN_ALLOW_THREADS;
7912 err = self->db_env->repmgr_set_local_site(self->db_env, host, port, flags);
7913 MYDB_END_ALLOW_THREADS;
7914 RETURN_IF_ERR();
7915 RETURN_NONE();
7916}
7917
7918static PyObject*
7919DBEnv_repmgr_add_remote_site(DBEnvObject* self, PyObject* args, PyObject*
7920 kwargs)
7921{
7922 int err;
7923 char *host;
7924 int port;
7925 int flags = 0;
7926 int eidp;
7927 static char* kwnames[] = {"host", "port", "flags", NULL};
7928
7929 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
7930 "si|i:repmgr_add_remote_site", kwnames, &host, &port, &flags))
7931 {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00007932 return NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00007933 }
7934 CHECK_ENV_NOT_CLOSED(self);
7935 MYDB_BEGIN_ALLOW_THREADS;
7936 err = self->db_env->repmgr_add_remote_site(self->db_env, host, port, &eidp, flags);
7937 MYDB_END_ALLOW_THREADS;
7938 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007939 return NUMBER_FromLong(eidp);
Jesus Ceaef9764f2008-05-13 18:45:46 +00007940}
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07007941#endif
Jesus Ceaef9764f2008-05-13 18:45:46 +00007942
7943static PyObject*
7944DBEnv_repmgr_set_ack_policy(DBEnvObject* self, PyObject* args)
7945{
7946 int err;
7947 int ack_policy;
7948
7949 if (!PyArg_ParseTuple(args, "i:repmgr_set_ack_policy", &ack_policy))
7950 {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00007951 return NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00007952 }
7953 CHECK_ENV_NOT_CLOSED(self);
7954 MYDB_BEGIN_ALLOW_THREADS;
7955 err = self->db_env->repmgr_set_ack_policy(self->db_env, ack_policy);
7956 MYDB_END_ALLOW_THREADS;
7957 RETURN_IF_ERR();
7958 RETURN_NONE();
7959}
7960
7961static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007962DBEnv_repmgr_get_ack_policy(DBEnvObject* self)
Jesus Ceaef9764f2008-05-13 18:45:46 +00007963{
7964 int err;
7965 int ack_policy;
7966
Jesus Ceaef9764f2008-05-13 18:45:46 +00007967 CHECK_ENV_NOT_CLOSED(self);
7968 MYDB_BEGIN_ALLOW_THREADS;
7969 err = self->db_env->repmgr_get_ack_policy(self->db_env, &ack_policy);
7970 MYDB_END_ALLOW_THREADS;
7971 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007972 return NUMBER_FromLong(ack_policy);
Jesus Ceaef9764f2008-05-13 18:45:46 +00007973}
7974
7975static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007976DBEnv_repmgr_site_list(DBEnvObject* self)
Jesus Ceaef9764f2008-05-13 18:45:46 +00007977{
7978 int err;
7979 unsigned int countp;
7980 DB_REPMGR_SITE *listp;
7981 PyObject *stats, *key, *tuple;
7982
Jesus Ceaef9764f2008-05-13 18:45:46 +00007983 CHECK_ENV_NOT_CLOSED(self);
7984 MYDB_BEGIN_ALLOW_THREADS;
7985 err = self->db_env->repmgr_site_list(self->db_env, &countp, &listp);
7986 MYDB_END_ALLOW_THREADS;
7987 RETURN_IF_ERR();
7988
7989 stats=PyDict_New();
7990 if (stats == NULL) {
7991 free(listp);
7992 return NULL;
7993 }
7994
7995 for(;countp--;) {
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007996 key=NUMBER_FromLong(listp[countp].eid);
Jesus Ceaef9764f2008-05-13 18:45:46 +00007997 if(!key) {
7998 Py_DECREF(stats);
7999 free(listp);
8000 return NULL;
8001 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00008002 tuple=Py_BuildValue("(sII)", listp[countp].host,
8003 listp[countp].port, listp[countp].status);
Jesus Ceaef9764f2008-05-13 18:45:46 +00008004 if(!tuple) {
8005 Py_DECREF(key);
8006 Py_DECREF(stats);
8007 free(listp);
8008 return NULL;
8009 }
8010 if(PyDict_SetItem(stats, key, tuple)) {
8011 Py_DECREF(key);
8012 Py_DECREF(tuple);
8013 Py_DECREF(stats);
8014 free(listp);
8015 return NULL;
8016 }
Florent Xiclunae7901c52010-03-01 20:45:01 +00008017 Py_DECREF(key);
8018 Py_DECREF(tuple);
Jesus Ceaef9764f2008-05-13 18:45:46 +00008019 }
8020 free(listp);
8021 return stats;
8022}
8023#endif
8024
8025#if (DBVER >= 46)
8026static PyObject*
8027DBEnv_repmgr_stat_print(DBEnvObject* self, PyObject* args, PyObject *kwargs)
8028{
8029 int err;
8030 int flags=0;
8031 static char* kwnames[] = { "flags", NULL };
8032
8033 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:repmgr_stat_print",
8034 kwnames, &flags))
8035 {
8036 return NULL;
8037 }
8038 CHECK_ENV_NOT_CLOSED(self);
8039 MYDB_BEGIN_ALLOW_THREADS;
8040 err = self->db_env->repmgr_stat_print(self->db_env, flags);
8041 MYDB_END_ALLOW_THREADS;
8042 RETURN_IF_ERR();
8043 RETURN_NONE();
8044}
8045
8046static PyObject*
8047DBEnv_repmgr_stat(DBEnvObject* self, PyObject* args, PyObject *kwargs)
8048{
8049 int err;
8050 int flags=0;
8051 DB_REPMGR_STAT *statp;
8052 PyObject *stats;
8053 static char* kwnames[] = { "flags", NULL };
8054
8055 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:repmgr_stat",
8056 kwnames, &flags))
8057 {
8058 return NULL;
8059 }
8060 CHECK_ENV_NOT_CLOSED(self);
8061 MYDB_BEGIN_ALLOW_THREADS;
8062 err = self->db_env->repmgr_stat(self->db_env, &statp, flags);
8063 MYDB_END_ALLOW_THREADS;
8064 RETURN_IF_ERR();
8065
8066 stats=PyDict_New();
8067 if (stats == NULL) {
8068 free(statp);
8069 return NULL;
8070 }
8071
8072#define MAKE_ENTRY(name) _addIntToDict(stats, #name, statp->st_##name)
8073
8074 MAKE_ENTRY(perm_failed);
8075 MAKE_ENTRY(msgs_queued);
8076 MAKE_ENTRY(msgs_dropped);
8077 MAKE_ENTRY(connection_drop);
8078 MAKE_ENTRY(connect_fail);
8079
8080#undef MAKE_ENTRY
8081
8082 free(statp);
8083 return stats;
8084}
8085#endif
8086
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008087
8088/* --------------------------------------------------------------------- */
8089/* DBTxn methods */
8090
8091
Jesus Ceaef9764f2008-05-13 18:45:46 +00008092static void _close_transaction_cursors(DBTxnObject* txn)
8093{
8094 PyObject *dummy;
8095
8096 while(txn->children_cursors) {
8097 PyErr_Warn(PyExc_RuntimeWarning,
8098 "Must close cursors before resolving a transaction.");
8099 dummy=DBC_close_internal(txn->children_cursors);
8100 Py_XDECREF(dummy);
8101 }
8102}
8103
8104static void _promote_transaction_dbs_and_sequences(DBTxnObject *txn)
8105{
8106 DBObject *db;
Jesus Ceaef9764f2008-05-13 18:45:46 +00008107 DBSequenceObject *dbs;
Jesus Ceaef9764f2008-05-13 18:45:46 +00008108
8109 while (txn->children_dbs) {
8110 db=txn->children_dbs;
8111 EXTRACT_FROM_DOUBLE_LINKED_LIST_TXN(db);
8112 if (txn->parent_txn) {
8113 INSERT_IN_DOUBLE_LINKED_LIST_TXN(txn->parent_txn->children_dbs,db);
8114 db->txn=txn->parent_txn;
8115 } else {
8116 /* The db is already linked to its environment,
8117 ** so nothing to do.
8118 */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00008119 db->txn=NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00008120 }
8121 }
8122
Jesus Ceaef9764f2008-05-13 18:45:46 +00008123 while (txn->children_sequences) {
8124 dbs=txn->children_sequences;
8125 EXTRACT_FROM_DOUBLE_LINKED_LIST_TXN(dbs);
8126 if (txn->parent_txn) {
8127 INSERT_IN_DOUBLE_LINKED_LIST_TXN(txn->parent_txn->children_sequences,dbs);
8128 dbs->txn=txn->parent_txn;
8129 } else {
8130 /* The sequence is already linked to its
8131 ** parent db. Nothing to do.
8132 */
8133 dbs->txn=NULL;
8134 }
8135 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00008136}
8137
8138
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008139static PyObject*
8140DBTxn_commit(DBTxnObject* self, PyObject* args)
8141{
8142 int flags=0, err;
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008143 DB_TXN *txn;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008144
8145 if (!PyArg_ParseTuple(args, "|i:commit", &flags))
8146 return NULL;
8147
Jesus Ceaef9764f2008-05-13 18:45:46 +00008148 _close_transaction_cursors(self);
8149
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008150 if (!self->txn) {
Thomas Woutersb3153832006-03-08 01:47:19 +00008151 PyObject *t = Py_BuildValue("(is)", 0, "DBTxn must not be used "
Jesus Ceaef9764f2008-05-13 18:45:46 +00008152 "after txn_commit, txn_abort "
8153 "or txn_discard");
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008154 if (t) {
8155 PyErr_SetObject(DBError, t);
8156 Py_DECREF(t);
8157 }
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008158 return NULL;
8159 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00008160 self->flag_prepare=0;
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008161 txn = self->txn;
8162 self->txn = NULL; /* this DB_TXN is no longer valid after this call */
Jesus Ceaef9764f2008-05-13 18:45:46 +00008163
8164 EXTRACT_FROM_DOUBLE_LINKED_LIST(self);
8165
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008166 MYDB_BEGIN_ALLOW_THREADS;
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008167 err = txn->commit(txn, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008168 MYDB_END_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00008169
8170 _promote_transaction_dbs_and_sequences(self);
8171
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008172 RETURN_IF_ERR();
8173 RETURN_NONE();
8174}
8175
8176static PyObject*
8177DBTxn_prepare(DBTxnObject* self, PyObject* args)
8178{
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008179 int err;
8180 char* gid=NULL;
8181 int gid_size=0;
8182
8183 if (!PyArg_ParseTuple(args, "s#:prepare", &gid, &gid_size))
8184 return NULL;
8185
Matthias Klose54cc5392010-03-15 12:46:18 +00008186 if (gid_size != DB_GID_SIZE) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008187 PyErr_SetString(PyExc_TypeError,
Matthias Klose54cc5392010-03-15 12:46:18 +00008188 "gid must be DB_GID_SIZE bytes long");
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008189 return NULL;
8190 }
8191
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008192 if (!self->txn) {
Thomas Woutersb3153832006-03-08 01:47:19 +00008193 PyObject *t = Py_BuildValue("(is)", 0,"DBTxn must not be used "
Jesus Ceaef9764f2008-05-13 18:45:46 +00008194 "after txn_commit, txn_abort "
8195 "or txn_discard");
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008196 if (t) {
8197 PyErr_SetObject(DBError, t);
8198 Py_DECREF(t);
8199 }
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008200 return NULL;
8201 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00008202 self->flag_prepare=1; /* Prepare state */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008203 MYDB_BEGIN_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008204 err = self->txn->prepare(self->txn, (u_int8_t*)gid);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008205 MYDB_END_ALLOW_THREADS;
8206 RETURN_IF_ERR();
8207 RETURN_NONE();
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008208}
8209
8210
8211static PyObject*
Jesus Ceaef9764f2008-05-13 18:45:46 +00008212DBTxn_abort_discard_internal(DBTxnObject* self, int discard)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008213{
Jesus Ceaef9764f2008-05-13 18:45:46 +00008214 PyObject *dummy;
8215 int err=0;
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008216 DB_TXN *txn;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008217
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008218 if (!self->txn) {
Thomas Woutersb3153832006-03-08 01:47:19 +00008219 PyObject *t = Py_BuildValue("(is)", 0, "DBTxn must not be used "
Jesus Ceaef9764f2008-05-13 18:45:46 +00008220 "after txn_commit, txn_abort "
8221 "or txn_discard");
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008222 if (t) {
8223 PyErr_SetObject(DBError, t);
8224 Py_DECREF(t);
8225 }
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008226 return NULL;
8227 }
8228 txn = self->txn;
8229 self->txn = NULL; /* this DB_TXN is no longer valid after this call */
Jesus Ceaef9764f2008-05-13 18:45:46 +00008230
8231 _close_transaction_cursors(self);
Jesus Ceaef9764f2008-05-13 18:45:46 +00008232 while (self->children_sequences) {
8233 dummy=DBSequence_close_internal(self->children_sequences,0,0);
8234 Py_XDECREF(dummy);
8235 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00008236 while (self->children_dbs) {
Jesus Cea5cd5f122008-09-23 18:54:08 +00008237 dummy=DB_close_internal(self->children_dbs, 0, 0);
Jesus Ceaef9764f2008-05-13 18:45:46 +00008238 Py_XDECREF(dummy);
8239 }
8240
8241 EXTRACT_FROM_DOUBLE_LINKED_LIST(self);
8242
8243 MYDB_BEGIN_ALLOW_THREADS;
8244 if (discard) {
8245 assert(!self->flag_prepare);
Jesus Ceaef9764f2008-05-13 18:45:46 +00008246 err = txn->discard(txn,0);
Jesus Ceaef9764f2008-05-13 18:45:46 +00008247 } else {
8248 /*
8249 ** If the transaction is in the "prepare" or "recover" state,
8250 ** we better do not implicitly abort it.
8251 */
8252 if (!self->flag_prepare) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00008253 err = txn->abort(txn);
Jesus Ceaef9764f2008-05-13 18:45:46 +00008254 }
8255 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008256 MYDB_END_ALLOW_THREADS;
8257 RETURN_IF_ERR();
8258 RETURN_NONE();
8259}
8260
Jesus Ceaef9764f2008-05-13 18:45:46 +00008261static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008262DBTxn_abort(DBTxnObject* self)
Jesus Ceaef9764f2008-05-13 18:45:46 +00008263{
Jesus Ceaef9764f2008-05-13 18:45:46 +00008264 self->flag_prepare=0;
8265 _close_transaction_cursors(self);
8266
8267 return DBTxn_abort_discard_internal(self,0);
8268}
8269
8270static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008271DBTxn_discard(DBTxnObject* self)
Jesus Ceaef9764f2008-05-13 18:45:46 +00008272{
Jesus Ceaef9764f2008-05-13 18:45:46 +00008273 self->flag_prepare=0;
8274 _close_transaction_cursors(self);
8275
8276 return DBTxn_abort_discard_internal(self,1);
8277}
8278
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008279
8280static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008281DBTxn_id(DBTxnObject* self)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008282{
8283 int id;
8284
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008285 if (!self->txn) {
Thomas Woutersb3153832006-03-08 01:47:19 +00008286 PyObject *t = Py_BuildValue("(is)", 0, "DBTxn must not be used "
Jesus Ceaef9764f2008-05-13 18:45:46 +00008287 "after txn_commit, txn_abort "
8288 "or txn_discard");
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008289 if (t) {
8290 PyErr_SetObject(DBError, t);
8291 Py_DECREF(t);
8292 }
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008293 return NULL;
8294 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008295 MYDB_BEGIN_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008296 id = self->txn->id(self->txn);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008297 MYDB_END_ALLOW_THREADS;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008298 return NUMBER_FromLong(id);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008299}
8300
Jesus Cea6557aac2010-03-22 14:22:26 +00008301
8302static PyObject*
8303DBTxn_set_timeout(DBTxnObject* self, PyObject* args, PyObject* kwargs)
8304{
8305 int err;
8306 u_int32_t flags=0;
8307 u_int32_t timeout = 0;
8308 static char* kwnames[] = { "timeout", "flags", NULL };
8309
8310 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ii:set_timeout", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00008311 &timeout, &flags)) {
8312 return NULL;
Jesus Cea6557aac2010-03-22 14:22:26 +00008313 }
8314
8315 MYDB_BEGIN_ALLOW_THREADS;
8316 err = self->txn->set_timeout(self->txn, (db_timeout_t)timeout, flags);
8317 MYDB_END_ALLOW_THREADS;
8318
8319 RETURN_IF_ERR();
8320 RETURN_NONE();
8321}
8322
8323
8324#if (DBVER >= 44)
8325static PyObject*
8326DBTxn_set_name(DBTxnObject* self, PyObject* args)
8327{
8328 int err;
8329 const char *name;
8330
8331 if (!PyArg_ParseTuple(args, "s:set_name", &name))
8332 return NULL;
8333
8334 MYDB_BEGIN_ALLOW_THREADS;
8335 err = self->txn->set_name(self->txn, name);
8336 MYDB_END_ALLOW_THREADS;
8337
8338 RETURN_IF_ERR();
8339 RETURN_NONE();
8340}
8341#endif
8342
8343
8344#if (DBVER >= 44)
8345static PyObject*
8346DBTxn_get_name(DBTxnObject* self)
8347{
8348 int err;
8349 const char *name;
8350
8351 MYDB_BEGIN_ALLOW_THREADS;
8352 err = self->txn->get_name(self->txn, &name);
8353 MYDB_END_ALLOW_THREADS;
8354
8355 RETURN_IF_ERR();
8356#if (PY_VERSION_HEX < 0x03000000)
8357 if (!name) {
8358 return PyString_FromString("");
8359 }
8360 return PyString_FromString(name);
8361#else
8362 if (!name) {
8363 return PyUnicode_FromString("");
8364 }
8365 return PyUnicode_FromString(name);
8366#endif
8367}
8368#endif
8369
8370
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008371/* --------------------------------------------------------------------- */
8372/* DBSequence methods */
8373
8374
8375static PyObject*
Jesus Ceaef9764f2008-05-13 18:45:46 +00008376DBSequence_close_internal(DBSequenceObject* self, int flags, int do_not_close)
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008377{
Jesus Ceaef9764f2008-05-13 18:45:46 +00008378 int err=0;
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008379
Jesus Ceaef9764f2008-05-13 18:45:46 +00008380 if (self->sequence!=NULL) {
8381 EXTRACT_FROM_DOUBLE_LINKED_LIST(self);
8382 if (self->txn) {
8383 EXTRACT_FROM_DOUBLE_LINKED_LIST_TXN(self);
8384 self->txn=NULL;
8385 }
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008386
Jesus Cea5cd5f122008-09-23 18:54:08 +00008387 /*
8388 ** "do_not_close" is used to dispose all related objects in the
8389 ** tree, without actually releasing the "root" object.
8390 ** This is done, for example, because function calls like
8391 ** "DBSequence.remove()" implicitly close the underlying handle. So
8392 ** the handle doesn't need to be closed, but related objects
8393 ** must be cleaned up.
8394 */
Jesus Ceaef9764f2008-05-13 18:45:46 +00008395 if (!do_not_close) {
8396 MYDB_BEGIN_ALLOW_THREADS
8397 err = self->sequence->close(self->sequence, flags);
8398 MYDB_END_ALLOW_THREADS
8399 }
8400 self->sequence = NULL;
8401
8402 RETURN_IF_ERR();
8403 }
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008404
8405 RETURN_NONE();
8406}
8407
8408static PyObject*
Jesus Ceaef9764f2008-05-13 18:45:46 +00008409DBSequence_close(DBSequenceObject* self, PyObject* args)
8410{
8411 int flags=0;
8412 if (!PyArg_ParseTuple(args,"|i:close", &flags))
8413 return NULL;
8414
8415 return DBSequence_close_internal(self,flags,0);
8416}
8417
8418static PyObject*
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008419DBSequence_get(DBSequenceObject* self, PyObject* args, PyObject* kwargs)
8420{
8421 int err, flags = 0;
8422 int delta = 1;
8423 db_seq_t value;
8424 PyObject *txnobj = NULL;
8425 DB_TXN *txn = NULL;
8426 static char* kwnames[] = {"delta", "txn", "flags", NULL };
8427 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|iOi:get", kwnames, &delta, &txnobj, &flags))
8428 return NULL;
8429 CHECK_SEQUENCE_NOT_CLOSED(self)
8430
8431 if (!checkTxnObj(txnobj, &txn))
8432 return NULL;
8433
8434 MYDB_BEGIN_ALLOW_THREADS
8435 err = self->sequence->get(self->sequence, txn, delta, &value, flags);
8436 MYDB_END_ALLOW_THREADS
8437
8438 RETURN_IF_ERR();
8439 return PyLong_FromLongLong(value);
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008440}
8441
8442static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008443DBSequence_get_dbp(DBSequenceObject* self)
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008444{
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008445 CHECK_SEQUENCE_NOT_CLOSED(self)
8446 Py_INCREF(self->mydb);
8447 return (PyObject* )self->mydb;
8448}
8449
8450static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008451DBSequence_get_key(DBSequenceObject* self)
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008452{
8453 int err;
8454 DBT key;
Neal Norwitz088beae2007-10-12 03:01:54 +00008455 PyObject *retval = NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00008456
Gregory P. Smithe70be5c2007-10-06 07:48:10 +00008457 key.flags = DB_DBT_MALLOC;
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008458 CHECK_SEQUENCE_NOT_CLOSED(self)
8459 MYDB_BEGIN_ALLOW_THREADS
8460 err = self->sequence->get_key(self->sequence, &key);
8461 MYDB_END_ALLOW_THREADS
8462
Gregory P. Smithe70be5c2007-10-06 07:48:10 +00008463 if (!err)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008464 retval = Build_PyString(key.data, key.size);
Gregory P. Smithe70be5c2007-10-06 07:48:10 +00008465
8466 FREE_DBT(key);
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008467 RETURN_IF_ERR();
8468
Gregory P. Smithe70be5c2007-10-06 07:48:10 +00008469 return retval;
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008470}
8471
8472static PyObject*
Jesus Cea6557aac2010-03-22 14:22:26 +00008473DBSequence_initial_value(DBSequenceObject* self, PyObject* args)
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008474{
8475 int err;
Jesus Ceaef9764f2008-05-13 18:45:46 +00008476 PY_LONG_LONG value;
8477 db_seq_t value2;
Jesus Cea6557aac2010-03-22 14:22:26 +00008478 if (!PyArg_ParseTuple(args,"L:initial_value", &value))
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008479 return NULL;
8480 CHECK_SEQUENCE_NOT_CLOSED(self)
8481
Jesus Ceaef9764f2008-05-13 18:45:46 +00008482 value2=value; /* If truncation, compiler should show a warning */
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008483 MYDB_BEGIN_ALLOW_THREADS
Jesus Ceaef9764f2008-05-13 18:45:46 +00008484 err = self->sequence->initial_value(self->sequence, value2);
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008485 MYDB_END_ALLOW_THREADS
8486
8487 RETURN_IF_ERR();
8488
8489 RETURN_NONE();
8490}
8491
8492static PyObject*
8493DBSequence_open(DBSequenceObject* self, PyObject* args, PyObject* kwargs)
8494{
8495 int err, flags = 0;
8496 PyObject* keyobj;
8497 PyObject *txnobj = NULL;
8498 DB_TXN *txn = NULL;
8499 DBT key;
8500
8501 static char* kwnames[] = {"key", "txn", "flags", NULL };
Neal Norwitzdd2a6bf2006-06-06 07:23:01 +00008502 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|Oi:open", kwnames, &keyobj, &txnobj, &flags))
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008503 return NULL;
8504
8505 if (!checkTxnObj(txnobj, &txn))
8506 return NULL;
8507
8508 if (!make_key_dbt(self->mydb, keyobj, &key, NULL))
8509 return NULL;
8510
8511 MYDB_BEGIN_ALLOW_THREADS
8512 err = self->sequence->open(self->sequence, txn, &key, flags);
8513 MYDB_END_ALLOW_THREADS
8514
Jesus Ceaac25fab2008-09-03 17:50:32 +00008515 FREE_DBT(key);
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008516 RETURN_IF_ERR();
8517
Jesus Ceaef9764f2008-05-13 18:45:46 +00008518 if (txn) {
8519 INSERT_IN_DOUBLE_LINKED_LIST_TXN(((DBTxnObject *)txnobj)->children_sequences,self);
8520 self->txn=(DBTxnObject *)txnobj;
8521 }
8522
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008523 RETURN_NONE();
8524}
8525
8526static PyObject*
8527DBSequence_remove(DBSequenceObject* self, PyObject* args, PyObject* kwargs)
8528{
Jesus Ceaef9764f2008-05-13 18:45:46 +00008529 PyObject *dummy;
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008530 int err, flags = 0;
8531 PyObject *txnobj = NULL;
8532 DB_TXN *txn = NULL;
8533
8534 static char* kwnames[] = {"txn", "flags", NULL };
Neal Norwitzdd2a6bf2006-06-06 07:23:01 +00008535 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Oi:remove", kwnames, &txnobj, &flags))
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008536 return NULL;
8537
8538 if (!checkTxnObj(txnobj, &txn))
8539 return NULL;
8540
8541 CHECK_SEQUENCE_NOT_CLOSED(self)
8542
8543 MYDB_BEGIN_ALLOW_THREADS
8544 err = self->sequence->remove(self->sequence, txn, flags);
8545 MYDB_END_ALLOW_THREADS
8546
Jesus Ceaef9764f2008-05-13 18:45:46 +00008547 dummy=DBSequence_close_internal(self,flags,1);
8548 Py_XDECREF(dummy);
8549
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008550 RETURN_IF_ERR();
8551 RETURN_NONE();
8552}
8553
8554static PyObject*
8555DBSequence_set_cachesize(DBSequenceObject* self, PyObject* args)
8556{
8557 int err, size;
Neal Norwitzdd2a6bf2006-06-06 07:23:01 +00008558 if (!PyArg_ParseTuple(args,"i:set_cachesize", &size))
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008559 return NULL;
8560 CHECK_SEQUENCE_NOT_CLOSED(self)
8561
8562 MYDB_BEGIN_ALLOW_THREADS
8563 err = self->sequence->set_cachesize(self->sequence, size);
8564 MYDB_END_ALLOW_THREADS
8565
8566 RETURN_IF_ERR();
8567 RETURN_NONE();
8568}
8569
8570static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008571DBSequence_get_cachesize(DBSequenceObject* self)
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008572{
8573 int err, size;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008574
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008575 CHECK_SEQUENCE_NOT_CLOSED(self)
8576
8577 MYDB_BEGIN_ALLOW_THREADS
8578 err = self->sequence->get_cachesize(self->sequence, &size);
8579 MYDB_END_ALLOW_THREADS
8580
8581 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008582 return NUMBER_FromLong(size);
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008583}
8584
8585static PyObject*
8586DBSequence_set_flags(DBSequenceObject* self, PyObject* args)
8587{
8588 int err, flags = 0;
Neal Norwitzdd2a6bf2006-06-06 07:23:01 +00008589 if (!PyArg_ParseTuple(args,"i:set_flags", &flags))
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008590 return NULL;
8591 CHECK_SEQUENCE_NOT_CLOSED(self)
8592
8593 MYDB_BEGIN_ALLOW_THREADS
8594 err = self->sequence->set_flags(self->sequence, flags);
8595 MYDB_END_ALLOW_THREADS
8596
8597 RETURN_IF_ERR();
8598 RETURN_NONE();
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008599}
8600
8601static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008602DBSequence_get_flags(DBSequenceObject* self)
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008603{
8604 unsigned int flags;
8605 int err;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008606
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008607 CHECK_SEQUENCE_NOT_CLOSED(self)
8608
8609 MYDB_BEGIN_ALLOW_THREADS
8610 err = self->sequence->get_flags(self->sequence, &flags);
8611 MYDB_END_ALLOW_THREADS
8612
8613 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008614 return NUMBER_FromLong((int)flags);
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008615}
8616
8617static PyObject*
8618DBSequence_set_range(DBSequenceObject* self, PyObject* args)
8619{
8620 int err;
Jesus Ceaef9764f2008-05-13 18:45:46 +00008621 PY_LONG_LONG min, max;
8622 db_seq_t min2, max2;
Tim Petersbb21b2c2006-06-06 15:50:17 +00008623 if (!PyArg_ParseTuple(args,"(LL):set_range", &min, &max))
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008624 return NULL;
8625 CHECK_SEQUENCE_NOT_CLOSED(self)
8626
Jesus Ceaef9764f2008-05-13 18:45:46 +00008627 min2=min; /* If truncation, compiler should show a warning */
8628 max2=max;
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008629 MYDB_BEGIN_ALLOW_THREADS
Jesus Ceaef9764f2008-05-13 18:45:46 +00008630 err = self->sequence->set_range(self->sequence, min2, max2);
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008631 MYDB_END_ALLOW_THREADS
8632
8633 RETURN_IF_ERR();
8634 RETURN_NONE();
8635}
8636
8637static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008638DBSequence_get_range(DBSequenceObject* self)
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008639{
8640 int err;
Jesus Ceaef9764f2008-05-13 18:45:46 +00008641 PY_LONG_LONG min, max;
8642 db_seq_t min2, max2;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008643
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008644 CHECK_SEQUENCE_NOT_CLOSED(self)
8645
8646 MYDB_BEGIN_ALLOW_THREADS
Jesus Ceaef9764f2008-05-13 18:45:46 +00008647 err = self->sequence->get_range(self->sequence, &min2, &max2);
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008648 MYDB_END_ALLOW_THREADS
8649
8650 RETURN_IF_ERR();
Jesus Ceaef9764f2008-05-13 18:45:46 +00008651 min=min2; /* If truncation, compiler should show a warning */
8652 max=max2;
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008653 return Py_BuildValue("(LL)", min, max);
8654}
8655
Jesus Cea6557aac2010-03-22 14:22:26 +00008656
8657static PyObject*
8658DBSequence_stat_print(DBSequenceObject* self, PyObject* args, PyObject *kwargs)
8659{
8660 int err;
8661 int flags=0;
8662 static char* kwnames[] = { "flags", NULL };
8663
8664 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:stat_print",
8665 kwnames, &flags))
8666 {
8667 return NULL;
8668 }
8669
8670 CHECK_SEQUENCE_NOT_CLOSED(self);
8671
8672 MYDB_BEGIN_ALLOW_THREADS;
8673 err = self->sequence->stat_print(self->sequence, flags);
8674 MYDB_END_ALLOW_THREADS;
8675 RETURN_IF_ERR();
8676 RETURN_NONE();
8677}
8678
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008679static PyObject*
8680DBSequence_stat(DBSequenceObject* self, PyObject* args, PyObject* kwargs)
8681{
8682 int err, flags = 0;
8683 DB_SEQUENCE_STAT* sp = NULL;
8684 PyObject* dict_stat;
8685 static char* kwnames[] = {"flags", NULL };
8686 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:stat", kwnames, &flags))
8687 return NULL;
8688 CHECK_SEQUENCE_NOT_CLOSED(self);
8689
8690 MYDB_BEGIN_ALLOW_THREADS;
8691 err = self->sequence->stat(self->sequence, &sp, flags);
8692 MYDB_END_ALLOW_THREADS;
8693 RETURN_IF_ERR();
8694
8695 if ((dict_stat = PyDict_New()) == NULL) {
8696 free(sp);
8697 return NULL;
8698 }
8699
8700
8701#define MAKE_INT_ENTRY(name) _addIntToDict(dict_stat, #name, sp->st_##name)
8702#define MAKE_LONG_LONG_ENTRY(name) _addDb_seq_tToDict(dict_stat, #name, sp->st_##name)
8703
8704 MAKE_INT_ENTRY(wait);
8705 MAKE_INT_ENTRY(nowait);
8706 MAKE_LONG_LONG_ENTRY(current);
8707 MAKE_LONG_LONG_ENTRY(value);
8708 MAKE_LONG_LONG_ENTRY(last_value);
8709 MAKE_LONG_LONG_ENTRY(min);
8710 MAKE_LONG_LONG_ENTRY(max);
8711 MAKE_INT_ENTRY(cache_size);
8712 MAKE_INT_ENTRY(flags);
8713
8714#undef MAKE_INT_ENTRY
8715#undef MAKE_LONG_LONG_ENTRY
8716
8717 free(sp);
8718 return dict_stat;
8719}
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008720
8721
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008722/* --------------------------------------------------------------------- */
8723/* Method definition tables and type objects */
8724
8725static PyMethodDef DB_methods[] = {
Jesus Cea4907d272008-08-31 14:00:51 +00008726 {"append", (PyCFunction)DB_append, METH_VARARGS|METH_KEYWORDS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008727 {"associate", (PyCFunction)DB_associate, METH_VARARGS|METH_KEYWORDS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008728 {"close", (PyCFunction)DB_close, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008729#if (DBVER >= 47)
8730 {"compact", (PyCFunction)DB_compact, METH_VARARGS|METH_KEYWORDS},
8731#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008732 {"consume", (PyCFunction)DB_consume, METH_VARARGS|METH_KEYWORDS},
8733 {"consume_wait", (PyCFunction)DB_consume_wait, METH_VARARGS|METH_KEYWORDS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008734 {"cursor", (PyCFunction)DB_cursor, METH_VARARGS|METH_KEYWORDS},
8735 {"delete", (PyCFunction)DB_delete, METH_VARARGS|METH_KEYWORDS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008736 {"fd", (PyCFunction)DB_fd, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008737#if (DBVER >= 46)
8738 {"exists", (PyCFunction)DB_exists,
8739 METH_VARARGS|METH_KEYWORDS},
8740#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008741 {"get", (PyCFunction)DB_get, METH_VARARGS|METH_KEYWORDS},
Gregory P. Smith19699a92004-06-28 04:06:49 +00008742 {"pget", (PyCFunction)DB_pget, METH_VARARGS|METH_KEYWORDS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008743 {"get_both", (PyCFunction)DB_get_both, METH_VARARGS|METH_KEYWORDS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008744 {"get_byteswapped", (PyCFunction)DB_get_byteswapped,METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008745 {"get_size", (PyCFunction)DB_get_size, METH_VARARGS|METH_KEYWORDS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008746 {"get_type", (PyCFunction)DB_get_type, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008747 {"join", (PyCFunction)DB_join, METH_VARARGS},
8748 {"key_range", (PyCFunction)DB_key_range, METH_VARARGS|METH_KEYWORDS},
Jesus Cea4907d272008-08-31 14:00:51 +00008749 {"has_key", (PyCFunction)DB_has_key, METH_VARARGS|METH_KEYWORDS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008750 {"items", (PyCFunction)DB_items, METH_VARARGS},
8751 {"keys", (PyCFunction)DB_keys, METH_VARARGS},
8752 {"open", (PyCFunction)DB_open, METH_VARARGS|METH_KEYWORDS},
8753 {"put", (PyCFunction)DB_put, METH_VARARGS|METH_KEYWORDS},
8754 {"remove", (PyCFunction)DB_remove, METH_VARARGS|METH_KEYWORDS},
8755 {"rename", (PyCFunction)DB_rename, METH_VARARGS},
8756 {"set_bt_minkey", (PyCFunction)DB_set_bt_minkey, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008757 {"get_bt_minkey", (PyCFunction)DB_get_bt_minkey, METH_NOARGS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008758 {"set_bt_compare", (PyCFunction)DB_set_bt_compare, METH_O},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008759 {"set_cachesize", (PyCFunction)DB_set_cachesize, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008760 {"get_cachesize", (PyCFunction)DB_get_cachesize, METH_NOARGS},
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07008761 {"set_dup_compare", (PyCFunction)DB_set_dup_compare, METH_O},
Jesus Cea6557aac2010-03-22 14:22:26 +00008762 {"set_encrypt", (PyCFunction)DB_set_encrypt, METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008763 {"get_encrypt_flags", (PyCFunction)DB_get_encrypt_flags, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008764 {"set_flags", (PyCFunction)DB_set_flags, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008765 {"get_flags", (PyCFunction)DB_get_flags, METH_NOARGS},
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07008766 {"get_transactional", (PyCFunction)DB_get_transactional, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008767 {"set_h_ffactor", (PyCFunction)DB_set_h_ffactor, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008768 {"get_h_ffactor", (PyCFunction)DB_get_h_ffactor, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008769 {"set_h_nelem", (PyCFunction)DB_set_h_nelem, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008770 {"get_h_nelem", (PyCFunction)DB_get_h_nelem, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008771 {"set_lorder", (PyCFunction)DB_set_lorder, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008772 {"get_lorder", (PyCFunction)DB_get_lorder, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008773 {"set_pagesize", (PyCFunction)DB_set_pagesize, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008774 {"get_pagesize", (PyCFunction)DB_get_pagesize, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008775 {"set_re_delim", (PyCFunction)DB_set_re_delim, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008776 {"get_re_delim", (PyCFunction)DB_get_re_delim, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008777 {"set_re_len", (PyCFunction)DB_set_re_len, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008778 {"get_re_len", (PyCFunction)DB_get_re_len, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008779 {"set_re_pad", (PyCFunction)DB_set_re_pad, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008780 {"get_re_pad", (PyCFunction)DB_get_re_pad, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008781 {"set_re_source", (PyCFunction)DB_set_re_source, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008782 {"get_re_source", (PyCFunction)DB_get_re_source, METH_NOARGS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008783 {"set_q_extentsize",(PyCFunction)DB_set_q_extentsize, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008784 {"get_q_extentsize",(PyCFunction)DB_get_q_extentsize, METH_NOARGS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008785 {"set_private", (PyCFunction)DB_set_private, METH_O},
8786 {"get_private", (PyCFunction)DB_get_private, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008787#if (DBVER >= 46)
8788 {"set_priority", (PyCFunction)DB_set_priority, METH_VARARGS},
8789 {"get_priority", (PyCFunction)DB_get_priority, METH_NOARGS},
8790#endif
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07008791 {"get_dbname", (PyCFunction)DB_get_dbname, METH_NOARGS},
8792 {"get_open_flags", (PyCFunction)DB_get_open_flags, METH_NOARGS},
Gregory P. Smith8b7e9172004-12-13 09:51:23 +00008793 {"stat", (PyCFunction)DB_stat, METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008794 {"stat_print", (PyCFunction)DB_stat_print,
8795 METH_VARARGS|METH_KEYWORDS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008796 {"sync", (PyCFunction)DB_sync, METH_VARARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008797 {"truncate", (PyCFunction)DB_truncate, METH_VARARGS|METH_KEYWORDS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008798 {"type", (PyCFunction)DB_get_type, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008799 {"upgrade", (PyCFunction)DB_upgrade, METH_VARARGS},
8800 {"values", (PyCFunction)DB_values, METH_VARARGS},
8801 {"verify", (PyCFunction)DB_verify, METH_VARARGS|METH_KEYWORDS},
8802 {"set_get_returns_none",(PyCFunction)DB_set_get_returns_none, METH_VARARGS},
8803 {NULL, NULL} /* sentinel */
8804};
8805
8806
Jesus Cea6557aac2010-03-22 14:22:26 +00008807/* We need this to support __contains__() */
8808static PySequenceMethods DB_sequence = {
8809 0, /* sq_length, mapping wins here */
8810 0, /* sq_concat */
8811 0, /* sq_repeat */
8812 0, /* sq_item */
8813 0, /* sq_slice */
8814 0, /* sq_ass_item */
8815 0, /* sq_ass_slice */
8816 (objobjproc)DB_contains, /* sq_contains */
8817 0, /* sq_inplace_concat */
8818 0, /* sq_inplace_repeat */
8819};
8820
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008821static PyMappingMethods DB_mapping = {
Martin v. Löwis70ee3cc2006-06-12 04:26:31 +00008822 DB_length, /*mp_length*/
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008823 (binaryfunc)DB_subscript, /*mp_subscript*/
8824 (objobjargproc)DB_ass_sub, /*mp_ass_subscript*/
8825};
8826
8827
8828static PyMethodDef DBCursor_methods[] = {
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008829 {"close", (PyCFunction)DBC_close, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008830 {"count", (PyCFunction)DBC_count, METH_VARARGS},
8831 {"current", (PyCFunction)DBC_current, METH_VARARGS|METH_KEYWORDS},
8832 {"delete", (PyCFunction)DBC_delete, METH_VARARGS},
8833 {"dup", (PyCFunction)DBC_dup, METH_VARARGS},
8834 {"first", (PyCFunction)DBC_first, METH_VARARGS|METH_KEYWORDS},
8835 {"get", (PyCFunction)DBC_get, METH_VARARGS|METH_KEYWORDS},
Gregory P. Smith19699a92004-06-28 04:06:49 +00008836 {"pget", (PyCFunction)DBC_pget, METH_VARARGS|METH_KEYWORDS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008837 {"get_recno", (PyCFunction)DBC_get_recno, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008838 {"last", (PyCFunction)DBC_last, METH_VARARGS|METH_KEYWORDS},
8839 {"next", (PyCFunction)DBC_next, METH_VARARGS|METH_KEYWORDS},
8840 {"prev", (PyCFunction)DBC_prev, METH_VARARGS|METH_KEYWORDS},
8841 {"put", (PyCFunction)DBC_put, METH_VARARGS|METH_KEYWORDS},
8842 {"set", (PyCFunction)DBC_set, METH_VARARGS|METH_KEYWORDS},
8843 {"set_range", (PyCFunction)DBC_set_range, METH_VARARGS|METH_KEYWORDS},
8844 {"get_both", (PyCFunction)DBC_get_both, METH_VARARGS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008845 {"get_current_size",(PyCFunction)DBC_get_current_size, METH_NOARGS},
Gregory P. Smith455d46f2003-07-09 04:45:59 +00008846 {"set_both", (PyCFunction)DBC_set_both, METH_VARARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008847 {"set_recno", (PyCFunction)DBC_set_recno, METH_VARARGS|METH_KEYWORDS},
8848 {"consume", (PyCFunction)DBC_consume, METH_VARARGS|METH_KEYWORDS},
8849 {"next_dup", (PyCFunction)DBC_next_dup, METH_VARARGS|METH_KEYWORDS},
8850 {"next_nodup", (PyCFunction)DBC_next_nodup, METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008851#if (DBVER >= 46)
8852 {"prev_dup", (PyCFunction)DBC_prev_dup,
8853 METH_VARARGS|METH_KEYWORDS},
8854#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008855 {"prev_nodup", (PyCFunction)DBC_prev_nodup, METH_VARARGS|METH_KEYWORDS},
8856 {"join_item", (PyCFunction)DBC_join_item, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008857#if (DBVER >= 46)
8858 {"set_priority", (PyCFunction)DBC_set_priority,
8859 METH_VARARGS|METH_KEYWORDS},
8860 {"get_priority", (PyCFunction)DBC_get_priority, METH_NOARGS},
8861#endif
8862 {NULL, NULL} /* sentinel */
8863};
8864
8865
8866static PyMethodDef DBLogCursor_methods[] = {
8867 {"close", (PyCFunction)DBLogCursor_close, METH_NOARGS},
8868 {"current", (PyCFunction)DBLogCursor_current, METH_NOARGS},
8869 {"first", (PyCFunction)DBLogCursor_first, METH_NOARGS},
8870 {"last", (PyCFunction)DBLogCursor_last, METH_NOARGS},
8871 {"next", (PyCFunction)DBLogCursor_next, METH_NOARGS},
8872 {"prev", (PyCFunction)DBLogCursor_prev, METH_NOARGS},
8873 {"set", (PyCFunction)DBLogCursor_set, METH_VARARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008874 {NULL, NULL} /* sentinel */
8875};
8876
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07008877#if (DBVER >= 52)
8878static PyMethodDef DBSite_methods[] = {
8879 {"get_config", (PyCFunction)DBSite_get_config,
8880 METH_VARARGS | METH_KEYWORDS},
8881 {"set_config", (PyCFunction)DBSite_set_config,
8882 METH_VARARGS | METH_KEYWORDS},
8883 {"remove", (PyCFunction)DBSite_remove, METH_NOARGS},
8884 {"get_eid", (PyCFunction)DBSite_get_eid, METH_NOARGS},
8885 {"get_address", (PyCFunction)DBSite_get_address, METH_NOARGS},
8886 {"close", (PyCFunction)DBSite_close, METH_NOARGS},
8887 {NULL, NULL} /* sentinel */
8888};
8889#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008890
8891static PyMethodDef DBEnv_methods[] = {
8892 {"close", (PyCFunction)DBEnv_close, METH_VARARGS},
8893 {"open", (PyCFunction)DBEnv_open, METH_VARARGS},
8894 {"remove", (PyCFunction)DBEnv_remove, METH_VARARGS},
Barry Warsaw9a0d7792002-12-30 20:53:52 +00008895 {"dbremove", (PyCFunction)DBEnv_dbremove, METH_VARARGS|METH_KEYWORDS},
8896 {"dbrename", (PyCFunction)DBEnv_dbrename, METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008897#if (DBVER >= 46)
8898 {"set_thread_count", (PyCFunction)DBEnv_set_thread_count, METH_VARARGS},
8899 {"get_thread_count", (PyCFunction)DBEnv_get_thread_count, METH_NOARGS},
8900#endif
Barry Warsaw9a0d7792002-12-30 20:53:52 +00008901 {"set_encrypt", (PyCFunction)DBEnv_set_encrypt, METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008902 {"get_encrypt_flags", (PyCFunction)DBEnv_get_encrypt_flags, METH_NOARGS},
8903 {"get_timeout", (PyCFunction)DBEnv_get_timeout,
8904 METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008905 {"set_timeout", (PyCFunction)DBEnv_set_timeout, METH_VARARGS|METH_KEYWORDS},
8906 {"set_shm_key", (PyCFunction)DBEnv_set_shm_key, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008907 {"get_shm_key", (PyCFunction)DBEnv_get_shm_key, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008908#if (DBVER >= 46)
8909 {"set_cache_max", (PyCFunction)DBEnv_set_cache_max, METH_VARARGS},
8910 {"get_cache_max", (PyCFunction)DBEnv_get_cache_max, METH_NOARGS},
8911#endif
8912 {"set_cachesize", (PyCFunction)DBEnv_set_cachesize, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008913 {"get_cachesize", (PyCFunction)DBEnv_get_cachesize, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008914 {"memp_trickle", (PyCFunction)DBEnv_memp_trickle, METH_VARARGS},
8915 {"memp_sync", (PyCFunction)DBEnv_memp_sync, METH_VARARGS},
8916 {"memp_stat", (PyCFunction)DBEnv_memp_stat,
8917 METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008918 {"memp_stat_print", (PyCFunction)DBEnv_memp_stat_print,
8919 METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008920#if (DBVER >= 44)
8921 {"mutex_set_max", (PyCFunction)DBEnv_mutex_set_max, METH_VARARGS},
8922 {"mutex_get_max", (PyCFunction)DBEnv_mutex_get_max, METH_NOARGS},
8923 {"mutex_set_align", (PyCFunction)DBEnv_mutex_set_align, METH_VARARGS},
8924 {"mutex_get_align", (PyCFunction)DBEnv_mutex_get_align, METH_NOARGS},
8925 {"mutex_set_increment", (PyCFunction)DBEnv_mutex_set_increment,
8926 METH_VARARGS},
8927 {"mutex_get_increment", (PyCFunction)DBEnv_mutex_get_increment,
8928 METH_NOARGS},
8929 {"mutex_set_tas_spins", (PyCFunction)DBEnv_mutex_set_tas_spins,
8930 METH_VARARGS},
8931 {"mutex_get_tas_spins", (PyCFunction)DBEnv_mutex_get_tas_spins,
8932 METH_NOARGS},
8933 {"mutex_stat", (PyCFunction)DBEnv_mutex_stat, METH_VARARGS},
8934#if (DBVER >= 44)
8935 {"mutex_stat_print", (PyCFunction)DBEnv_mutex_stat_print,
8936 METH_VARARGS|METH_KEYWORDS},
8937#endif
8938#endif
8939 {"set_data_dir", (PyCFunction)DBEnv_set_data_dir, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008940 {"get_data_dirs", (PyCFunction)DBEnv_get_data_dirs, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008941 {"get_flags", (PyCFunction)DBEnv_get_flags, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008942 {"set_flags", (PyCFunction)DBEnv_set_flags, METH_VARARGS},
8943#if (DBVER >= 47)
8944 {"log_set_config", (PyCFunction)DBEnv_log_set_config, METH_VARARGS},
8945 {"log_get_config", (PyCFunction)DBEnv_log_get_config, METH_VARARGS},
8946#endif
8947 {"set_lg_bsize", (PyCFunction)DBEnv_set_lg_bsize, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008948 {"get_lg_bsize", (PyCFunction)DBEnv_get_lg_bsize, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008949 {"set_lg_dir", (PyCFunction)DBEnv_set_lg_dir, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008950 {"get_lg_dir", (PyCFunction)DBEnv_get_lg_dir, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008951 {"set_lg_max", (PyCFunction)DBEnv_set_lg_max, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008952 {"get_lg_max", (PyCFunction)DBEnv_get_lg_max, METH_NOARGS},
Gregory P. Smithe9477062005-06-04 06:46:59 +00008953 {"set_lg_regionmax",(PyCFunction)DBEnv_set_lg_regionmax, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008954 {"get_lg_regionmax",(PyCFunction)DBEnv_get_lg_regionmax, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008955#if (DBVER >= 44)
8956 {"set_lg_filemode", (PyCFunction)DBEnv_set_lg_filemode, METH_VARARGS},
8957 {"get_lg_filemode", (PyCFunction)DBEnv_get_lg_filemode, METH_NOARGS},
8958#endif
8959#if (DBVER >= 47)
8960 {"set_lk_partitions", (PyCFunction)DBEnv_set_lk_partitions, METH_VARARGS},
8961 {"get_lk_partitions", (PyCFunction)DBEnv_get_lk_partitions, METH_NOARGS},
8962#endif
8963 {"set_lk_detect", (PyCFunction)DBEnv_set_lk_detect, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008964 {"get_lk_detect", (PyCFunction)DBEnv_get_lk_detect, METH_NOARGS},
Gregory P. Smith8b96a352007-01-05 01:59:42 +00008965#if (DBVER < 45)
Jesus Cea6557aac2010-03-22 14:22:26 +00008966 {"set_lk_max", (PyCFunction)DBEnv_set_lk_max, METH_VARARGS},
Gregory P. Smith8b96a352007-01-05 01:59:42 +00008967#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008968 {"set_lk_max_locks", (PyCFunction)DBEnv_set_lk_max_locks, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008969 {"get_lk_max_locks", (PyCFunction)DBEnv_get_lk_max_locks, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008970 {"set_lk_max_lockers", (PyCFunction)DBEnv_set_lk_max_lockers, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008971 {"get_lk_max_lockers", (PyCFunction)DBEnv_get_lk_max_lockers, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008972 {"set_lk_max_objects", (PyCFunction)DBEnv_set_lk_max_objects, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008973 {"get_lk_max_objects", (PyCFunction)DBEnv_get_lk_max_objects, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008974 {"stat_print", (PyCFunction)DBEnv_stat_print,
8975 METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008976 {"set_mp_mmapsize", (PyCFunction)DBEnv_set_mp_mmapsize, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008977 {"get_mp_mmapsize", (PyCFunction)DBEnv_get_mp_mmapsize, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008978 {"set_tmp_dir", (PyCFunction)DBEnv_set_tmp_dir, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008979 {"get_tmp_dir", (PyCFunction)DBEnv_get_tmp_dir, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008980 {"txn_begin", (PyCFunction)DBEnv_txn_begin, METH_VARARGS|METH_KEYWORDS},
8981 {"txn_checkpoint", (PyCFunction)DBEnv_txn_checkpoint, METH_VARARGS},
8982 {"txn_stat", (PyCFunction)DBEnv_txn_stat, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008983 {"txn_stat_print", (PyCFunction)DBEnv_txn_stat_print,
8984 METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008985 {"get_tx_max", (PyCFunction)DBEnv_get_tx_max, METH_NOARGS},
8986 {"get_tx_timestamp", (PyCFunction)DBEnv_get_tx_timestamp, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008987 {"set_tx_max", (PyCFunction)DBEnv_set_tx_max, METH_VARARGS},
Gregory P. Smith8a474042006-01-27 07:05:40 +00008988 {"set_tx_timestamp", (PyCFunction)DBEnv_set_tx_timestamp, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008989 {"lock_detect", (PyCFunction)DBEnv_lock_detect, METH_VARARGS},
8990 {"lock_get", (PyCFunction)DBEnv_lock_get, METH_VARARGS},
8991 {"lock_id", (PyCFunction)DBEnv_lock_id, METH_NOARGS},
8992 {"lock_id_free", (PyCFunction)DBEnv_lock_id_free, METH_VARARGS},
8993 {"lock_put", (PyCFunction)DBEnv_lock_put, METH_VARARGS},
8994 {"lock_stat", (PyCFunction)DBEnv_lock_stat, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008995 {"lock_stat_print", (PyCFunction)DBEnv_lock_stat_print,
8996 METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008997 {"log_cursor", (PyCFunction)DBEnv_log_cursor, METH_NOARGS},
8998 {"log_file", (PyCFunction)DBEnv_log_file, METH_VARARGS},
Gregory P. Smithdb8a8072006-06-05 01:56:15 +00008999#if (DBVER >= 44)
Jesus Cea6557aac2010-03-22 14:22:26 +00009000 {"log_printf", (PyCFunction)DBEnv_log_printf,
9001 METH_VARARGS|METH_KEYWORDS},
9002#endif
9003 {"log_archive", (PyCFunction)DBEnv_log_archive, METH_VARARGS},
9004 {"log_flush", (PyCFunction)DBEnv_log_flush, METH_NOARGS},
9005 {"log_stat", (PyCFunction)DBEnv_log_stat, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00009006 {"log_stat_print", (PyCFunction)DBEnv_log_stat_print,
9007 METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00009008#if (DBVER >= 44)
9009 {"fileid_reset", (PyCFunction)DBEnv_fileid_reset, METH_VARARGS|METH_KEYWORDS},
9010 {"lsn_reset", (PyCFunction)DBEnv_lsn_reset, METH_VARARGS|METH_KEYWORDS},
Gregory P. Smithdb8a8072006-06-05 01:56:15 +00009011#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009012 {"set_get_returns_none",(PyCFunction)DBEnv_set_get_returns_none, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00009013 {"txn_recover", (PyCFunction)DBEnv_txn_recover, METH_NOARGS},
Matthias Klose54cc5392010-03-15 12:46:18 +00009014#if (DBVER < 48)
Jesus Ceaca3939c2008-05-22 15:27:38 +00009015 {"set_rpc_server", (PyCFunction)DBEnv_set_rpc_server,
Stefan Krah77112732011-09-15 22:56:00 +02009016 METH_VARARGS|METH_KEYWORDS},
Matthias Klose54cc5392010-03-15 12:46:18 +00009017#endif
Jesus Cea6557aac2010-03-22 14:22:26 +00009018 {"set_mp_max_openfd", (PyCFunction)DBEnv_set_mp_max_openfd, METH_VARARGS},
9019 {"get_mp_max_openfd", (PyCFunction)DBEnv_get_mp_max_openfd, METH_NOARGS},
9020 {"set_mp_max_write", (PyCFunction)DBEnv_set_mp_max_write, METH_VARARGS},
9021 {"get_mp_max_write", (PyCFunction)DBEnv_get_mp_max_write, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00009022 {"set_verbose", (PyCFunction)DBEnv_set_verbose, METH_VARARGS},
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009023 {"get_verbose", (PyCFunction)DBEnv_get_verbose, METH_VARARGS},
9024 {"set_private", (PyCFunction)DBEnv_set_private, METH_O},
9025 {"get_private", (PyCFunction)DBEnv_get_private, METH_NOARGS},
9026 {"get_open_flags", (PyCFunction)DBEnv_get_open_flags, METH_NOARGS},
9027#if (DBVER >= 47)
9028 {"set_intermediate_dir_mode", (PyCFunction)DBEnv_set_intermediate_dir_mode,
9029 METH_VARARGS},
9030 {"get_intermediate_dir_mode", (PyCFunction)DBEnv_get_intermediate_dir_mode,
9031 METH_NOARGS},
Jesus Ceaef9764f2008-05-13 18:45:46 +00009032#endif
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009033#if (DBVER < 47)
9034 {"set_intermediate_dir", (PyCFunction)DBEnv_set_intermediate_dir,
9035 METH_VARARGS},
9036#endif
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009037 {"rep_start", (PyCFunction)DBEnv_rep_start,
9038 METH_VARARGS|METH_KEYWORDS},
9039 {"rep_set_transport", (PyCFunction)DBEnv_rep_set_transport, METH_VARARGS},
9040 {"rep_process_message", (PyCFunction)DBEnv_rep_process_message,
9041 METH_VARARGS},
9042#if (DBVER >= 46)
9043 {"rep_elect", (PyCFunction)DBEnv_rep_elect, METH_VARARGS},
9044#endif
9045#if (DBVER >= 44)
9046 {"rep_set_config", (PyCFunction)DBEnv_rep_set_config, METH_VARARGS},
9047 {"rep_get_config", (PyCFunction)DBEnv_rep_get_config, METH_VARARGS},
9048 {"rep_sync", (PyCFunction)DBEnv_rep_sync, METH_NOARGS},
Jesus Ceaef9764f2008-05-13 18:45:46 +00009049#endif
9050#if (DBVER >= 45)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009051 {"rep_set_limit", (PyCFunction)DBEnv_rep_set_limit, METH_VARARGS},
9052 {"rep_get_limit", (PyCFunction)DBEnv_rep_get_limit, METH_NOARGS},
9053#endif
9054#if (DBVER >= 47)
9055 {"rep_set_request", (PyCFunction)DBEnv_rep_set_request, METH_VARARGS},
9056 {"rep_get_request", (PyCFunction)DBEnv_rep_get_request, METH_NOARGS},
9057#endif
9058#if (DBVER >= 45)
9059 {"set_event_notify", (PyCFunction)DBEnv_set_event_notify, METH_O},
Jesus Ceaef9764f2008-05-13 18:45:46 +00009060#endif
9061#if (DBVER >= 45)
9062 {"rep_set_nsites", (PyCFunction)DBEnv_rep_set_nsites, METH_VARARGS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009063 {"rep_get_nsites", (PyCFunction)DBEnv_rep_get_nsites, METH_NOARGS},
Jesus Ceaef9764f2008-05-13 18:45:46 +00009064 {"rep_set_priority", (PyCFunction)DBEnv_rep_set_priority, METH_VARARGS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009065 {"rep_get_priority", (PyCFunction)DBEnv_rep_get_priority, METH_NOARGS},
Jesus Ceaef9764f2008-05-13 18:45:46 +00009066 {"rep_set_timeout", (PyCFunction)DBEnv_rep_set_timeout, METH_VARARGS},
9067 {"rep_get_timeout", (PyCFunction)DBEnv_rep_get_timeout, METH_VARARGS},
9068#endif
Jesus Cea6557aac2010-03-22 14:22:26 +00009069#if (DBVER >= 47)
9070 {"rep_set_clockskew", (PyCFunction)DBEnv_rep_set_clockskew, METH_VARARGS},
9071 {"rep_get_clockskew", (PyCFunction)DBEnv_rep_get_clockskew, METH_VARARGS},
9072#endif
9073 {"rep_stat", (PyCFunction)DBEnv_rep_stat,
9074 METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00009075 {"rep_stat_print", (PyCFunction)DBEnv_rep_stat_print,
9076 METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00009077
Jesus Ceaef9764f2008-05-13 18:45:46 +00009078#if (DBVER >= 45)
9079 {"repmgr_start", (PyCFunction)DBEnv_repmgr_start,
9080 METH_VARARGS|METH_KEYWORDS},
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009081#if (DBVER < 52)
Jesus Ceaef9764f2008-05-13 18:45:46 +00009082 {"repmgr_set_local_site", (PyCFunction)DBEnv_repmgr_set_local_site,
9083 METH_VARARGS|METH_KEYWORDS},
9084 {"repmgr_add_remote_site", (PyCFunction)DBEnv_repmgr_add_remote_site,
9085 METH_VARARGS|METH_KEYWORDS},
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009086#endif
Jesus Ceaef9764f2008-05-13 18:45:46 +00009087 {"repmgr_set_ack_policy", (PyCFunction)DBEnv_repmgr_set_ack_policy,
9088 METH_VARARGS},
9089 {"repmgr_get_ack_policy", (PyCFunction)DBEnv_repmgr_get_ack_policy,
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009090 METH_NOARGS},
Jesus Ceaef9764f2008-05-13 18:45:46 +00009091 {"repmgr_site_list", (PyCFunction)DBEnv_repmgr_site_list,
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009092 METH_NOARGS},
Jesus Ceaef9764f2008-05-13 18:45:46 +00009093#endif
9094#if (DBVER >= 46)
9095 {"repmgr_stat", (PyCFunction)DBEnv_repmgr_stat,
9096 METH_VARARGS|METH_KEYWORDS},
9097 {"repmgr_stat_print", (PyCFunction)DBEnv_repmgr_stat_print,
9098 METH_VARARGS|METH_KEYWORDS},
9099#endif
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009100#if (DBVER >= 52)
9101 {"repmgr_site", (PyCFunction)DBEnv_repmgr_site,
9102 METH_VARARGS | METH_KEYWORDS},
9103 {"repmgr_site_by_eid", (PyCFunction)DBEnv_repmgr_site_by_eid,
9104 METH_VARARGS | METH_KEYWORDS},
9105#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009106 {NULL, NULL} /* sentinel */
9107};
9108
9109
9110static PyMethodDef DBTxn_methods[] = {
9111 {"commit", (PyCFunction)DBTxn_commit, METH_VARARGS},
9112 {"prepare", (PyCFunction)DBTxn_prepare, METH_VARARGS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009113 {"discard", (PyCFunction)DBTxn_discard, METH_NOARGS},
9114 {"abort", (PyCFunction)DBTxn_abort, METH_NOARGS},
9115 {"id", (PyCFunction)DBTxn_id, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00009116 {"set_timeout", (PyCFunction)DBTxn_set_timeout,
9117 METH_VARARGS|METH_KEYWORDS},
9118#if (DBVER >= 44)
9119 {"set_name", (PyCFunction)DBTxn_set_name, METH_VARARGS},
9120 {"get_name", (PyCFunction)DBTxn_get_name, METH_NOARGS},
9121#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009122 {NULL, NULL} /* sentinel */
9123};
9124
9125
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009126static PyMethodDef DBSequence_methods[] = {
9127 {"close", (PyCFunction)DBSequence_close, METH_VARARGS},
9128 {"get", (PyCFunction)DBSequence_get, METH_VARARGS|METH_KEYWORDS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009129 {"get_dbp", (PyCFunction)DBSequence_get_dbp, METH_NOARGS},
9130 {"get_key", (PyCFunction)DBSequence_get_key, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00009131 {"initial_value", (PyCFunction)DBSequence_initial_value, METH_VARARGS},
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009132 {"open", (PyCFunction)DBSequence_open, METH_VARARGS|METH_KEYWORDS},
9133 {"remove", (PyCFunction)DBSequence_remove, METH_VARARGS|METH_KEYWORDS},
9134 {"set_cachesize", (PyCFunction)DBSequence_set_cachesize, METH_VARARGS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009135 {"get_cachesize", (PyCFunction)DBSequence_get_cachesize, METH_NOARGS},
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009136 {"set_flags", (PyCFunction)DBSequence_set_flags, METH_VARARGS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009137 {"get_flags", (PyCFunction)DBSequence_get_flags, METH_NOARGS},
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009138 {"set_range", (PyCFunction)DBSequence_set_range, METH_VARARGS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009139 {"get_range", (PyCFunction)DBSequence_get_range, METH_NOARGS},
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009140 {"stat", (PyCFunction)DBSequence_stat, METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00009141 {"stat_print", (PyCFunction)DBSequence_stat_print,
9142 METH_VARARGS|METH_KEYWORDS},
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009143 {NULL, NULL} /* sentinel */
9144};
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009145
9146
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009147static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009148DBEnv_db_home_get(DBEnvObject* self)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009149{
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009150 const char *home = NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009151
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009152 CHECK_ENV_NOT_CLOSED(self);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009153
Jesus Cea6557aac2010-03-22 14:22:26 +00009154 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009155 self->db_env->get_home(self->db_env, &home);
Jesus Cea6557aac2010-03-22 14:22:26 +00009156 MYDB_END_ALLOW_THREADS;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009157
9158 if (home == NULL) {
9159 RETURN_NONE();
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009160 }
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009161 return PyBytes_FromString(home);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009162}
9163
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009164static PyGetSetDef DBEnv_getsets[] = {
9165 {"db_home", (getter)DBEnv_db_home_get, NULL,},
9166 {NULL}
9167};
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009168
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009169
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009170statichere PyTypeObject DB_Type = {
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009171#if (PY_VERSION_HEX < 0x03000000)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009172 PyObject_HEAD_INIT(NULL)
9173 0, /*ob_size*/
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009174#else
9175 PyVarObject_HEAD_INIT(NULL, 0)
9176#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009177 "DB", /*tp_name*/
9178 sizeof(DBObject), /*tp_basicsize*/
9179 0, /*tp_itemsize*/
9180 /* methods */
9181 (destructor)DB_dealloc, /*tp_dealloc*/
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009182 0, /*tp_print*/
9183 0, /*tp_getattr*/
9184 0, /*tp_setattr*/
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009185 0, /*tp_compare*/
9186 0, /*tp_repr*/
9187 0, /*tp_as_number*/
Jesus Cea6557aac2010-03-22 14:22:26 +00009188 &DB_sequence,/*tp_as_sequence*/
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009189 &DB_mapping,/*tp_as_mapping*/
9190 0, /*tp_hash*/
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009191 0, /* tp_call */
9192 0, /* tp_str */
9193 0, /* tp_getattro */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009194 0, /* tp_setattro */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009195 0, /* tp_as_buffer */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009196#if (PY_VERSION_HEX < 0x03000000)
Gregory P. Smith31c50652004-06-28 01:20:40 +00009197 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009198#else
9199 Py_TPFLAGS_DEFAULT, /* tp_flags */
9200#endif
9201 0, /* tp_doc */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009202 0, /* tp_traverse */
9203 0, /* tp_clear */
9204 0, /* tp_richcompare */
Gregory P. Smith31c50652004-06-28 01:20:40 +00009205 offsetof(DBObject, in_weakreflist), /* tp_weaklistoffset */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009206 0, /*tp_iter*/
9207 0, /*tp_iternext*/
9208 DB_methods, /*tp_methods*/
9209 0, /*tp_members*/
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009210};
9211
9212
9213statichere PyTypeObject DBCursor_Type = {
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009214#if (PY_VERSION_HEX < 0x03000000)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009215 PyObject_HEAD_INIT(NULL)
9216 0, /*ob_size*/
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009217#else
9218 PyVarObject_HEAD_INIT(NULL, 0)
9219#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009220 "DBCursor", /*tp_name*/
9221 sizeof(DBCursorObject), /*tp_basicsize*/
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009222 0, /*tp_itemsize*/
9223 /* methods */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009224 (destructor)DBCursor_dealloc,/*tp_dealloc*/
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009225 0, /*tp_print*/
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009226 0, /*tp_getattr*/
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009227 0, /*tp_setattr*/
9228 0, /*tp_compare*/
9229 0, /*tp_repr*/
9230 0, /*tp_as_number*/
9231 0, /*tp_as_sequence*/
9232 0, /*tp_as_mapping*/
9233 0, /*tp_hash*/
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009234 0, /*tp_call*/
9235 0, /*tp_str*/
9236 0, /*tp_getattro*/
9237 0, /*tp_setattro*/
9238 0, /*tp_as_buffer*/
9239#if (PY_VERSION_HEX < 0x03000000)
Gregory P. Smith31c50652004-06-28 01:20:40 +00009240 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009241#else
9242 Py_TPFLAGS_DEFAULT, /* tp_flags */
9243#endif
9244 0, /* tp_doc */
9245 0, /* tp_traverse */
9246 0, /* tp_clear */
9247 0, /* tp_richcompare */
9248 offsetof(DBCursorObject, in_weakreflist), /* tp_weaklistoffset */
9249 0, /*tp_iter*/
9250 0, /*tp_iternext*/
9251 DBCursor_methods, /*tp_methods*/
9252 0, /*tp_members*/
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009253};
9254
9255
Jesus Cea6557aac2010-03-22 14:22:26 +00009256statichere PyTypeObject DBLogCursor_Type = {
9257#if (PY_VERSION_HEX < 0x03000000)
9258 PyObject_HEAD_INIT(NULL)
9259 0, /*ob_size*/
9260#else
9261 PyVarObject_HEAD_INIT(NULL, 0)
9262#endif
9263 "DBLogCursor", /*tp_name*/
9264 sizeof(DBLogCursorObject), /*tp_basicsize*/
9265 0, /*tp_itemsize*/
9266 /* methods */
9267 (destructor)DBLogCursor_dealloc,/*tp_dealloc*/
9268 0, /*tp_print*/
9269 0, /*tp_getattr*/
9270 0, /*tp_setattr*/
9271 0, /*tp_compare*/
9272 0, /*tp_repr*/
9273 0, /*tp_as_number*/
9274 0, /*tp_as_sequence*/
9275 0, /*tp_as_mapping*/
9276 0, /*tp_hash*/
9277 0, /*tp_call*/
9278 0, /*tp_str*/
9279 0, /*tp_getattro*/
9280 0, /*tp_setattro*/
9281 0, /*tp_as_buffer*/
9282#if (PY_VERSION_HEX < 0x03000000)
9283 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
9284#else
9285 Py_TPFLAGS_DEFAULT, /* tp_flags */
9286#endif
9287 0, /* tp_doc */
9288 0, /* tp_traverse */
9289 0, /* tp_clear */
9290 0, /* tp_richcompare */
9291 offsetof(DBLogCursorObject, in_weakreflist), /* tp_weaklistoffset */
9292 0, /*tp_iter*/
9293 0, /*tp_iternext*/
9294 DBLogCursor_methods, /*tp_methods*/
9295 0, /*tp_members*/
9296};
9297
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009298#if (DBVER >= 52)
9299statichere PyTypeObject DBSite_Type = {
9300#if (PY_VERSION_HEX < 0x03000000)
9301 PyObject_HEAD_INIT(NULL)
9302 0, /*ob_size*/
9303#else
9304 PyVarObject_HEAD_INIT(NULL, 0)
9305#endif
9306 "DBSite", /*tp_name*/
9307 sizeof(DBSiteObject), /*tp_basicsize*/
9308 0, /*tp_itemsize*/
9309 /* methods */
9310 (destructor)DBSite_dealloc,/*tp_dealloc*/
9311 0, /*tp_print*/
9312 0, /*tp_getattr*/
9313 0, /*tp_setattr*/
9314 0, /*tp_compare*/
9315 0, /*tp_repr*/
9316 0, /*tp_as_number*/
9317 0, /*tp_as_sequence*/
9318 0, /*tp_as_mapping*/
9319 0, /*tp_hash*/
9320 0, /*tp_call*/
9321 0, /*tp_str*/
9322 0, /*tp_getattro*/
9323 0, /*tp_setattro*/
9324 0, /*tp_as_buffer*/
9325#if (PY_VERSION_HEX < 0x03000000)
9326 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
9327#else
9328 Py_TPFLAGS_DEFAULT, /* tp_flags */
9329#endif
9330 0, /* tp_doc */
9331 0, /* tp_traverse */
9332 0, /* tp_clear */
9333 0, /* tp_richcompare */
9334 offsetof(DBSiteObject, in_weakreflist), /* tp_weaklistoffset */
9335 0, /*tp_iter*/
9336 0, /*tp_iternext*/
9337 DBSite_methods, /*tp_methods*/
9338 0, /*tp_members*/
9339};
9340#endif
Jesus Cea6557aac2010-03-22 14:22:26 +00009341
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009342statichere PyTypeObject DBEnv_Type = {
9343#if (PY_VERSION_HEX < 0x03000000)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009344 PyObject_HEAD_INIT(NULL)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009345 0, /*ob_size*/
9346#else
9347 PyVarObject_HEAD_INIT(NULL, 0)
9348#endif
9349 "DBEnv", /*tp_name*/
9350 sizeof(DBEnvObject), /*tp_basicsize*/
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009351 0, /*tp_itemsize*/
9352 /* methods */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009353 (destructor)DBEnv_dealloc, /*tp_dealloc*/
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009354 0, /*tp_print*/
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009355 0, /*tp_getattr*/
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009356 0, /*tp_setattr*/
9357 0, /*tp_compare*/
9358 0, /*tp_repr*/
9359 0, /*tp_as_number*/
9360 0, /*tp_as_sequence*/
9361 0, /*tp_as_mapping*/
9362 0, /*tp_hash*/
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009363 0, /* tp_call */
9364 0, /* tp_str */
9365 0, /* tp_getattro */
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009366 0, /* tp_setattro */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009367 0, /* tp_as_buffer */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009368#if (PY_VERSION_HEX < 0x03000000)
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009369 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009370#else
9371 Py_TPFLAGS_DEFAULT, /* tp_flags */
9372#endif
9373 0, /* tp_doc */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009374 0, /* tp_traverse */
9375 0, /* tp_clear */
9376 0, /* tp_richcompare */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009377 offsetof(DBEnvObject, in_weakreflist), /* tp_weaklistoffset */
9378 0, /* tp_iter */
9379 0, /* tp_iternext */
9380 DBEnv_methods, /* tp_methods */
9381 0, /* tp_members */
9382 DBEnv_getsets, /* tp_getsets */
9383};
9384
9385statichere PyTypeObject DBTxn_Type = {
9386#if (PY_VERSION_HEX < 0x03000000)
9387 PyObject_HEAD_INIT(NULL)
9388 0, /*ob_size*/
9389#else
9390 PyVarObject_HEAD_INIT(NULL, 0)
9391#endif
9392 "DBTxn", /*tp_name*/
9393 sizeof(DBTxnObject), /*tp_basicsize*/
9394 0, /*tp_itemsize*/
9395 /* methods */
9396 (destructor)DBTxn_dealloc, /*tp_dealloc*/
9397 0, /*tp_print*/
9398 0, /*tp_getattr*/
9399 0, /*tp_setattr*/
9400 0, /*tp_compare*/
9401 0, /*tp_repr*/
9402 0, /*tp_as_number*/
9403 0, /*tp_as_sequence*/
9404 0, /*tp_as_mapping*/
9405 0, /*tp_hash*/
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009406 0, /* tp_call */
9407 0, /* tp_str */
9408 0, /* tp_getattro */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009409 0, /* tp_setattro */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009410 0, /* tp_as_buffer */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009411#if (PY_VERSION_HEX < 0x03000000)
9412 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
9413#else
9414 Py_TPFLAGS_DEFAULT, /* tp_flags */
9415#endif
9416 0, /* tp_doc */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009417 0, /* tp_traverse */
9418 0, /* tp_clear */
9419 0, /* tp_richcompare */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009420 offsetof(DBTxnObject, in_weakreflist), /* tp_weaklistoffset */
9421 0, /*tp_iter*/
9422 0, /*tp_iternext*/
9423 DBTxn_methods, /*tp_methods*/
9424 0, /*tp_members*/
9425};
9426
9427
9428statichere PyTypeObject DBLock_Type = {
9429#if (PY_VERSION_HEX < 0x03000000)
9430 PyObject_HEAD_INIT(NULL)
9431 0, /*ob_size*/
9432#else
9433 PyVarObject_HEAD_INIT(NULL, 0)
9434#endif
9435 "DBLock", /*tp_name*/
9436 sizeof(DBLockObject), /*tp_basicsize*/
9437 0, /*tp_itemsize*/
9438 /* methods */
9439 (destructor)DBLock_dealloc, /*tp_dealloc*/
9440 0, /*tp_print*/
9441 0, /*tp_getattr*/
9442 0, /*tp_setattr*/
9443 0, /*tp_compare*/
9444 0, /*tp_repr*/
9445 0, /*tp_as_number*/
9446 0, /*tp_as_sequence*/
9447 0, /*tp_as_mapping*/
9448 0, /*tp_hash*/
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009449 0, /* tp_call */
9450 0, /* tp_str */
9451 0, /* tp_getattro */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009452 0, /* tp_setattro */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009453 0, /* tp_as_buffer */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009454#if (PY_VERSION_HEX < 0x03000000)
9455 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
9456#else
9457 Py_TPFLAGS_DEFAULT, /* tp_flags */
9458#endif
9459 0, /* tp_doc */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009460 0, /* tp_traverse */
9461 0, /* tp_clear */
9462 0, /* tp_richcompare */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009463 offsetof(DBLockObject, in_weakreflist), /* tp_weaklistoffset */
9464};
9465
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009466statichere PyTypeObject DBSequence_Type = {
9467#if (PY_VERSION_HEX < 0x03000000)
9468 PyObject_HEAD_INIT(NULL)
9469 0, /*ob_size*/
9470#else
9471 PyVarObject_HEAD_INIT(NULL, 0)
9472#endif
9473 "DBSequence", /*tp_name*/
9474 sizeof(DBSequenceObject), /*tp_basicsize*/
9475 0, /*tp_itemsize*/
9476 /* methods */
9477 (destructor)DBSequence_dealloc, /*tp_dealloc*/
9478 0, /*tp_print*/
9479 0, /*tp_getattr*/
9480 0, /*tp_setattr*/
9481 0, /*tp_compare*/
9482 0, /*tp_repr*/
9483 0, /*tp_as_number*/
9484 0, /*tp_as_sequence*/
9485 0, /*tp_as_mapping*/
9486 0, /*tp_hash*/
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009487 0, /* tp_call */
9488 0, /* tp_str */
9489 0, /* tp_getattro */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009490 0, /* tp_setattro */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009491 0, /* tp_as_buffer */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009492#if (PY_VERSION_HEX < 0x03000000)
9493 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
9494#else
9495 Py_TPFLAGS_DEFAULT, /* tp_flags */
9496#endif
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009497 0, /* tp_doc */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009498 0, /* tp_traverse */
9499 0, /* tp_clear */
9500 0, /* tp_richcompare */
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009501 offsetof(DBSequenceObject, in_weakreflist), /* tp_weaklistoffset */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009502 0, /*tp_iter*/
9503 0, /*tp_iternext*/
9504 DBSequence_methods, /*tp_methods*/
9505 0, /*tp_members*/
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009506};
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009507
9508/* --------------------------------------------------------------------- */
9509/* Module-level functions */
9510
9511static PyObject*
9512DB_construct(PyObject* self, PyObject* args, PyObject* kwargs)
9513{
9514 PyObject* dbenvobj = NULL;
9515 int flags = 0;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00009516 static char* kwnames[] = { "dbEnv", "flags", NULL};
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009517
Barry Warsaw9a0d7792002-12-30 20:53:52 +00009518 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Oi:DB", kwnames,
9519 &dbenvobj, &flags))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009520 return NULL;
9521 if (dbenvobj == Py_None)
9522 dbenvobj = NULL;
9523 else if (dbenvobj && !DBEnvObject_Check(dbenvobj)) {
9524 makeTypeError("DBEnv", dbenvobj);
9525 return NULL;
9526 }
9527
9528 return (PyObject* )newDBObject((DBEnvObject*)dbenvobj, flags);
9529}
9530
9531
9532static PyObject*
9533DBEnv_construct(PyObject* self, PyObject* args)
9534{
9535 int flags = 0;
9536 if (!PyArg_ParseTuple(args, "|i:DbEnv", &flags)) return NULL;
9537 return (PyObject* )newDBEnvObject(flags);
9538}
9539
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009540static PyObject*
9541DBSequence_construct(PyObject* self, PyObject* args, PyObject* kwargs)
9542{
Neal Norwitzb4fcf8d2006-06-11 05:44:18 +00009543 PyObject* dbobj;
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009544 int flags = 0;
9545 static char* kwnames[] = { "db", "flags", NULL};
9546
9547 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|i:DBSequence", kwnames, &dbobj, &flags))
9548 return NULL;
Neal Norwitzb4fcf8d2006-06-11 05:44:18 +00009549 if (!DBObject_Check(dbobj)) {
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009550 makeTypeError("DB", dbobj);
9551 return NULL;
9552 }
9553 return (PyObject* )newDBSequenceObject((DBObject*)dbobj, flags);
9554}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009555
9556static char bsddb_version_doc[] =
9557"Returns a tuple of major, minor, and patch release numbers of the\n\
9558underlying DB library.";
9559
9560static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009561bsddb_version(PyObject* self)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009562{
9563 int major, minor, patch;
9564
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009565 /* This should be instantaneous, no need to release the GIL */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009566 db_version(&major, &minor, &patch);
9567 return Py_BuildValue("(iii)", major, minor, patch);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009568}
9569
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009570#if (DBVER >= 50)
9571static PyObject*
9572bsddb_version_full(PyObject* self)
9573{
9574 char *version_string;
9575 int family, release, major, minor, patch;
9576
9577 /* This should be instantaneous, no need to release the GIL */
9578 version_string = db_full_version(&family, &release, &major, &minor, &patch);
9579 return Py_BuildValue("(siiiii)",
9580 version_string, family, release, major, minor, patch);
9581}
9582#endif
9583
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009584
9585/* List of functions defined in the module */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009586static PyMethodDef bsddb_methods[] = {
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009587 {"DB", (PyCFunction)DB_construct, METH_VARARGS | METH_KEYWORDS },
9588 {"DBEnv", (PyCFunction)DBEnv_construct, METH_VARARGS},
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009589 {"DBSequence", (PyCFunction)DBSequence_construct, METH_VARARGS | METH_KEYWORDS },
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009590 {"version", (PyCFunction)bsddb_version, METH_NOARGS, bsddb_version_doc},
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009591#if (DBVER >= 50)
9592 {"full_version", (PyCFunction)bsddb_version_full, METH_NOARGS},
9593#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009594 {NULL, NULL} /* sentinel */
9595};
9596
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009597
Gregory P. Smith39250532007-10-09 06:02:21 +00009598/* API structure */
9599static BSDDB_api bsddb_api;
9600
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009601
9602/* --------------------------------------------------------------------- */
9603/* Module initialization */
9604
9605
9606/* Convenience routine to export an integer value.
9607 * Errors are silently ignored, for better or for worse...
9608 */
9609#define ADD_INT(dict, NAME) _addIntToDict(dict, #NAME, NAME)
9610
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009611/*
9612** We can rename the module at import time, so the string allocated
9613** must be big enough, and any use of the name must use this particular
9614** string.
9615*/
Gregory P. Smith41631e82003-09-21 00:08:14 +00009616#define MODULE_NAME_MAX_LEN 11
9617static char _bsddbModuleName[MODULE_NAME_MAX_LEN+1] = "_bsddb";
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009618
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009619#if (PY_VERSION_HEX >= 0x03000000)
9620static struct PyModuleDef bsddbmodule = {
9621 PyModuleDef_HEAD_INIT,
9622 _bsddbModuleName, /* Name of module */
9623 NULL, /* module documentation, may be NULL */
9624 -1, /* size of per-interpreter state of the module,
9625 or -1 if the module keeps state in global variables. */
9626 bsddb_methods,
9627 NULL, /* Reload */
9628 NULL, /* Traverse */
9629 NULL, /* Clear */
9630 NULL /* Free */
9631};
9632#endif
9633
9634
9635#if (PY_VERSION_HEX < 0x03000000)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009636DL_EXPORT(void) init_bsddb(void)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009637#else
9638PyMODINIT_FUNC PyInit__bsddb(void) /* Note the two underscores */
9639#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009640{
9641 PyObject* m;
9642 PyObject* d;
Gregory P. Smith39250532007-10-09 06:02:21 +00009643 PyObject* py_api;
Jesus Cea6557aac2010-03-22 14:22:26 +00009644 PyObject* pybsddb_version_s;
9645 PyObject* db_version_s;
9646 PyObject* cvsid_s;
9647
9648#if (PY_VERSION_HEX < 0x03000000)
9649 pybsddb_version_s = PyString_FromString(PY_BSDDB_VERSION);
9650 db_version_s = PyString_FromString(DB_VERSION_STRING);
9651 cvsid_s = PyString_FromString(rcs_id);
9652#else
9653 /* This data should be ascii, so UTF-8 conversion is fine */
9654 pybsddb_version_s = PyUnicode_FromString(PY_BSDDB_VERSION);
9655 db_version_s = PyUnicode_FromString(DB_VERSION_STRING);
9656 cvsid_s = PyUnicode_FromString(rcs_id);
9657#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009658
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009659 /* Initialize object types */
9660 if ((PyType_Ready(&DB_Type) < 0)
9661 || (PyType_Ready(&DBCursor_Type) < 0)
Jesus Cea6557aac2010-03-22 14:22:26 +00009662 || (PyType_Ready(&DBLogCursor_Type) < 0)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009663 || (PyType_Ready(&DBEnv_Type) < 0)
9664 || (PyType_Ready(&DBTxn_Type) < 0)
9665 || (PyType_Ready(&DBLock_Type) < 0)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009666 || (PyType_Ready(&DBSequence_Type) < 0)
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009667#if (DBVER >= 52)
9668 || (PyType_Ready(&DBSite_Type) < 0)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009669#endif
9670 ) {
9671#if (PY_VERSION_HEX < 0x03000000)
9672 return;
9673#else
9674 return NULL;
9675#endif
9676 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009677
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009678 /* Create the module and add the functions */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009679#if (PY_VERSION_HEX < 0x03000000)
Gregory P. Smith41631e82003-09-21 00:08:14 +00009680 m = Py_InitModule(_bsddbModuleName, bsddb_methods);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009681#else
9682 m=PyModule_Create(&bsddbmodule);
9683#endif
9684 if (m == NULL) {
9685#if (PY_VERSION_HEX < 0x03000000)
9686 return;
9687#else
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009688 return NULL;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009689#endif
9690 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009691
9692 /* Add some symbolic constants to the module */
9693 d = PyModule_GetDict(m);
9694 PyDict_SetItemString(d, "__version__", pybsddb_version_s);
9695 PyDict_SetItemString(d, "cvsid", cvsid_s);
9696 PyDict_SetItemString(d, "DB_VERSION_STRING", db_version_s);
9697 Py_DECREF(pybsddb_version_s);
9698 pybsddb_version_s = NULL;
9699 Py_DECREF(cvsid_s);
9700 cvsid_s = NULL;
9701 Py_DECREF(db_version_s);
9702 db_version_s = NULL;
9703
9704 ADD_INT(d, DB_VERSION_MAJOR);
9705 ADD_INT(d, DB_VERSION_MINOR);
9706 ADD_INT(d, DB_VERSION_PATCH);
9707
9708 ADD_INT(d, DB_MAX_PAGES);
9709 ADD_INT(d, DB_MAX_RECORDS);
9710
Matthias Klose54cc5392010-03-15 12:46:18 +00009711#if (DBVER < 48)
Gregory P. Smith41631e82003-09-21 00:08:14 +00009712 ADD_INT(d, DB_RPCCLIENT);
Matthias Klose54cc5392010-03-15 12:46:18 +00009713#endif
9714
9715#if (DBVER < 48)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009716 ADD_INT(d, DB_XA_CREATE);
Matthias Klose54cc5392010-03-15 12:46:18 +00009717#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009718
9719 ADD_INT(d, DB_CREATE);
9720 ADD_INT(d, DB_NOMMAP);
9721 ADD_INT(d, DB_THREAD);
Jesus Ceaef9764f2008-05-13 18:45:46 +00009722#if (DBVER >= 45)
9723 ADD_INT(d, DB_MULTIVERSION);
9724#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009725
9726 ADD_INT(d, DB_FORCE);
9727 ADD_INT(d, DB_INIT_CDB);
9728 ADD_INT(d, DB_INIT_LOCK);
9729 ADD_INT(d, DB_INIT_LOG);
9730 ADD_INT(d, DB_INIT_MPOOL);
9731 ADD_INT(d, DB_INIT_TXN);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009732 ADD_INT(d, DB_JOINENV);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009733
Matthias Klose54cc5392010-03-15 12:46:18 +00009734#if (DBVER >= 48)
9735 ADD_INT(d, DB_GID_SIZE);
9736#else
Jesus Ceaef9764f2008-05-13 18:45:46 +00009737 ADD_INT(d, DB_XIDDATASIZE);
Matthias Klose54cc5392010-03-15 12:46:18 +00009738 /* Allow new code to work in old BDB releases */
9739 _addIntToDict(d, "DB_GID_SIZE", DB_XIDDATASIZE);
9740#endif
Jesus Ceaef9764f2008-05-13 18:45:46 +00009741
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009742 ADD_INT(d, DB_RECOVER);
9743 ADD_INT(d, DB_RECOVER_FATAL);
9744 ADD_INT(d, DB_TXN_NOSYNC);
9745 ADD_INT(d, DB_USE_ENVIRON);
9746 ADD_INT(d, DB_USE_ENVIRON_ROOT);
9747
9748 ADD_INT(d, DB_LOCKDOWN);
9749 ADD_INT(d, DB_PRIVATE);
9750 ADD_INT(d, DB_SYSTEM_MEM);
9751
9752 ADD_INT(d, DB_TXN_SYNC);
9753 ADD_INT(d, DB_TXN_NOWAIT);
9754
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009755#if (DBVER >= 51)
9756 ADD_INT(d, DB_TXN_BULK);
9757#endif
9758
9759#if (DBVER >= 48)
9760 ADD_INT(d, DB_CURSOR_BULK);
9761#endif
9762
Jesus Cea6557aac2010-03-22 14:22:26 +00009763#if (DBVER >= 46)
9764 ADD_INT(d, DB_TXN_WAIT);
9765#endif
9766
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009767 ADD_INT(d, DB_EXCL);
9768 ADD_INT(d, DB_FCNTL_LOCKING);
9769 ADD_INT(d, DB_ODDFILESIZE);
9770 ADD_INT(d, DB_RDWRMASTER);
9771 ADD_INT(d, DB_RDONLY);
9772 ADD_INT(d, DB_TRUNCATE);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009773 ADD_INT(d, DB_EXTENT);
9774 ADD_INT(d, DB_CDB_ALLDB);
9775 ADD_INT(d, DB_VERIFY);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009776 ADD_INT(d, DB_UPGRADE);
9777
Jesus Cea6557aac2010-03-22 14:22:26 +00009778 ADD_INT(d, DB_PRINTABLE);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009779 ADD_INT(d, DB_AGGRESSIVE);
9780 ADD_INT(d, DB_NOORDERCHK);
9781 ADD_INT(d, DB_ORDERCHKONLY);
9782 ADD_INT(d, DB_PR_PAGE);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009783
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009784 ADD_INT(d, DB_PR_RECOVERYTEST);
9785 ADD_INT(d, DB_SALVAGE);
9786
9787 ADD_INT(d, DB_LOCK_NORUN);
9788 ADD_INT(d, DB_LOCK_DEFAULT);
9789 ADD_INT(d, DB_LOCK_OLDEST);
9790 ADD_INT(d, DB_LOCK_RANDOM);
9791 ADD_INT(d, DB_LOCK_YOUNGEST);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009792 ADD_INT(d, DB_LOCK_MAXLOCKS);
9793 ADD_INT(d, DB_LOCK_MINLOCKS);
9794 ADD_INT(d, DB_LOCK_MINWRITE);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009795
Jesus Ceaef9764f2008-05-13 18:45:46 +00009796 ADD_INT(d, DB_LOCK_EXPIRE);
Jesus Ceaef9764f2008-05-13 18:45:46 +00009797 ADD_INT(d, DB_LOCK_MAXWRITE);
Jesus Ceaef9764f2008-05-13 18:45:46 +00009798
Barry Warsaw9a0d7792002-12-30 20:53:52 +00009799 _addIntToDict(d, "DB_LOCK_CONFLICT", 0);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009800
9801 ADD_INT(d, DB_LOCK_DUMP);
9802 ADD_INT(d, DB_LOCK_GET);
9803 ADD_INT(d, DB_LOCK_INHERIT);
9804 ADD_INT(d, DB_LOCK_PUT);
9805 ADD_INT(d, DB_LOCK_PUT_ALL);
9806 ADD_INT(d, DB_LOCK_PUT_OBJ);
9807
9808 ADD_INT(d, DB_LOCK_NG);
9809 ADD_INT(d, DB_LOCK_READ);
9810 ADD_INT(d, DB_LOCK_WRITE);
9811 ADD_INT(d, DB_LOCK_NOWAIT);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009812 ADD_INT(d, DB_LOCK_WAIT);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009813 ADD_INT(d, DB_LOCK_IWRITE);
9814 ADD_INT(d, DB_LOCK_IREAD);
9815 ADD_INT(d, DB_LOCK_IWR);
Gregory P. Smith29602d22006-01-24 09:46:48 +00009816#if (DBVER < 44)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009817 ADD_INT(d, DB_LOCK_DIRTY);
Gregory P. Smith29602d22006-01-24 09:46:48 +00009818#else
9819 ADD_INT(d, DB_LOCK_READ_UNCOMMITTED); /* renamed in 4.4 */
9820#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009821 ADD_INT(d, DB_LOCK_WWRITE);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009822
9823 ADD_INT(d, DB_LOCK_RECORD);
9824 ADD_INT(d, DB_LOCK_UPGRADE);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009825 ADD_INT(d, DB_LOCK_SWITCH);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009826 ADD_INT(d, DB_LOCK_UPGRADE_WRITE);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009827
9828 ADD_INT(d, DB_LOCK_NOWAIT);
9829 ADD_INT(d, DB_LOCK_RECORD);
9830 ADD_INT(d, DB_LOCK_UPGRADE);
9831
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009832 ADD_INT(d, DB_LSTAT_ABORTED);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009833 ADD_INT(d, DB_LSTAT_FREE);
9834 ADD_INT(d, DB_LSTAT_HELD);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009835
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009836 ADD_INT(d, DB_LSTAT_PENDING);
9837 ADD_INT(d, DB_LSTAT_WAITING);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009838
9839 ADD_INT(d, DB_ARCH_ABS);
9840 ADD_INT(d, DB_ARCH_DATA);
9841 ADD_INT(d, DB_ARCH_LOG);
Gregory P. Smith3dd20022006-06-05 00:31:01 +00009842 ADD_INT(d, DB_ARCH_REMOVE);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009843
9844 ADD_INT(d, DB_BTREE);
9845 ADD_INT(d, DB_HASH);
9846 ADD_INT(d, DB_RECNO);
9847 ADD_INT(d, DB_QUEUE);
9848 ADD_INT(d, DB_UNKNOWN);
9849
9850 ADD_INT(d, DB_DUP);
9851 ADD_INT(d, DB_DUPSORT);
9852 ADD_INT(d, DB_RECNUM);
9853 ADD_INT(d, DB_RENUMBER);
9854 ADD_INT(d, DB_REVSPLITOFF);
9855 ADD_INT(d, DB_SNAPSHOT);
9856
Jesus Cea6557aac2010-03-22 14:22:26 +00009857 ADD_INT(d, DB_INORDER);
Jesus Cea6557aac2010-03-22 14:22:26 +00009858
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009859 ADD_INT(d, DB_JOIN_NOSORT);
9860
9861 ADD_INT(d, DB_AFTER);
9862 ADD_INT(d, DB_APPEND);
9863 ADD_INT(d, DB_BEFORE);
Gregory P. Smith8b96a352007-01-05 01:59:42 +00009864#if (DBVER < 45)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009865 ADD_INT(d, DB_CACHED_COUNTS);
Gregory P. Smith8b96a352007-01-05 01:59:42 +00009866#endif
Jesus Ceaca3939c2008-05-22 15:27:38 +00009867
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009868 ADD_INT(d, DB_CONSUME);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009869 ADD_INT(d, DB_CONSUME_WAIT);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009870 ADD_INT(d, DB_CURRENT);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009871 ADD_INT(d, DB_FAST_STAT);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009872 ADD_INT(d, DB_FIRST);
9873 ADD_INT(d, DB_FLUSH);
9874 ADD_INT(d, DB_GET_BOTH);
Jesus Cea6557aac2010-03-22 14:22:26 +00009875 ADD_INT(d, DB_GET_BOTH_RANGE);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009876 ADD_INT(d, DB_GET_RECNO);
9877 ADD_INT(d, DB_JOIN_ITEM);
9878 ADD_INT(d, DB_KEYFIRST);
9879 ADD_INT(d, DB_KEYLAST);
9880 ADD_INT(d, DB_LAST);
9881 ADD_INT(d, DB_NEXT);
9882 ADD_INT(d, DB_NEXT_DUP);
9883 ADD_INT(d, DB_NEXT_NODUP);
9884 ADD_INT(d, DB_NODUPDATA);
9885 ADD_INT(d, DB_NOOVERWRITE);
9886 ADD_INT(d, DB_NOSYNC);
9887 ADD_INT(d, DB_POSITION);
9888 ADD_INT(d, DB_PREV);
9889 ADD_INT(d, DB_PREV_NODUP);
Jesus Cea6557aac2010-03-22 14:22:26 +00009890#if (DBVER >= 46)
9891 ADD_INT(d, DB_PREV_DUP);
9892#endif
Gregory P. Smith8b96a352007-01-05 01:59:42 +00009893#if (DBVER < 45)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009894 ADD_INT(d, DB_RECORDCOUNT);
Gregory P. Smith8b96a352007-01-05 01:59:42 +00009895#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009896 ADD_INT(d, DB_SET);
9897 ADD_INT(d, DB_SET_RANGE);
9898 ADD_INT(d, DB_SET_RECNO);
9899 ADD_INT(d, DB_WRITECURSOR);
9900
9901 ADD_INT(d, DB_OPFLAGS_MASK);
9902 ADD_INT(d, DB_RMW);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009903 ADD_INT(d, DB_DIRTY_READ);
9904 ADD_INT(d, DB_MULTIPLE);
9905 ADD_INT(d, DB_MULTIPLE_KEY);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009906
Gregory P. Smith29602d22006-01-24 09:46:48 +00009907#if (DBVER >= 44)
Jesus Cea6557aac2010-03-22 14:22:26 +00009908 ADD_INT(d, DB_IMMUTABLE_KEY);
Gregory P. Smith29602d22006-01-24 09:46:48 +00009909 ADD_INT(d, DB_READ_UNCOMMITTED); /* replaces DB_DIRTY_READ in 4.4 */
9910 ADD_INT(d, DB_READ_COMMITTED);
9911#endif
9912
Jesus Cea6557aac2010-03-22 14:22:26 +00009913#if (DBVER >= 44)
9914 ADD_INT(d, DB_FREELIST_ONLY);
9915 ADD_INT(d, DB_FREE_SPACE);
9916#endif
9917
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009918 ADD_INT(d, DB_DONOTINDEX);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009919
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009920 ADD_INT(d, DB_KEYEMPTY);
9921 ADD_INT(d, DB_KEYEXIST);
9922 ADD_INT(d, DB_LOCK_DEADLOCK);
9923 ADD_INT(d, DB_LOCK_NOTGRANTED);
9924 ADD_INT(d, DB_NOSERVER);
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009925#if (DBVER < 52)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009926 ADD_INT(d, DB_NOSERVER_HOME);
9927 ADD_INT(d, DB_NOSERVER_ID);
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009928#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009929 ADD_INT(d, DB_NOTFOUND);
9930 ADD_INT(d, DB_OLD_VERSION);
9931 ADD_INT(d, DB_RUNRECOVERY);
9932 ADD_INT(d, DB_VERIFY_BAD);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009933 ADD_INT(d, DB_PAGE_NOTFOUND);
9934 ADD_INT(d, DB_SECONDARY_BAD);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009935 ADD_INT(d, DB_STAT_CLEAR);
9936 ADD_INT(d, DB_REGION_INIT);
9937 ADD_INT(d, DB_NOLOCKING);
9938 ADD_INT(d, DB_YIELDCPU);
9939 ADD_INT(d, DB_PANIC_ENVIRONMENT);
9940 ADD_INT(d, DB_NOPANIC);
Jesus Ceaef9764f2008-05-13 18:45:46 +00009941 ADD_INT(d, DB_OVERWRITE);
Jesus Cea6557aac2010-03-22 14:22:26 +00009942
Jesus Cea6557aac2010-03-22 14:22:26 +00009943 ADD_INT(d, DB_STAT_SUBSYSTEM);
9944 ADD_INT(d, DB_STAT_MEMP_HASH);
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009945 ADD_INT(d, DB_STAT_LOCK_CONF);
9946 ADD_INT(d, DB_STAT_LOCK_LOCKERS);
9947 ADD_INT(d, DB_STAT_LOCK_OBJECTS);
9948 ADD_INT(d, DB_STAT_LOCK_PARAMS);
Jesus Ceaef9764f2008-05-13 18:45:46 +00009949
Jesus Cea6557aac2010-03-22 14:22:26 +00009950#if (DBVER >= 48)
9951 ADD_INT(d, DB_OVERWRITE_DUP);
9952#endif
9953
9954#if (DBVER >= 47)
9955 ADD_INT(d, DB_FOREIGN_ABORT);
9956 ADD_INT(d, DB_FOREIGN_CASCADE);
9957 ADD_INT(d, DB_FOREIGN_NULLIFY);
9958#endif
9959
9960#if (DBVER >= 44)
Gregory P. Smithaae141a2007-11-01 21:08:14 +00009961 ADD_INT(d, DB_REGISTER);
9962#endif
9963
Jesus Cea6557aac2010-03-22 14:22:26 +00009964 ADD_INT(d, DB_EID_INVALID);
9965 ADD_INT(d, DB_EID_BROADCAST);
9966
Gregory P. Smith41631e82003-09-21 00:08:14 +00009967 ADD_INT(d, DB_TIME_NOTGRANTED);
9968 ADD_INT(d, DB_TXN_NOT_DURABLE);
9969 ADD_INT(d, DB_TXN_WRITE_NOSYNC);
Gregory P. Smith41631e82003-09-21 00:08:14 +00009970 ADD_INT(d, DB_DIRECT_DB);
9971 ADD_INT(d, DB_INIT_REP);
9972 ADD_INT(d, DB_ENCRYPT);
9973 ADD_INT(d, DB_CHKSUM);
Gregory P. Smith41631e82003-09-21 00:08:14 +00009974
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009975#if (DBVER < 47)
Jesus Ceaca3939c2008-05-22 15:27:38 +00009976 ADD_INT(d, DB_LOG_AUTOREMOVE);
9977 ADD_INT(d, DB_DIRECT_LOG);
9978#endif
9979
9980#if (DBVER >= 47)
9981 ADD_INT(d, DB_LOG_DIRECT);
9982 ADD_INT(d, DB_LOG_DSYNC);
9983 ADD_INT(d, DB_LOG_IN_MEMORY);
9984 ADD_INT(d, DB_LOG_AUTO_REMOVE);
9985 ADD_INT(d, DB_LOG_ZERO);
9986#endif
9987
Jesus Ceaef9764f2008-05-13 18:45:46 +00009988#if (DBVER >= 44)
9989 ADD_INT(d, DB_DSYNC_DB);
9990#endif
9991
9992#if (DBVER >= 45)
9993 ADD_INT(d, DB_TXN_SNAPSHOT);
9994#endif
9995
Jesus Ceaef9764f2008-05-13 18:45:46 +00009996 ADD_INT(d, DB_VERB_DEADLOCK);
9997#if (DBVER >= 46)
9998 ADD_INT(d, DB_VERB_FILEOPS);
9999 ADD_INT(d, DB_VERB_FILEOPS_ALL);
10000#endif
10001 ADD_INT(d, DB_VERB_RECOVERY);
10002#if (DBVER >= 44)
10003 ADD_INT(d, DB_VERB_REGISTER);
10004#endif
10005 ADD_INT(d, DB_VERB_REPLICATION);
10006 ADD_INT(d, DB_VERB_WAITSFOR);
Jesus Ceaef9764f2008-05-13 18:45:46 +000010007
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010008#if (DBVER >= 50)
10009 ADD_INT(d, DB_VERB_REP_SYSTEM);
10010#endif
10011
10012#if (DBVER >= 47)
10013 ADD_INT(d, DB_VERB_REP_ELECT);
10014 ADD_INT(d, DB_VERB_REP_LEASE);
10015 ADD_INT(d, DB_VERB_REP_MISC);
10016 ADD_INT(d, DB_VERB_REP_MSGS);
10017 ADD_INT(d, DB_VERB_REP_SYNC);
10018 ADD_INT(d, DB_VERB_REPMGR_CONNFAIL);
10019 ADD_INT(d, DB_VERB_REPMGR_MISC);
10020#endif
10021
Jesus Ceaef9764f2008-05-13 18:45:46 +000010022#if (DBVER >= 45)
10023 ADD_INT(d, DB_EVENT_PANIC);
10024 ADD_INT(d, DB_EVENT_REP_CLIENT);
10025#if (DBVER >= 46)
10026 ADD_INT(d, DB_EVENT_REP_ELECTED);
10027#endif
10028 ADD_INT(d, DB_EVENT_REP_MASTER);
10029 ADD_INT(d, DB_EVENT_REP_NEWMASTER);
10030#if (DBVER >= 46)
10031 ADD_INT(d, DB_EVENT_REP_PERM_FAILED);
10032#endif
10033 ADD_INT(d, DB_EVENT_REP_STARTUPDONE);
10034 ADD_INT(d, DB_EVENT_WRITE_FAILED);
10035#endif
10036
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010037#if (DBVER >= 50)
10038 ADD_INT(d, DB_REPMGR_CONF_ELECTIONS);
10039 ADD_INT(d, DB_EVENT_REP_MASTER_FAILURE);
10040 ADD_INT(d, DB_EVENT_REP_DUPMASTER);
10041 ADD_INT(d, DB_EVENT_REP_ELECTION_FAILED);
10042#endif
10043#if (DBVER >= 48)
10044 ADD_INT(d, DB_EVENT_REG_ALIVE);
10045 ADD_INT(d, DB_EVENT_REG_PANIC);
10046#endif
10047
10048#if (DBVER >=52)
10049 ADD_INT(d, DB_EVENT_REP_SITE_ADDED);
10050 ADD_INT(d, DB_EVENT_REP_SITE_REMOVED);
10051 ADD_INT(d, DB_EVENT_REP_LOCAL_SITE_REMOVED);
10052 ADD_INT(d, DB_EVENT_REP_CONNECT_BROKEN);
10053 ADD_INT(d, DB_EVENT_REP_CONNECT_ESTD);
10054 ADD_INT(d, DB_EVENT_REP_CONNECT_TRY_FAILED);
10055 ADD_INT(d, DB_EVENT_REP_INIT_DONE);
10056
10057 ADD_INT(d, DB_MEM_LOCK);
10058 ADD_INT(d, DB_MEM_LOCKOBJECT);
10059 ADD_INT(d, DB_MEM_LOCKER);
10060 ADD_INT(d, DB_MEM_LOGID);
10061 ADD_INT(d, DB_MEM_TRANSACTION);
10062 ADD_INT(d, DB_MEM_THREAD);
10063
10064 ADD_INT(d, DB_BOOTSTRAP_HELPER);
10065 ADD_INT(d, DB_GROUP_CREATOR);
10066 ADD_INT(d, DB_LEGACY);
10067 ADD_INT(d, DB_LOCAL_SITE);
10068 ADD_INT(d, DB_REPMGR_PEER);
10069#endif
10070
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010071 ADD_INT(d, DB_REP_DUPMASTER);
10072 ADD_INT(d, DB_REP_HOLDELECTION);
10073#if (DBVER >= 44)
10074 ADD_INT(d, DB_REP_IGNORE);
10075 ADD_INT(d, DB_REP_JOIN_FAILURE);
10076#endif
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010077 ADD_INT(d, DB_REP_ISPERM);
10078 ADD_INT(d, DB_REP_NOTPERM);
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010079 ADD_INT(d, DB_REP_NEWSITE);
10080
Jesus Ceaef9764f2008-05-13 18:45:46 +000010081 ADD_INT(d, DB_REP_MASTER);
10082 ADD_INT(d, DB_REP_CLIENT);
Jesus Cea6557aac2010-03-22 14:22:26 +000010083
10084 ADD_INT(d, DB_REP_PERMANENT);
10085
10086#if (DBVER >= 44)
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010087#if (DBVER >= 50)
10088 ADD_INT(d, DB_REP_CONF_AUTOINIT);
10089#else
Jesus Cea6557aac2010-03-22 14:22:26 +000010090 ADD_INT(d, DB_REP_CONF_NOAUTOINIT);
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010091#endif /* 5.0 */
10092#endif /* 4.4 */
10093#if (DBVER >= 44)
Jesus Cea6557aac2010-03-22 14:22:26 +000010094 ADD_INT(d, DB_REP_CONF_DELAYCLIENT);
10095 ADD_INT(d, DB_REP_CONF_BULK);
10096 ADD_INT(d, DB_REP_CONF_NOWAIT);
10097 ADD_INT(d, DB_REP_ANYWHERE);
10098 ADD_INT(d, DB_REP_REREQUEST);
10099#endif
10100
Jesus Cea6557aac2010-03-22 14:22:26 +000010101 ADD_INT(d, DB_REP_NOBUFFER);
Jesus Cea6557aac2010-03-22 14:22:26 +000010102
10103#if (DBVER >= 46)
10104 ADD_INT(d, DB_REP_LEASE_EXPIRED);
10105 ADD_INT(d, DB_IGNORE_LEASE);
10106#endif
10107
10108#if (DBVER >= 47)
10109 ADD_INT(d, DB_REP_CONF_LEASE);
10110 ADD_INT(d, DB_REPMGR_CONF_2SITE_STRICT);
10111#endif
10112
Jesus Ceaef9764f2008-05-13 18:45:46 +000010113#if (DBVER >= 45)
10114 ADD_INT(d, DB_REP_ELECTION);
10115
10116 ADD_INT(d, DB_REP_ACK_TIMEOUT);
10117 ADD_INT(d, DB_REP_CONNECTION_RETRY);
10118 ADD_INT(d, DB_REP_ELECTION_TIMEOUT);
10119 ADD_INT(d, DB_REP_ELECTION_RETRY);
10120#endif
10121#if (DBVER >= 46)
10122 ADD_INT(d, DB_REP_CHECKPOINT_DELAY);
10123 ADD_INT(d, DB_REP_FULL_ELECTION_TIMEOUT);
Jesus Cea6557aac2010-03-22 14:22:26 +000010124 ADD_INT(d, DB_REP_LEASE_TIMEOUT);
10125#endif
10126#if (DBVER >= 47)
10127 ADD_INT(d, DB_REP_HEARTBEAT_MONITOR);
10128 ADD_INT(d, DB_REP_HEARTBEAT_SEND);
Jesus Ceaef9764f2008-05-13 18:45:46 +000010129#endif
Jesus Ceaef9764f2008-05-13 18:45:46 +000010130
10131#if (DBVER >= 45)
10132 ADD_INT(d, DB_REPMGR_PEER);
10133 ADD_INT(d, DB_REPMGR_ACKS_ALL);
10134 ADD_INT(d, DB_REPMGR_ACKS_ALL_PEERS);
10135 ADD_INT(d, DB_REPMGR_ACKS_NONE);
10136 ADD_INT(d, DB_REPMGR_ACKS_ONE);
10137 ADD_INT(d, DB_REPMGR_ACKS_ONE_PEER);
10138 ADD_INT(d, DB_REPMGR_ACKS_QUORUM);
10139 ADD_INT(d, DB_REPMGR_CONNECTED);
10140 ADD_INT(d, DB_REPMGR_DISCONNECTED);
Jesus Ceaef9764f2008-05-13 18:45:46 +000010141 ADD_INT(d, DB_STAT_ALL);
10142#endif
10143
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010144#if (DBVER >= 51)
10145 ADD_INT(d, DB_REPMGR_ACKS_ALL_AVAILABLE);
10146#endif
10147
10148#if (DBVER >= 48)
10149 ADD_INT(d, DB_REP_CONF_INMEM);
10150#endif
10151
10152 ADD_INT(d, DB_TIMEOUT);
10153
10154#if (DBVER >= 50)
10155 ADD_INT(d, DB_FORCESYNC);
10156#endif
10157
10158#if (DBVER >= 48)
10159 ADD_INT(d, DB_FAILCHK);
10160#endif
10161
10162#if (DBVER >= 51)
10163 ADD_INT(d, DB_HOTBACKUP_IN_PROGRESS);
10164#endif
10165
Gregory P. Smith8b7e9172004-12-13 09:51:23 +000010166 ADD_INT(d, DB_BUFFER_SMALL);
Gregory P. Smithf0547d02006-06-05 17:38:04 +000010167 ADD_INT(d, DB_SEQ_DEC);
10168 ADD_INT(d, DB_SEQ_INC);
10169 ADD_INT(d, DB_SEQ_WRAP);
Gregory P. Smith8b7e9172004-12-13 09:51:23 +000010170
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010171#if (DBVER < 47)
Jesus Ceaca3939c2008-05-22 15:27:38 +000010172 ADD_INT(d, DB_LOG_INMEMORY);
10173 ADD_INT(d, DB_DSYNC_LOG);
10174#endif
10175
Barry Warsaw9a0d7792002-12-30 20:53:52 +000010176 ADD_INT(d, DB_ENCRYPT_AES);
10177 ADD_INT(d, DB_AUTO_COMMIT);
Jesus Cea6557aac2010-03-22 14:22:26 +000010178 ADD_INT(d, DB_PRIORITY_VERY_LOW);
10179 ADD_INT(d, DB_PRIORITY_LOW);
10180 ADD_INT(d, DB_PRIORITY_DEFAULT);
10181 ADD_INT(d, DB_PRIORITY_HIGH);
10182 ADD_INT(d, DB_PRIORITY_VERY_HIGH);
10183
10184#if (DBVER >= 46)
10185 ADD_INT(d, DB_PRIORITY_UNCHANGED);
Barry Warsaw9a0d7792002-12-30 20:53:52 +000010186#endif
10187
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010188 ADD_INT(d, EINVAL);
10189 ADD_INT(d, EACCES);
10190 ADD_INT(d, ENOSPC);
10191 ADD_INT(d, ENOMEM);
10192 ADD_INT(d, EAGAIN);
10193 ADD_INT(d, EBUSY);
10194 ADD_INT(d, EEXIST);
10195 ADD_INT(d, ENOENT);
10196 ADD_INT(d, EPERM);
10197
Barry Warsaw1baa9822003-03-31 19:51:29 +000010198 ADD_INT(d, DB_SET_LOCK_TIMEOUT);
10199 ADD_INT(d, DB_SET_TXN_TIMEOUT);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010200
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010201#if (DBVER >= 48)
10202 ADD_INT(d, DB_SET_REG_TIMEOUT);
10203#endif
10204
Gregory P. Smith7f5b6f42006-04-08 07:10:51 +000010205 /* The exception name must be correct for pickled exception *
10206 * objects to unpickle properly. */
10207#ifdef PYBSDDB_STANDALONE /* different value needed for standalone pybsddb */
10208#define PYBSDDB_EXCEPTION_BASE "bsddb3.db."
10209#else
10210#define PYBSDDB_EXCEPTION_BASE "bsddb.db."
10211#endif
10212
10213 /* All the rest of the exceptions derive only from DBError */
10214#define MAKE_EX(name) name = PyErr_NewException(PYBSDDB_EXCEPTION_BASE #name, DBError, NULL); \
10215 PyDict_SetItemString(d, #name, name)
10216
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010217 /* The base exception class is DBError */
Gregory P. Smith7f5b6f42006-04-08 07:10:51 +000010218 DBError = NULL; /* used in MAKE_EX so that it derives from nothing */
10219 MAKE_EX(DBError);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010220
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010221#if (PY_VERSION_HEX < 0x03000000)
Gregory P. Smithe9477062005-06-04 06:46:59 +000010222 /* Some magic to make DBNotFoundError and DBKeyEmptyError derive
10223 * from both DBError and KeyError, since the API only supports
10224 * using one base class. */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010225 PyDict_SetItemString(d, "KeyError", PyExc_KeyError);
Gregory P. Smithe9477062005-06-04 06:46:59 +000010226 PyRun_String("class DBNotFoundError(DBError, KeyError): pass\n"
Antoine Pitrouc83ea132010-05-09 14:46:46 +000010227 "class DBKeyEmptyError(DBError, KeyError): pass",
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010228 Py_file_input, d, d);
10229 DBNotFoundError = PyDict_GetItemString(d, "DBNotFoundError");
Gregory P. Smithe9477062005-06-04 06:46:59 +000010230 DBKeyEmptyError = PyDict_GetItemString(d, "DBKeyEmptyError");
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010231 PyDict_DelItemString(d, "KeyError");
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010232#else
10233 /* Since Python 2.5, PyErr_NewException() accepts a tuple, to be able to
10234 ** derive from several classes. We use this new API only for Python 3.0,
10235 ** though.
10236 */
10237 {
10238 PyObject* bases;
10239
10240 bases = PyTuple_Pack(2, DBError, PyExc_KeyError);
10241
10242#define MAKE_EX2(name) name = PyErr_NewException(PYBSDDB_EXCEPTION_BASE #name, bases, NULL); \
10243 PyDict_SetItemString(d, #name, name)
10244 MAKE_EX2(DBNotFoundError);
10245 MAKE_EX2(DBKeyEmptyError);
10246
10247#undef MAKE_EX2
10248
10249 Py_XDECREF(bases);
10250 }
10251#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010252
Gregory P. Smithe2767172003-11-02 08:06:29 +000010253 MAKE_EX(DBCursorClosedError);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010254 MAKE_EX(DBKeyExistError);
10255 MAKE_EX(DBLockDeadlockError);
10256 MAKE_EX(DBLockNotGrantedError);
10257 MAKE_EX(DBOldVersionError);
10258 MAKE_EX(DBRunRecoveryError);
10259 MAKE_EX(DBVerifyBadError);
10260 MAKE_EX(DBNoServerError);
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010261#if (DBVER < 52)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010262 MAKE_EX(DBNoServerHomeError);
10263 MAKE_EX(DBNoServerIDError);
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010264#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010265 MAKE_EX(DBPageNotFoundError);
10266 MAKE_EX(DBSecondaryBadError);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010267
10268 MAKE_EX(DBInvalidArgError);
10269 MAKE_EX(DBAccessError);
10270 MAKE_EX(DBNoSpaceError);
10271 MAKE_EX(DBNoMemoryError);
10272 MAKE_EX(DBAgainError);
10273 MAKE_EX(DBBusyError);
10274 MAKE_EX(DBFileExistsError);
10275 MAKE_EX(DBNoSuchFileError);
10276 MAKE_EX(DBPermissionsError);
10277
Jesus Ceaef9764f2008-05-13 18:45:46 +000010278 MAKE_EX(DBRepHandleDeadError);
Jesus Cea6557aac2010-03-22 14:22:26 +000010279#if (DBVER >= 44)
10280 MAKE_EX(DBRepLockoutError);
10281#endif
Jesus Ceaef9764f2008-05-13 18:45:46 +000010282
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010283 MAKE_EX(DBRepUnavailError);
10284
Jesus Cea6557aac2010-03-22 14:22:26 +000010285#if (DBVER >= 46)
10286 MAKE_EX(DBRepLeaseExpiredError);
10287#endif
10288
10289#if (DBVER >= 47)
10290 MAKE_EX(DBForeignConflictError);
10291#endif
10292
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010293#undef MAKE_EX
10294
Jesus Cea6557aac2010-03-22 14:22:26 +000010295 /* Initialise the C API structure and add it to the module */
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010296 bsddb_api.api_version = PYBSDDB_API_VERSION;
Jesus Cea6557aac2010-03-22 14:22:26 +000010297 bsddb_api.db_type = &DB_Type;
10298 bsddb_api.dbcursor_type = &DBCursor_Type;
10299 bsddb_api.dblogcursor_type = &DBLogCursor_Type;
10300 bsddb_api.dbenv_type = &DBEnv_Type;
10301 bsddb_api.dbtxn_type = &DBTxn_Type;
10302 bsddb_api.dblock_type = &DBLock_Type;
Jesus Cea6557aac2010-03-22 14:22:26 +000010303 bsddb_api.dbsequence_type = &DBSequence_Type;
Jesus Cea6557aac2010-03-22 14:22:26 +000010304 bsddb_api.makeDBError = makeDBError;
Gregory P. Smith39250532007-10-09 06:02:21 +000010305
Jesus Cea6557aac2010-03-22 14:22:26 +000010306 /*
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010307 ** Capsules exist from Python 2.7 and 3.1.
10308 ** We don't support Python 3.0 anymore, so...
10309 ** #if (PY_VERSION_HEX < ((PY_MAJOR_VERSION < 3) ? 0x02070000 : 0x03020000))
Jesus Cea6557aac2010-03-22 14:22:26 +000010310 */
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010311#if (PY_VERSION_HEX < 0x02070000)
Gregory P. Smith39250532007-10-09 06:02:21 +000010312 py_api = PyCObject_FromVoidPtr((void*)&bsddb_api, NULL);
Jesus Cea6557aac2010-03-22 14:22:26 +000010313#else
10314 {
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010315 /*
10316 ** The data must outlive the call!!. So, the static definition.
10317 ** The buffer must be big enough...
10318 */
10319 static char py_api_name[MODULE_NAME_MAX_LEN+10];
Jesus Cea6557aac2010-03-22 14:22:26 +000010320
10321 strcpy(py_api_name, _bsddbModuleName);
10322 strcat(py_api_name, ".api");
10323
10324 py_api = PyCapsule_New((void*)&bsddb_api, py_api_name, NULL);
10325 }
10326#endif
10327
Jesus Cea84f2c322010-11-05 00:13:50 +000010328 /* Check error control */
10329 /*
10330 ** PyErr_NoMemory();
10331 ** py_api = NULL;
10332 */
10333
10334 if (py_api) {
10335 PyDict_SetItemString(d, "api", py_api);
10336 Py_DECREF(py_api);
10337 } else { /* Something bad happened */
10338 PyErr_WriteUnraisable(m);
Jesus Ceabf088f82010-11-08 12:57:59 +000010339 if(PyErr_Warn(PyExc_RuntimeWarning,
10340 "_bsddb/_pybsddb C API will be not available")) {
10341 PyErr_WriteUnraisable(m);
10342 }
Jesus Cea84f2c322010-11-05 00:13:50 +000010343 PyErr_Clear();
10344 }
Gregory P. Smith39250532007-10-09 06:02:21 +000010345
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010346 /* Check for errors */
10347 if (PyErr_Occurred()) {
10348 PyErr_Print();
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010349 Py_FatalError("can't initialize module _bsddb/_pybsddb");
10350 Py_DECREF(m);
10351 m = NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010352 }
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010353#if (PY_VERSION_HEX < 0x03000000)
10354 return;
10355#else
10356 return m;
10357#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010358}
Gregory P. Smith41631e82003-09-21 00:08:14 +000010359
10360/* allow this module to be named _pybsddb so that it can be installed
10361 * and imported on top of python >= 2.3 that includes its own older
10362 * copy of the library named _bsddb without importing the old version. */
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010363#if (PY_VERSION_HEX < 0x03000000)
Gregory P. Smith41631e82003-09-21 00:08:14 +000010364DL_EXPORT(void) init_pybsddb(void)
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010365#else
10366PyMODINIT_FUNC PyInit__pybsddb(void) /* Note the two underscores */
10367#endif
Gregory P. Smith41631e82003-09-21 00:08:14 +000010368{
10369 strncpy(_bsddbModuleName, "_pybsddb", MODULE_NAME_MAX_LEN);
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010370#if (PY_VERSION_HEX < 0x03000000)
Gregory P. Smith41631e82003-09-21 00:08:14 +000010371 init_bsddb();
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010372#else
10373 return PyInit__bsddb(); /* Note the two underscores */
10374#endif
Gregory P. Smith41631e82003-09-21 00:08:14 +000010375}