blob: 9c81ec5217f3b4a69932cbfd3d5ccb8dac7ec830 [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;
1506 Py_ssize_t size;
1507 int i, listlen;
1508 DBT* dbts;
1509
1510 listlen = PyList_Size(result);
1511
1512 dbts = (DBT *)malloc(sizeof(DBT) * listlen);
1513
1514 for (i=0; i<listlen; i++)
1515 {
1516 if (!PyBytes_Check(PyList_GetItem(result, i)))
1517 {
1518 PyErr_SetString(
1519 PyExc_TypeError,
1520#if (PY_VERSION_HEX < 0x03000000)
1521"The list returned by DB->associate callback should be a list of strings.");
1522#else
1523"The list returned by DB->associate callback should be a list of bytes.");
1524#endif
1525 PyErr_Print();
1526 }
1527
1528 PyBytes_AsStringAndSize(
1529 PyList_GetItem(result, i),
1530 &data, &size);
1531
1532 CLEAR_DBT(dbts[i]);
1533 dbts[i].data = malloc(size); /* TODO, check this */
1534
1535 if (dbts[i].data)
1536 {
1537 memcpy(dbts[i].data, data, size);
1538 dbts[i].size = size;
1539 dbts[i].ulen = dbts[i].size;
1540 dbts[i].flags = DB_DBT_APPMALLOC; /* DB will free */
1541 }
1542 else
1543 {
1544 PyErr_SetString(PyExc_MemoryError,
1545 "malloc failed in _db_associateCallback (list)");
1546 PyErr_Print();
1547 }
1548 }
1549
1550 CLEAR_DBT(*secKey);
1551
1552 secKey->data = dbts;
1553 secKey->size = listlen;
1554 secKey->flags = DB_DBT_APPMALLOC | DB_DBT_MULTIPLE;
1555 retval = 0;
1556 }
1557#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001558 else {
Barry Warsaw9a0d7792002-12-30 20:53:52 +00001559 PyErr_SetString(
1560 PyExc_TypeError,
Jesus Cea6557aac2010-03-22 14:22:26 +00001561#if (PY_VERSION_HEX < 0x03000000)
1562"DB associate callback should return DB_DONOTINDEX/string/list of strings.");
1563#else
1564"DB associate callback should return DB_DONOTINDEX/bytes/list of bytes.");
1565#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001566 PyErr_Print();
1567 }
1568
Thomas Woutersb3153832006-03-08 01:47:19 +00001569 Py_XDECREF(args);
1570 Py_XDECREF(result);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001571
1572 MYDB_END_BLOCK_THREADS;
1573 }
1574 return retval;
1575}
1576
1577
1578static PyObject*
1579DB_associate(DBObject* self, PyObject* args, PyObject* kwargs)
1580{
1581 int err, flags=0;
1582 DBObject* secondaryDB;
1583 PyObject* callback;
Barry Warsaw9a0d7792002-12-30 20:53:52 +00001584 PyObject *txnobj = NULL;
1585 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00001586 static char* kwnames[] = {"secondaryDB", "callback", "flags", "txn",
Jeremy Hyltonaf68c872005-12-10 18:50:16 +00001587 NULL};
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001588
Barry Warsaw9a0d7792002-12-30 20:53:52 +00001589 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|iO:associate", kwnames,
1590 &secondaryDB, &callback, &flags,
1591 &txnobj)) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001592 return NULL;
Barry Warsaw9a0d7792002-12-30 20:53:52 +00001593 }
1594
Barry Warsaw9a0d7792002-12-30 20:53:52 +00001595 if (!checkTxnObj(txnobj, &txn)) return NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001596
1597 CHECK_DB_NOT_CLOSED(self);
1598 if (!DBObject_Check(secondaryDB)) {
1599 makeTypeError("DB", (PyObject*)secondaryDB);
1600 return NULL;
1601 }
Gregory P. Smith91116b62005-06-06 10:28:06 +00001602 CHECK_DB_NOT_CLOSED(secondaryDB);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001603 if (callback == Py_None) {
1604 callback = NULL;
1605 }
1606 else if (!PyCallable_Check(callback)) {
1607 makeTypeError("Callable", callback);
1608 return NULL;
1609 }
1610
1611 /* Save a reference to the callback in the secondary DB. */
Thomas Woutersb3153832006-03-08 01:47:19 +00001612 Py_XINCREF(callback);
Serhiy Storchakabc62af12016-04-06 09:51:18 +03001613 Py_XSETREF(secondaryDB->associateCallback, callback);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001614 secondaryDB->primaryDBType = _DB_get_type(self);
1615
Martin v. Löwisb2c7aff2002-11-23 11:26:07 +00001616 /* PyEval_InitThreads is called here due to a quirk in python 1.5
1617 * - 2.2.1 (at least) according to Russell Williamson <merel@wt.net>:
1618 * The global interepreter lock is not initialized until the first
1619 * thread is created using thread.start_new_thread() or fork() is
1620 * called. that would cause the ALLOW_THREADS here to segfault due
1621 * to a null pointer reference if no threads or child processes
1622 * have been created. This works around that and is a no-op if
1623 * threads have already been initialized.
1624 * (see pybsddb-users mailing list post on 2002-08-07)
1625 */
Gregory P. Smithaa71f5f2003-01-17 07:56:16 +00001626#ifdef WITH_THREAD
Martin v. Löwisb2c7aff2002-11-23 11:26:07 +00001627 PyEval_InitThreads();
Gregory P. Smithaa71f5f2003-01-17 07:56:16 +00001628#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001629 MYDB_BEGIN_ALLOW_THREADS;
Barry Warsaw9a0d7792002-12-30 20:53:52 +00001630 err = self->db->associate(self->db,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001631 txn,
Barry Warsaw9a0d7792002-12-30 20:53:52 +00001632 secondaryDB->db,
1633 _db_associateCallback,
1634 flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001635 MYDB_END_ALLOW_THREADS;
1636
1637 if (err) {
Serhiy Storchaka98a97222014-02-09 13:14:04 +02001638 Py_CLEAR(secondaryDB->associateCallback);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001639 secondaryDB->primaryDBType = 0;
1640 }
1641
1642 RETURN_IF_ERR();
1643 RETURN_NONE();
1644}
1645
1646
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001647static PyObject*
Jesus Cea5cd5f122008-09-23 18:54:08 +00001648DB_close_internal(DBObject* self, int flags, int do_not_close)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001649{
Jesus Ceaef9764f2008-05-13 18:45:46 +00001650 PyObject *dummy;
Jesus Cea5cd5f122008-09-23 18:54:08 +00001651 int err = 0;
Jesus Ceaef9764f2008-05-13 18:45:46 +00001652
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001653 if (self->db != NULL) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00001654 /* Can be NULL if db is not in an environment */
1655 EXTRACT_FROM_DOUBLE_LINKED_LIST_MAYBE_NULL(self);
Jesus Cea4907d272008-08-31 14:00:51 +00001656
Jesus Ceaef9764f2008-05-13 18:45:46 +00001657 if (self->txn) {
1658 EXTRACT_FROM_DOUBLE_LINKED_LIST_TXN(self);
1659 self->txn=NULL;
1660 }
1661
1662 while(self->children_cursors) {
1663 dummy=DBC_close_internal(self->children_cursors);
1664 Py_XDECREF(dummy);
1665 }
1666
Jesus Ceaef9764f2008-05-13 18:45:46 +00001667 while(self->children_sequences) {
1668 dummy=DBSequence_close_internal(self->children_sequences,0,0);
1669 Py_XDECREF(dummy);
1670 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00001671
Jesus Cea5cd5f122008-09-23 18:54:08 +00001672 /*
1673 ** "do_not_close" is used to dispose all related objects in the
1674 ** tree, without actually releasing the "root" object.
1675 ** This is done, for example, because function calls like
1676 ** "DB.verify()" implicitly close the underlying handle. So
1677 ** the handle doesn't need to be closed, but related objects
1678 ** must be cleaned up.
1679 */
1680 if (!do_not_close) {
1681 MYDB_BEGIN_ALLOW_THREADS;
1682 err = self->db->close(self->db, flags);
1683 MYDB_END_ALLOW_THREADS;
1684 self->db = NULL;
1685 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001686 RETURN_IF_ERR();
1687 }
1688 RETURN_NONE();
1689}
1690
Jesus Ceaef9764f2008-05-13 18:45:46 +00001691static PyObject*
1692DB_close(DBObject* self, PyObject* args)
1693{
1694 int flags=0;
1695 if (!PyArg_ParseTuple(args,"|i:close", &flags))
1696 return NULL;
Jesus Cea5cd5f122008-09-23 18:54:08 +00001697 return DB_close_internal(self, flags, 0);
Jesus Ceaef9764f2008-05-13 18:45:46 +00001698}
1699
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001700
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001701static PyObject*
1702_DB_consume(DBObject* self, PyObject* args, PyObject* kwargs, int consume_flag)
1703{
1704 int err, flags=0, type;
1705 PyObject* txnobj = NULL;
1706 PyObject* retval = NULL;
1707 DBT key, data;
1708 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00001709 static char* kwnames[] = { "txn", "flags", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001710
1711 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Oi:consume", kwnames,
1712 &txnobj, &flags))
1713 return NULL;
1714
1715 CHECK_DB_NOT_CLOSED(self);
1716 type = _DB_get_type(self);
1717 if (type == -1)
1718 return NULL;
1719 if (type != DB_QUEUE) {
Barry Warsaw9a0d7792002-12-30 20:53:52 +00001720 PyErr_SetString(PyExc_TypeError,
1721 "Consume methods only allowed for Queue DB's");
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001722 return NULL;
1723 }
1724 if (!checkTxnObj(txnobj, &txn))
1725 return NULL;
1726
1727 CLEAR_DBT(key);
1728 CLEAR_DBT(data);
1729 if (CHECK_DBFLAG(self, DB_THREAD)) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00001730 /* Tell Berkeley DB to malloc the return value (thread safe) */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001731 data.flags = DB_DBT_MALLOC;
1732 key.flags = DB_DBT_MALLOC;
1733 }
1734
1735 MYDB_BEGIN_ALLOW_THREADS;
1736 err = self->db->get(self->db, txn, &key, &data, flags|consume_flag);
1737 MYDB_END_ALLOW_THREADS;
1738
Gregory P. Smithe9477062005-06-04 06:46:59 +00001739 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001740 && self->moduleFlags.getReturnsNone) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001741 err = 0;
1742 Py_INCREF(Py_None);
1743 retval = Py_None;
1744 }
1745 else if (!err) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00001746 retval = BuildValue_SS(key.data, key.size, data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001747 FREE_DBT(key);
1748 FREE_DBT(data);
1749 }
1750
1751 RETURN_IF_ERR();
1752 return retval;
1753}
1754
1755static PyObject*
1756DB_consume(DBObject* self, PyObject* args, PyObject* kwargs, int consume_flag)
1757{
1758 return _DB_consume(self, args, kwargs, DB_CONSUME);
1759}
1760
1761static PyObject*
Barry Warsaw9a0d7792002-12-30 20:53:52 +00001762DB_consume_wait(DBObject* self, PyObject* args, PyObject* kwargs,
1763 int consume_flag)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001764{
1765 return _DB_consume(self, args, kwargs, DB_CONSUME_WAIT);
1766}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001767
1768
1769static PyObject*
1770DB_cursor(DBObject* self, PyObject* args, PyObject* kwargs)
1771{
1772 int err, flags=0;
1773 DBC* dbc;
1774 PyObject* txnobj = NULL;
1775 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00001776 static char* kwnames[] = { "txn", "flags", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001777
1778 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Oi:cursor", kwnames,
1779 &txnobj, &flags))
1780 return NULL;
1781 CHECK_DB_NOT_CLOSED(self);
1782 if (!checkTxnObj(txnobj, &txn))
1783 return NULL;
1784
1785 MYDB_BEGIN_ALLOW_THREADS;
1786 err = self->db->cursor(self->db, txn, &dbc, flags);
1787 MYDB_END_ALLOW_THREADS;
1788 RETURN_IF_ERR();
Jesus Ceaef9764f2008-05-13 18:45:46 +00001789 return (PyObject*) newDBCursorObject(dbc, (DBTxnObject *)txnobj, self);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001790}
1791
1792
1793static PyObject*
1794DB_delete(DBObject* self, PyObject* args, PyObject* kwargs)
1795{
1796 PyObject* txnobj = NULL;
1797 int flags = 0;
1798 PyObject* keyobj;
1799 DBT key;
1800 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00001801 static char* kwnames[] = { "key", "txn", "flags", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001802
1803 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|Oi:delete", kwnames,
1804 &keyobj, &txnobj, &flags))
1805 return NULL;
1806 CHECK_DB_NOT_CLOSED(self);
1807 if (!make_key_dbt(self, keyobj, &key, NULL))
1808 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00001809 if (!checkTxnObj(txnobj, &txn)) {
1810 FREE_DBT(key);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001811 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00001812 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001813
Gregory P. Smithdc5af702004-06-27 23:32:34 +00001814 if (-1 == _DB_delete(self, txn, &key, 0)) {
1815 FREE_DBT(key);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001816 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00001817 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001818
1819 FREE_DBT(key);
1820 RETURN_NONE();
1821}
1822
1823
Jesus Cea6557aac2010-03-22 14:22:26 +00001824#if (DBVER >= 47)
1825/*
1826** This function is available since Berkeley DB 4.4,
1827** but 4.6 version is so buggy that we only support
1828** it from BDB 4.7 and newer.
1829*/
1830static PyObject*
1831DB_compact(DBObject* self, PyObject* args, PyObject* kwargs)
1832{
1833 PyObject* txnobj = NULL;
1834 PyObject *startobj = NULL, *stopobj = NULL;
1835 int flags = 0;
1836 DB_TXN *txn = NULL;
1837 DBT *start_p = NULL, *stop_p = NULL;
1838 DBT start, stop;
1839 int err;
1840 DB_COMPACT c_data = { 0 };
1841 static char* kwnames[] = { "txn", "start", "stop", "flags",
1842 "compact_fillpercent", "compact_pages",
1843 "compact_timeout", NULL };
1844
1845
1846 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OOOiiiI:compact", kwnames,
1847 &txnobj, &startobj, &stopobj, &flags,
1848 &c_data.compact_fillpercent,
1849 &c_data.compact_pages,
1850 &c_data.compact_timeout))
1851 return NULL;
1852
1853 CHECK_DB_NOT_CLOSED(self);
1854 if (!checkTxnObj(txnobj, &txn)) {
1855 return NULL;
1856 }
1857
1858 if (startobj && make_key_dbt(self, startobj, &start, NULL)) {
1859 start_p = &start;
1860 }
1861 if (stopobj && make_key_dbt(self, stopobj, &stop, NULL)) {
1862 stop_p = &stop;
1863 }
1864
1865 MYDB_BEGIN_ALLOW_THREADS;
1866 err = self->db->compact(self->db, txn, start_p, stop_p, &c_data,
1867 flags, NULL);
1868 MYDB_END_ALLOW_THREADS;
1869
1870 if (startobj)
1871 FREE_DBT(start);
1872 if (stopobj)
1873 FREE_DBT(stop);
1874
1875 RETURN_IF_ERR();
1876
1877 return PyLong_FromUnsignedLong(c_data.compact_pages_truncated);
1878}
1879#endif
1880
1881
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001882static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00001883DB_fd(DBObject* self)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001884{
1885 int err, the_fd;
1886
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001887 CHECK_DB_NOT_CLOSED(self);
1888
1889 MYDB_BEGIN_ALLOW_THREADS;
1890 err = self->db->fd(self->db, &the_fd);
1891 MYDB_END_ALLOW_THREADS;
1892 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00001893 return NUMBER_FromLong(the_fd);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001894}
1895
1896
Jesus Cea6557aac2010-03-22 14:22:26 +00001897#if (DBVER >= 46)
1898static PyObject*
1899DB_exists(DBObject* self, PyObject* args, PyObject* kwargs)
1900{
1901 int err, flags=0;
1902 PyObject* txnobj = NULL;
1903 PyObject* keyobj;
1904 DBT key;
1905 DB_TXN *txn;
1906
1907 static char* kwnames[] = {"key", "txn", "flags", NULL};
1908
1909 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|Oi:exists", kwnames,
1910 &keyobj, &txnobj, &flags))
1911 return NULL;
1912
1913 CHECK_DB_NOT_CLOSED(self);
1914 if (!make_key_dbt(self, keyobj, &key, NULL))
1915 return NULL;
1916 if (!checkTxnObj(txnobj, &txn)) {
1917 FREE_DBT(key);
1918 return NULL;
1919 }
1920
1921 MYDB_BEGIN_ALLOW_THREADS;
1922 err = self->db->exists(self->db, txn, &key, flags);
1923 MYDB_END_ALLOW_THREADS;
1924
1925 FREE_DBT(key);
1926
1927 if (!err) {
1928 Py_INCREF(Py_True);
1929 return Py_True;
1930 }
1931 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)) {
1932 Py_INCREF(Py_False);
1933 return Py_False;
1934 }
1935
1936 /*
1937 ** If we reach there, there was an error. The
1938 ** "return" should be unreachable.
1939 */
1940 RETURN_IF_ERR();
1941 assert(0); /* This coude SHOULD be unreachable */
1942 return NULL;
1943}
1944#endif
1945
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001946static PyObject*
1947DB_get(DBObject* self, PyObject* args, PyObject* kwargs)
1948{
1949 int err, flags=0;
1950 PyObject* txnobj = NULL;
1951 PyObject* keyobj;
1952 PyObject* dfltobj = NULL;
1953 PyObject* retval = NULL;
1954 int dlen = -1;
1955 int doff = -1;
1956 DBT key, data;
1957 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00001958 static char* kwnames[] = {"key", "default", "txn", "flags", "dlen",
Jeremy Hyltonaf68c872005-12-10 18:50:16 +00001959 "doff", NULL};
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001960
1961 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|OOiii:get", kwnames,
Barry Warsaw9a0d7792002-12-30 20:53:52 +00001962 &keyobj, &dfltobj, &txnobj, &flags, &dlen,
1963 &doff))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001964 return NULL;
1965
1966 CHECK_DB_NOT_CLOSED(self);
1967 if (!make_key_dbt(self, keyobj, &key, &flags))
1968 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00001969 if (!checkTxnObj(txnobj, &txn)) {
1970 FREE_DBT(key);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001971 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00001972 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001973
1974 CLEAR_DBT(data);
1975 if (CHECK_DBFLAG(self, DB_THREAD)) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00001976 /* Tell Berkeley DB to malloc the return value (thread safe) */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001977 data.flags = DB_DBT_MALLOC;
1978 }
Gregory P. Smithdc5af702004-06-27 23:32:34 +00001979 if (!add_partial_dbt(&data, dlen, doff)) {
1980 FREE_DBT(key);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001981 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00001982 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001983
1984 MYDB_BEGIN_ALLOW_THREADS;
1985 err = self->db->get(self->db, txn, &key, &data, flags);
1986 MYDB_END_ALLOW_THREADS;
1987
Gregory P. Smithe9477062005-06-04 06:46:59 +00001988 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY) && (dfltobj != NULL)) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001989 err = 0;
1990 Py_INCREF(dfltobj);
1991 retval = dfltobj;
1992 }
Gregory P. Smithe9477062005-06-04 06:46:59 +00001993 else if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001994 && self->moduleFlags.getReturnsNone) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001995 err = 0;
1996 Py_INCREF(Py_None);
1997 retval = Py_None;
1998 }
1999 else if (!err) {
2000 if (flags & DB_SET_RECNO) /* return both key and data */
Jesus Ceaef9764f2008-05-13 18:45:46 +00002001 retval = BuildValue_SS(key.data, key.size, data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002002 else /* return just the data */
Jesus Ceaef9764f2008-05-13 18:45:46 +00002003 retval = Build_PyString(data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002004 FREE_DBT(data);
2005 }
Gregory P. Smithdc5af702004-06-27 23:32:34 +00002006 FREE_DBT(key);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002007
2008 RETURN_IF_ERR();
2009 return retval;
2010}
2011
Gregory P. Smith19699a92004-06-28 04:06:49 +00002012static PyObject*
2013DB_pget(DBObject* self, PyObject* args, PyObject* kwargs)
2014{
2015 int err, flags=0;
2016 PyObject* txnobj = NULL;
2017 PyObject* keyobj;
2018 PyObject* dfltobj = NULL;
2019 PyObject* retval = NULL;
2020 int dlen = -1;
2021 int doff = -1;
2022 DBT key, pkey, data;
2023 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002024 static char* kwnames[] = {"key", "default", "txn", "flags", "dlen",
Jeremy Hyltonaf68c872005-12-10 18:50:16 +00002025 "doff", NULL};
Gregory P. Smith19699a92004-06-28 04:06:49 +00002026
2027 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|OOiii:pget", kwnames,
2028 &keyobj, &dfltobj, &txnobj, &flags, &dlen,
2029 &doff))
2030 return NULL;
2031
2032 CHECK_DB_NOT_CLOSED(self);
2033 if (!make_key_dbt(self, keyobj, &key, &flags))
2034 return NULL;
2035 if (!checkTxnObj(txnobj, &txn)) {
2036 FREE_DBT(key);
2037 return NULL;
2038 }
2039
2040 CLEAR_DBT(data);
2041 if (CHECK_DBFLAG(self, DB_THREAD)) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00002042 /* Tell Berkeley DB to malloc the return value (thread safe) */
Gregory P. Smith19699a92004-06-28 04:06:49 +00002043 data.flags = DB_DBT_MALLOC;
2044 }
2045 if (!add_partial_dbt(&data, dlen, doff)) {
2046 FREE_DBT(key);
2047 return NULL;
2048 }
2049
2050 CLEAR_DBT(pkey);
2051 pkey.flags = DB_DBT_MALLOC;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002052
Gregory P. Smith19699a92004-06-28 04:06:49 +00002053 MYDB_BEGIN_ALLOW_THREADS;
2054 err = self->db->pget(self->db, txn, &key, &pkey, &data, flags);
2055 MYDB_END_ALLOW_THREADS;
2056
Gregory P. Smithe9477062005-06-04 06:46:59 +00002057 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY) && (dfltobj != NULL)) {
Gregory P. Smith19699a92004-06-28 04:06:49 +00002058 err = 0;
2059 Py_INCREF(dfltobj);
2060 retval = dfltobj;
2061 }
Gregory P. Smithe9477062005-06-04 06:46:59 +00002062 else if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002063 && self->moduleFlags.getReturnsNone) {
Gregory P. Smith19699a92004-06-28 04:06:49 +00002064 err = 0;
2065 Py_INCREF(Py_None);
2066 retval = Py_None;
2067 }
2068 else if (!err) {
2069 PyObject *pkeyObj;
2070 PyObject *dataObj;
Jesus Ceaef9764f2008-05-13 18:45:46 +00002071 dataObj = Build_PyString(data.data, data.size);
Gregory P. Smith19699a92004-06-28 04:06:49 +00002072
2073 if (self->primaryDBType == DB_RECNO ||
2074 self->primaryDBType == DB_QUEUE)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002075 pkeyObj = NUMBER_FromLong(*(int *)pkey.data);
Gregory P. Smith19699a92004-06-28 04:06:49 +00002076 else
Jesus Ceaef9764f2008-05-13 18:45:46 +00002077 pkeyObj = Build_PyString(pkey.data, pkey.size);
Gregory P. Smith19699a92004-06-28 04:06:49 +00002078
2079 if (flags & DB_SET_RECNO) /* return key , pkey and data */
2080 {
2081 PyObject *keyObj;
2082 int type = _DB_get_type(self);
2083 if (type == DB_RECNO || type == DB_QUEUE)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002084 keyObj = NUMBER_FromLong(*(int *)key.data);
Gregory P. Smith19699a92004-06-28 04:06:49 +00002085 else
Jesus Ceaef9764f2008-05-13 18:45:46 +00002086 keyObj = Build_PyString(key.data, key.size);
Gregory P. Smith4e414d82006-01-24 19:55:02 +00002087 retval = PyTuple_Pack(3, keyObj, pkeyObj, dataObj);
Thomas Woutersb3153832006-03-08 01:47:19 +00002088 Py_DECREF(keyObj);
Gregory P. Smith19699a92004-06-28 04:06:49 +00002089 }
2090 else /* return just the pkey and data */
2091 {
Gregory P. Smith4e414d82006-01-24 19:55:02 +00002092 retval = PyTuple_Pack(2, pkeyObj, dataObj);
Gregory P. Smith19699a92004-06-28 04:06:49 +00002093 }
Thomas Woutersb3153832006-03-08 01:47:19 +00002094 Py_DECREF(dataObj);
2095 Py_DECREF(pkeyObj);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002096 FREE_DBT(pkey);
Gregory P. Smith19699a92004-06-28 04:06:49 +00002097 FREE_DBT(data);
2098 }
2099 FREE_DBT(key);
2100
2101 RETURN_IF_ERR();
2102 return retval;
2103}
2104
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002105
2106/* Return size of entry */
2107static PyObject*
2108DB_get_size(DBObject* self, PyObject* args, PyObject* kwargs)
2109{
2110 int err, flags=0;
2111 PyObject* txnobj = NULL;
2112 PyObject* keyobj;
2113 PyObject* retval = NULL;
2114 DBT key, data;
2115 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002116 static char* kwnames[] = { "key", "txn", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002117
2118 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O:get_size", kwnames,
2119 &keyobj, &txnobj))
2120 return NULL;
2121 CHECK_DB_NOT_CLOSED(self);
2122 if (!make_key_dbt(self, keyobj, &key, &flags))
2123 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00002124 if (!checkTxnObj(txnobj, &txn)) {
2125 FREE_DBT(key);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002126 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00002127 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002128 CLEAR_DBT(data);
2129
Gregory P. Smith8b7e9172004-12-13 09:51:23 +00002130 /* We don't allocate any memory, forcing a DB_BUFFER_SMALL error and
2131 thus getting the record size. */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002132 data.flags = DB_DBT_USERMEM;
2133 data.ulen = 0;
2134 MYDB_BEGIN_ALLOW_THREADS;
2135 err = self->db->get(self->db, txn, &key, &data, flags);
2136 MYDB_END_ALLOW_THREADS;
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07002137 if ((err == DB_BUFFER_SMALL) || (err == 0)) {
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002138 retval = NUMBER_FromLong((long)data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002139 err = 0;
2140 }
2141
2142 FREE_DBT(key);
2143 FREE_DBT(data);
2144 RETURN_IF_ERR();
2145 return retval;
2146}
2147
2148
2149static PyObject*
2150DB_get_both(DBObject* self, PyObject* args, PyObject* kwargs)
2151{
2152 int err, flags=0;
2153 PyObject* txnobj = NULL;
2154 PyObject* keyobj;
2155 PyObject* dataobj;
2156 PyObject* retval = NULL;
2157 DBT key, data;
Neal Norwitz994ebed2007-06-03 20:32:50 +00002158 void *orig_data;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002159 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002160 static char* kwnames[] = { "key", "data", "txn", "flags", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002161
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002162 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|Oi:get_both", kwnames,
2163 &keyobj, &dataobj, &txnobj, &flags))
2164 return NULL;
2165
2166 CHECK_DB_NOT_CLOSED(self);
2167 if (!make_key_dbt(self, keyobj, &key, NULL))
2168 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00002169 if ( !make_dbt(dataobj, &data) ||
2170 !checkTxnObj(txnobj, &txn) )
2171 {
2172 FREE_DBT(key);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002173 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00002174 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002175
2176 flags |= DB_GET_BOTH;
Neal Norwitz994ebed2007-06-03 20:32:50 +00002177 orig_data = data.data;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002178
2179 if (CHECK_DBFLAG(self, DB_THREAD)) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00002180 /* Tell Berkeley DB to malloc the return value (thread safe) */
Neal Norwitz994ebed2007-06-03 20:32:50 +00002181 /* XXX(nnorwitz): At least 4.4.20 and 4.5.20 require this flag. */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002182 data.flags = DB_DBT_MALLOC;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002183 }
2184
2185 MYDB_BEGIN_ALLOW_THREADS;
2186 err = self->db->get(self->db, txn, &key, &data, flags);
2187 MYDB_END_ALLOW_THREADS;
2188
Gregory P. Smithe9477062005-06-04 06:46:59 +00002189 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002190 && self->moduleFlags.getReturnsNone) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002191 err = 0;
2192 Py_INCREF(Py_None);
2193 retval = Py_None;
2194 }
2195 else if (!err) {
Neal Norwitz994ebed2007-06-03 20:32:50 +00002196 /* XXX(nnorwitz): can we do: retval = dataobj; Py_INCREF(retval); */
Jesus Ceaef9764f2008-05-13 18:45:46 +00002197 retval = Build_PyString(data.data, data.size);
Neal Norwitz994ebed2007-06-03 20:32:50 +00002198
2199 /* Even though the flags require DB_DBT_MALLOC, data is not always
2200 allocated. 4.4: allocated, 4.5: *not* allocated. :-( */
2201 if (data.data != orig_data)
2202 FREE_DBT(data);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002203 }
2204
2205 FREE_DBT(key);
2206 RETURN_IF_ERR();
2207 return retval;
2208}
2209
2210
2211static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002212DB_get_byteswapped(DBObject* self)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002213{
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002214 int err = 0;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002215 int retval = -1;
2216
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002217 CHECK_DB_NOT_CLOSED(self);
2218
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002219 MYDB_BEGIN_ALLOW_THREADS;
2220 err = self->db->get_byteswapped(self->db, &retval);
2221 MYDB_END_ALLOW_THREADS;
2222 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002223 return NUMBER_FromLong(retval);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002224}
2225
2226
2227static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002228DB_get_type(DBObject* self)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002229{
2230 int type;
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 type = _DB_get_type(self);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002235 if (type == -1)
2236 return NULL;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002237 return NUMBER_FromLong(type);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002238}
2239
2240
2241static PyObject*
2242DB_join(DBObject* self, PyObject* args)
2243{
2244 int err, flags=0;
2245 int length, x;
2246 PyObject* cursorsObj;
2247 DBC** cursors;
2248 DBC* dbc;
2249
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002250 if (!PyArg_ParseTuple(args,"O|i:join", &cursorsObj, &flags))
2251 return NULL;
2252
2253 CHECK_DB_NOT_CLOSED(self);
2254
2255 if (!PySequence_Check(cursorsObj)) {
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002256 PyErr_SetString(PyExc_TypeError,
2257 "Sequence of DBCursor objects expected");
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002258 return NULL;
2259 }
2260
2261 length = PyObject_Length(cursorsObj);
2262 cursors = malloc((length+1) * sizeof(DBC*));
Neal Norwitz5aa96892006-08-13 18:11:43 +00002263 if (!cursors) {
Jesus Cea6557aac2010-03-22 14:22:26 +00002264 PyErr_NoMemory();
2265 return NULL;
Neal Norwitz5aa96892006-08-13 18:11:43 +00002266 }
2267
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002268 cursors[length] = NULL;
2269 for (x=0; x<length; x++) {
2270 PyObject* item = PySequence_GetItem(cursorsObj, x);
Thomas Woutersb3153832006-03-08 01:47:19 +00002271 if (item == NULL) {
2272 free(cursors);
2273 return NULL;
2274 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002275 if (!DBCursorObject_Check(item)) {
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002276 PyErr_SetString(PyExc_TypeError,
2277 "Sequence of DBCursor objects expected");
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002278 free(cursors);
2279 return NULL;
2280 }
2281 cursors[x] = ((DBCursorObject*)item)->dbc;
Thomas Woutersb2820ae2006-03-12 00:01:38 +00002282 Py_DECREF(item);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002283 }
2284
2285 MYDB_BEGIN_ALLOW_THREADS;
2286 err = self->db->join(self->db, cursors, &dbc, flags);
2287 MYDB_END_ALLOW_THREADS;
2288 free(cursors);
2289 RETURN_IF_ERR();
2290
Gregory P. Smith7441e652003-11-03 21:35:31 +00002291 /* FIXME: this is a buggy interface. The returned cursor
2292 contains internal references to the passed in cursors
2293 but does not hold python references to them or prevent
2294 them from being closed prematurely. This can cause
2295 python to crash when things are done in the wrong order. */
Jesus Ceaef9764f2008-05-13 18:45:46 +00002296 return (PyObject*) newDBCursorObject(dbc, NULL, self);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002297}
2298
2299
2300static PyObject*
2301DB_key_range(DBObject* self, PyObject* args, PyObject* kwargs)
2302{
2303 int err, flags=0;
2304 PyObject* txnobj = NULL;
2305 PyObject* keyobj;
2306 DBT key;
2307 DB_TXN *txn = NULL;
2308 DB_KEY_RANGE range;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002309 static char* kwnames[] = { "key", "txn", "flags", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002310
2311 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|Oi:key_range", kwnames,
2312 &keyobj, &txnobj, &flags))
2313 return NULL;
2314 CHECK_DB_NOT_CLOSED(self);
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002315 if (!make_dbt(keyobj, &key))
2316 /* BTree only, don't need to allow for an int key */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002317 return NULL;
2318 if (!checkTxnObj(txnobj, &txn))
2319 return NULL;
2320
2321 MYDB_BEGIN_ALLOW_THREADS;
2322 err = self->db->key_range(self->db, txn, &key, &range, flags);
2323 MYDB_END_ALLOW_THREADS;
2324
2325 RETURN_IF_ERR();
2326 return Py_BuildValue("ddd", range.less, range.equal, range.greater);
2327}
2328
2329
2330static PyObject*
2331DB_open(DBObject* self, PyObject* args, PyObject* kwargs)
2332{
2333 int err, type = DB_UNKNOWN, flags=0, mode=0660;
2334 char* filename = NULL;
2335 char* dbname = NULL;
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002336 PyObject *txnobj = NULL;
2337 DB_TXN *txn = NULL;
2338 /* with dbname */
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002339 static char* kwnames[] = {
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002340 "filename", "dbname", "dbtype", "flags", "mode", "txn", NULL};
2341 /* without dbname */
Tim Peters85b10522006-02-28 18:33:35 +00002342 static char* kwnames_basic[] = {
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002343 "filename", "dbtype", "flags", "mode", "txn", NULL};
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002344
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002345 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "z|ziiiO:open", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002346 &filename, &dbname, &type, &flags, &mode,
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002347 &txnobj))
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002348 {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002349 PyErr_Clear();
2350 type = DB_UNKNOWN; flags = 0; mode = 0660;
2351 filename = NULL; dbname = NULL;
2352 if (!PyArg_ParseTupleAndKeywords(args, kwargs,"z|iiiO:open",
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002353 kwnames_basic,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002354 &filename, &type, &flags, &mode,
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002355 &txnobj))
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002356 return NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002357 }
2358
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002359 if (!checkTxnObj(txnobj, &txn)) return NULL;
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002360
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002361 if (NULL == self->db) {
Thomas Woutersb3153832006-03-08 01:47:19 +00002362 PyObject *t = Py_BuildValue("(is)", 0,
2363 "Cannot call open() twice for DB object");
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002364 if (t) {
2365 PyErr_SetObject(DBError, t);
2366 Py_DECREF(t);
2367 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002368 return NULL;
2369 }
2370
Jesus Ceaef9764f2008-05-13 18:45:46 +00002371 if (txn) { /* Can't use 'txnobj' because could be 'txnobj==Py_None' */
2372 INSERT_IN_DOUBLE_LINKED_LIST_TXN(((DBTxnObject *)txnobj)->children_dbs,self);
2373 self->txn=(DBTxnObject *)txnobj;
2374 } else {
2375 self->txn=NULL;
2376 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00002377
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002378 MYDB_BEGIN_ALLOW_THREADS;
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002379 err = self->db->open(self->db, txn, filename, dbname, type, flags, mode);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002380 MYDB_END_ALLOW_THREADS;
Jesus Cea6557aac2010-03-22 14:22:26 +00002381
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002382 if (makeDBError(err)) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00002383 PyObject *dummy;
2384
Jesus Cea5cd5f122008-09-23 18:54:08 +00002385 dummy=DB_close_internal(self, 0, 0);
Jesus Ceaef9764f2008-05-13 18:45:46 +00002386 Py_XDECREF(dummy);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002387 return NULL;
2388 }
2389
Gregory P. Smithec10a4a2007-11-05 02:32:26 +00002390 self->db->get_flags(self->db, &self->setflags);
2391
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002392 self->flags = flags;
Jesus Ceaef9764f2008-05-13 18:45:46 +00002393
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002394 RETURN_NONE();
2395}
2396
2397
2398static PyObject*
2399DB_put(DBObject* self, PyObject* args, PyObject* kwargs)
2400{
2401 int flags=0;
2402 PyObject* txnobj = NULL;
2403 int dlen = -1;
2404 int doff = -1;
2405 PyObject* keyobj, *dataobj, *retval;
2406 DBT key, data;
2407 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002408 static char* kwnames[] = { "key", "data", "txn", "flags", "dlen",
Jeremy Hyltonaf68c872005-12-10 18:50:16 +00002409 "doff", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002410
2411 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|Oiii:put", kwnames,
2412 &keyobj, &dataobj, &txnobj, &flags, &dlen, &doff))
2413 return NULL;
2414
2415 CHECK_DB_NOT_CLOSED(self);
Gregory P. Smithdc5af702004-06-27 23:32:34 +00002416 if (!make_key_dbt(self, keyobj, &key, NULL))
2417 return NULL;
2418 if ( !make_dbt(dataobj, &data) ||
2419 !add_partial_dbt(&data, dlen, doff) ||
2420 !checkTxnObj(txnobj, &txn) )
2421 {
2422 FREE_DBT(key);
2423 return NULL;
2424 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002425
2426 if (-1 == _DB_put(self, txn, &key, &data, flags)) {
2427 FREE_DBT(key);
2428 return NULL;
2429 }
2430
2431 if (flags & DB_APPEND)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002432 retval = NUMBER_FromLong(*((db_recno_t*)key.data));
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002433 else {
2434 retval = Py_None;
2435 Py_INCREF(retval);
2436 }
2437 FREE_DBT(key);
2438 return retval;
2439}
2440
2441
2442
2443static PyObject*
2444DB_remove(DBObject* self, PyObject* args, PyObject* kwargs)
2445{
2446 char* filename;
2447 char* database = NULL;
2448 int err, flags=0;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002449 static char* kwnames[] = { "filename", "dbname", "flags", NULL};
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002450
2451 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|zi:remove", kwnames,
2452 &filename, &database, &flags))
2453 return NULL;
2454 CHECK_DB_NOT_CLOSED(self);
2455
Jesus Cea4907d272008-08-31 14:00:51 +00002456 EXTRACT_FROM_DOUBLE_LINKED_LIST_MAYBE_NULL(self);
2457
2458 MYDB_BEGIN_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002459 err = self->db->remove(self->db, filename, database, flags);
Jesus Cea4907d272008-08-31 14:00:51 +00002460 MYDB_END_ALLOW_THREADS;
2461
Gregory P. Smithf655dff2003-05-15 00:13:18 +00002462 self->db = NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002463 RETURN_IF_ERR();
2464 RETURN_NONE();
2465}
2466
2467
2468
2469static PyObject*
2470DB_rename(DBObject* self, PyObject* args)
2471{
2472 char* filename;
2473 char* database;
2474 char* newname;
2475 int err, flags=0;
2476
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002477 if (!PyArg_ParseTuple(args, "sss|i:rename", &filename, &database, &newname,
2478 &flags))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002479 return NULL;
2480 CHECK_DB_NOT_CLOSED(self);
2481
2482 MYDB_BEGIN_ALLOW_THREADS;
2483 err = self->db->rename(self->db, filename, database, newname, flags);
2484 MYDB_END_ALLOW_THREADS;
2485 RETURN_IF_ERR();
2486 RETURN_NONE();
2487}
2488
2489
2490static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002491DB_get_private(DBObject* self)
2492{
2493 /* We can give out the private field even if db is closed */
Jesus Cea4907d272008-08-31 14:00:51 +00002494 Py_INCREF(self->private_obj);
2495 return self->private_obj;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002496}
2497
2498static PyObject*
Jesus Cea4907d272008-08-31 14:00:51 +00002499DB_set_private(DBObject* self, PyObject* private_obj)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002500{
2501 /* We can set the private field even if db is closed */
Jesus Cea4907d272008-08-31 14:00:51 +00002502 Py_INCREF(private_obj);
Serhiy Storchaka763a61c2016-04-10 18:05:12 +03002503 Py_SETREF(self->private_obj, private_obj);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002504 RETURN_NONE();
2505}
2506
Jesus Cea6557aac2010-03-22 14:22:26 +00002507#if (DBVER >= 46)
2508static PyObject*
2509DB_set_priority(DBObject* self, PyObject* args)
2510{
2511 int err, priority;
2512
2513 if (!PyArg_ParseTuple(args,"i:set_priority", &priority))
2514 return NULL;
2515 CHECK_DB_NOT_CLOSED(self);
2516
2517 MYDB_BEGIN_ALLOW_THREADS;
2518 err = self->db->set_priority(self->db, priority);
2519 MYDB_END_ALLOW_THREADS;
2520 RETURN_IF_ERR();
2521 RETURN_NONE();
2522}
2523
2524static PyObject*
2525DB_get_priority(DBObject* self)
2526{
2527 int err = 0;
2528 DB_CACHE_PRIORITY priority;
2529
2530 CHECK_DB_NOT_CLOSED(self);
2531
2532 MYDB_BEGIN_ALLOW_THREADS;
2533 err = self->db->get_priority(self->db, &priority);
2534 MYDB_END_ALLOW_THREADS;
2535 RETURN_IF_ERR();
2536 return NUMBER_FromLong(priority);
2537}
2538#endif
2539
2540static PyObject*
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07002541DB_get_dbname(DBObject* self)
2542{
2543 int err;
2544 const char *filename, *dbname;
2545
2546 CHECK_DB_NOT_CLOSED(self);
2547
2548 MYDB_BEGIN_ALLOW_THREADS;
2549 err = self->db->get_dbname(self->db, &filename, &dbname);
2550 MYDB_END_ALLOW_THREADS;
2551 RETURN_IF_ERR();
2552 /* If "dbname==NULL", it is correctly converted to "None" */
2553 return Py_BuildValue("(ss)", filename, dbname);
2554}
2555
2556static PyObject*
2557DB_get_open_flags(DBObject* self)
2558{
2559 int err;
2560 unsigned int flags;
2561
2562 CHECK_DB_NOT_CLOSED(self);
2563
2564 MYDB_BEGIN_ALLOW_THREADS;
2565 err = self->db->get_open_flags(self->db, &flags);
2566 MYDB_END_ALLOW_THREADS;
2567 RETURN_IF_ERR();
2568 return NUMBER_FromLong(flags);
2569}
2570
2571static PyObject*
Jesus Cea6557aac2010-03-22 14:22:26 +00002572DB_set_q_extentsize(DBObject* self, PyObject* args)
2573{
2574 int err;
2575 u_int32_t extentsize;
2576
2577 if (!PyArg_ParseTuple(args,"i:set_q_extentsize", &extentsize))
2578 return NULL;
2579 CHECK_DB_NOT_CLOSED(self);
2580
2581 MYDB_BEGIN_ALLOW_THREADS;
2582 err = self->db->set_q_extentsize(self->db, extentsize);
2583 MYDB_END_ALLOW_THREADS;
2584 RETURN_IF_ERR();
2585 RETURN_NONE();
2586}
2587
Jesus Cea6557aac2010-03-22 14:22:26 +00002588static PyObject*
2589DB_get_q_extentsize(DBObject* self)
2590{
2591 int err = 0;
2592 u_int32_t extentsize;
2593
2594 CHECK_DB_NOT_CLOSED(self);
2595
2596 MYDB_BEGIN_ALLOW_THREADS;
2597 err = self->db->get_q_extentsize(self->db, &extentsize);
2598 MYDB_END_ALLOW_THREADS;
2599 RETURN_IF_ERR();
2600 return NUMBER_FromLong(extentsize);
2601}
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002602
2603static PyObject*
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002604DB_set_bt_minkey(DBObject* self, PyObject* args)
2605{
2606 int err, minkey;
2607
Jesus Cea6557aac2010-03-22 14:22:26 +00002608 if (!PyArg_ParseTuple(args,"i:set_bt_minkey", &minkey))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002609 return NULL;
2610 CHECK_DB_NOT_CLOSED(self);
2611
2612 MYDB_BEGIN_ALLOW_THREADS;
2613 err = self->db->set_bt_minkey(self->db, minkey);
2614 MYDB_END_ALLOW_THREADS;
2615 RETURN_IF_ERR();
2616 RETURN_NONE();
2617}
2618
Jesus Cea6557aac2010-03-22 14:22:26 +00002619static PyObject*
2620DB_get_bt_minkey(DBObject* self)
2621{
2622 int err;
2623 u_int32_t bt_minkey;
2624
2625 CHECK_DB_NOT_CLOSED(self);
2626
2627 MYDB_BEGIN_ALLOW_THREADS;
2628 err = self->db->get_bt_minkey(self->db, &bt_minkey);
2629 MYDB_END_ALLOW_THREADS;
2630 RETURN_IF_ERR();
2631 return NUMBER_FromLong(bt_minkey);
2632}
Jesus Cea6557aac2010-03-22 14:22:26 +00002633
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002634static int
Georg Brandlef1701f2006-03-07 14:57:48 +00002635_default_cmp(const DBT *leftKey,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002636 const DBT *rightKey)
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002637{
2638 int res;
2639 int lsize = leftKey->size, rsize = rightKey->size;
2640
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002641 res = memcmp(leftKey->data, rightKey->data,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002642 lsize < rsize ? lsize : rsize);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002643
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002644 if (res == 0) {
2645 if (lsize < rsize) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002646 res = -1;
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002647 }
2648 else if (lsize > rsize) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002649 res = 1;
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002650 }
2651 }
2652 return res;
2653}
2654
2655static int
Jesus Ceaef9764f2008-05-13 18:45:46 +00002656_db_compareCallback(DB* db,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002657 const DBT *leftKey,
2658 const DBT *rightKey)
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002659{
2660 int res = 0;
2661 PyObject *args;
Thomas Woutersb2820ae2006-03-12 00:01:38 +00002662 PyObject *result = NULL;
Georg Brandlef1701f2006-03-07 14:57:48 +00002663 DBObject *self = (DBObject *)db->app_private;
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002664
2665 if (self == NULL || self->btCompareCallback == NULL) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002666 MYDB_BEGIN_BLOCK_THREADS;
2667 PyErr_SetString(PyExc_TypeError,
2668 (self == 0
2669 ? "DB_bt_compare db is NULL."
2670 : "DB_bt_compare callback is NULL."));
2671 /* we're in a callback within the DB code, we can't raise */
2672 PyErr_Print();
2673 res = _default_cmp(leftKey, rightKey);
2674 MYDB_END_BLOCK_THREADS;
Georg Brandlef1701f2006-03-07 14:57:48 +00002675 } else {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002676 MYDB_BEGIN_BLOCK_THREADS;
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002677
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002678 args = BuildValue_SS(leftKey->data, leftKey->size, rightKey->data, rightKey->size);
2679 if (args != NULL) {
2680 result = PyEval_CallObject(self->btCompareCallback, args);
2681 }
2682 if (args == NULL || result == NULL) {
2683 /* we're in a callback within the DB code, we can't raise */
2684 PyErr_Print();
2685 res = _default_cmp(leftKey, rightKey);
2686 } else if (NUMBER_Check(result)) {
2687 res = NUMBER_AsLong(result);
2688 } else {
2689 PyErr_SetString(PyExc_TypeError,
2690 "DB_bt_compare callback MUST return an int.");
2691 /* we're in a callback within the DB code, we can't raise */
2692 PyErr_Print();
2693 res = _default_cmp(leftKey, rightKey);
2694 }
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002695
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002696 Py_XDECREF(args);
2697 Py_XDECREF(result);
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002698
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002699 MYDB_END_BLOCK_THREADS;
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002700 }
2701 return res;
2702}
2703
2704static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002705DB_set_bt_compare(DBObject* self, PyObject* comparator)
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002706{
2707 int err;
Thomas Woutersb3153832006-03-08 01:47:19 +00002708 PyObject *tuple, *result;
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002709
Georg Brandlef1701f2006-03-07 14:57:48 +00002710 CHECK_DB_NOT_CLOSED(self);
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002711
Georg Brandlef1701f2006-03-07 14:57:48 +00002712 if (!PyCallable_Check(comparator)) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002713 makeTypeError("Callable", comparator);
2714 return NULL;
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002715 }
2716
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002717 /*
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002718 * Perform a test call of the comparator function with two empty
2719 * string objects here. verify that it returns an int (0).
2720 * err if not.
2721 */
Thomas Woutersb3153832006-03-08 01:47:19 +00002722 tuple = Py_BuildValue("(ss)", "", "");
Georg Brandlef1701f2006-03-07 14:57:48 +00002723 result = PyEval_CallObject(comparator, tuple);
2724 Py_DECREF(tuple);
Thomas Woutersb3153832006-03-08 01:47:19 +00002725 if (result == NULL)
2726 return NULL;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002727 if (!NUMBER_Check(result)) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002728 Py_DECREF(result);
2729 PyErr_SetString(PyExc_TypeError,
2730 "callback MUST return an int");
2731 return NULL;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002732 } else if (NUMBER_AsLong(result) != 0) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002733 Py_DECREF(result);
2734 PyErr_SetString(PyExc_TypeError,
2735 "callback failed to return 0 on two empty strings");
2736 return NULL;
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002737 }
Thomas Woutersb3153832006-03-08 01:47:19 +00002738 Py_DECREF(result);
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002739
2740 /* We don't accept multiple set_bt_compare operations, in order to
2741 * simplify the code. This would have no real use, as one cannot
2742 * change the function once the db is opened anyway */
2743 if (self->btCompareCallback != NULL) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002744 PyErr_SetString(PyExc_RuntimeError, "set_bt_compare() cannot be called more than once");
2745 return NULL;
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002746 }
2747
Georg Brandlef1701f2006-03-07 14:57:48 +00002748 Py_INCREF(comparator);
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002749 self->btCompareCallback = comparator;
2750
2751 /* This is to workaround a problem with un-initialized threads (see
2752 comment in DB_associate) */
2753#ifdef WITH_THREAD
2754 PyEval_InitThreads();
2755#endif
2756
Thomas Woutersb3153832006-03-08 01:47:19 +00002757 err = self->db->set_bt_compare(self->db, _db_compareCallback);
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002758
2759 if (err) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002760 /* restore the old state in case of error */
2761 Py_DECREF(comparator);
2762 self->btCompareCallback = NULL;
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002763 }
2764
Georg Brandlef1701f2006-03-07 14:57:48 +00002765 RETURN_IF_ERR();
2766 RETURN_NONE();
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002767}
2768
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07002769static int
2770_db_dupCompareCallback(DB* db,
2771 const DBT *leftKey,
2772 const DBT *rightKey)
2773{
2774 int res = 0;
2775 PyObject *args;
2776 PyObject *result = NULL;
2777 DBObject *self = (DBObject *)db->app_private;
2778
2779 if (self == NULL || self->dupCompareCallback == NULL) {
2780 MYDB_BEGIN_BLOCK_THREADS;
2781 PyErr_SetString(PyExc_TypeError,
2782 (self == 0
2783 ? "DB_dup_compare db is NULL."
2784 : "DB_dup_compare callback is NULL."));
2785 /* we're in a callback within the DB code, we can't raise */
2786 PyErr_Print();
2787 res = _default_cmp(leftKey, rightKey);
2788 MYDB_END_BLOCK_THREADS;
2789 } else {
2790 MYDB_BEGIN_BLOCK_THREADS;
2791
2792 args = BuildValue_SS(leftKey->data, leftKey->size, rightKey->data, rightKey->size);
2793 if (args != NULL) {
2794 result = PyEval_CallObject(self->dupCompareCallback, args);
2795 }
2796 if (args == NULL || result == NULL) {
2797 /* we're in a callback within the DB code, we can't raise */
2798 PyErr_Print();
2799 res = _default_cmp(leftKey, rightKey);
2800 } else if (NUMBER_Check(result)) {
2801 res = NUMBER_AsLong(result);
2802 } else {
2803 PyErr_SetString(PyExc_TypeError,
2804 "DB_dup_compare callback MUST return an int.");
2805 /* we're in a callback within the DB code, we can't raise */
2806 PyErr_Print();
2807 res = _default_cmp(leftKey, rightKey);
2808 }
2809
2810 Py_XDECREF(args);
2811 Py_XDECREF(result);
2812
2813 MYDB_END_BLOCK_THREADS;
2814 }
2815 return res;
2816}
2817
2818static PyObject*
2819DB_set_dup_compare(DBObject* self, PyObject* comparator)
2820{
2821 int err;
2822 PyObject *tuple, *result;
2823
2824 CHECK_DB_NOT_CLOSED(self);
2825
2826 if (!PyCallable_Check(comparator)) {
2827 makeTypeError("Callable", comparator);
2828 return NULL;
2829 }
2830
2831 /*
2832 * Perform a test call of the comparator function with two empty
2833 * string objects here. verify that it returns an int (0).
2834 * err if not.
2835 */
2836 tuple = Py_BuildValue("(ss)", "", "");
2837 result = PyEval_CallObject(comparator, tuple);
2838 Py_DECREF(tuple);
2839 if (result == NULL)
2840 return NULL;
2841 if (!NUMBER_Check(result)) {
2842 Py_DECREF(result);
2843 PyErr_SetString(PyExc_TypeError,
2844 "callback MUST return an int");
2845 return NULL;
2846 } else if (NUMBER_AsLong(result) != 0) {
2847 Py_DECREF(result);
2848 PyErr_SetString(PyExc_TypeError,
2849 "callback failed to return 0 on two empty strings");
2850 return NULL;
2851 }
2852 Py_DECREF(result);
2853
2854 /* We don't accept multiple set_dup_compare operations, in order to
2855 * simplify the code. This would have no real use, as one cannot
2856 * change the function once the db is opened anyway */
2857 if (self->dupCompareCallback != NULL) {
2858 PyErr_SetString(PyExc_RuntimeError, "set_dup_compare() cannot be called more than once");
2859 return NULL;
2860 }
2861
2862 Py_INCREF(comparator);
2863 self->dupCompareCallback = comparator;
2864
2865 /* This is to workaround a problem with un-initialized threads (see
2866 comment in DB_associate) */
2867#ifdef WITH_THREAD
2868 PyEval_InitThreads();
2869#endif
2870
2871 err = self->db->set_dup_compare(self->db, _db_dupCompareCallback);
2872
2873 if (err) {
2874 /* restore the old state in case of error */
2875 Py_DECREF(comparator);
2876 self->dupCompareCallback = NULL;
2877 }
2878
2879 RETURN_IF_ERR();
2880 RETURN_NONE();
2881}
2882
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002883
2884static PyObject*
2885DB_set_cachesize(DBObject* self, PyObject* args)
2886{
2887 int err;
2888 int gbytes = 0, bytes = 0, ncache = 0;
2889
2890 if (!PyArg_ParseTuple(args,"ii|i:set_cachesize",
2891 &gbytes,&bytes,&ncache))
2892 return NULL;
2893 CHECK_DB_NOT_CLOSED(self);
2894
2895 MYDB_BEGIN_ALLOW_THREADS;
2896 err = self->db->set_cachesize(self->db, gbytes, bytes, ncache);
2897 MYDB_END_ALLOW_THREADS;
2898 RETURN_IF_ERR();
2899 RETURN_NONE();
2900}
2901
Jesus Cea6557aac2010-03-22 14:22:26 +00002902static PyObject*
2903DB_get_cachesize(DBObject* self)
2904{
2905 int err;
2906 u_int32_t gbytes, bytes;
2907 int ncache;
2908
2909 CHECK_DB_NOT_CLOSED(self);
2910
2911 MYDB_BEGIN_ALLOW_THREADS;
2912 err = self->db->get_cachesize(self->db, &gbytes, &bytes, &ncache);
2913 MYDB_END_ALLOW_THREADS;
2914
2915 RETURN_IF_ERR();
2916
2917 return Py_BuildValue("(iii)", gbytes, bytes, ncache);
2918}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002919
2920static PyObject*
2921DB_set_flags(DBObject* self, PyObject* args)
2922{
2923 int err, flags;
2924
2925 if (!PyArg_ParseTuple(args,"i:set_flags", &flags))
2926 return NULL;
2927 CHECK_DB_NOT_CLOSED(self);
2928
2929 MYDB_BEGIN_ALLOW_THREADS;
2930 err = self->db->set_flags(self->db, flags);
2931 MYDB_END_ALLOW_THREADS;
2932 RETURN_IF_ERR();
2933
2934 self->setflags |= flags;
2935 RETURN_NONE();
2936}
2937
Jesus Cea6557aac2010-03-22 14:22:26 +00002938static PyObject*
2939DB_get_flags(DBObject* self)
2940{
2941 int err;
2942 u_int32_t flags;
2943
2944 CHECK_DB_NOT_CLOSED(self);
2945
2946 MYDB_BEGIN_ALLOW_THREADS;
2947 err = self->db->get_flags(self->db, &flags);
2948 MYDB_END_ALLOW_THREADS;
2949 RETURN_IF_ERR();
2950 return NUMBER_FromLong(flags);
2951}
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07002952
2953static PyObject*
2954DB_get_transactional(DBObject* self)
2955{
2956 int err;
2957
2958 CHECK_DB_NOT_CLOSED(self);
2959
2960 MYDB_BEGIN_ALLOW_THREADS;
2961 err = self->db->get_transactional(self->db);
2962 MYDB_END_ALLOW_THREADS;
2963
2964 if(err == 0) {
2965 Py_INCREF(Py_False);
2966 return Py_False;
2967 } else if(err == 1) {
2968 Py_INCREF(Py_True);
2969 return Py_True;
2970 }
2971
2972 /*
2973 ** If we reach there, there was an error. The
2974 ** "return" should be unreachable.
2975 */
2976 RETURN_IF_ERR();
2977 assert(0); /* This code SHOULD be unreachable */
2978 return NULL;
2979}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002980
2981static PyObject*
2982DB_set_h_ffactor(DBObject* self, PyObject* args)
2983{
2984 int err, ffactor;
2985
2986 if (!PyArg_ParseTuple(args,"i:set_h_ffactor", &ffactor))
2987 return NULL;
2988 CHECK_DB_NOT_CLOSED(self);
2989
2990 MYDB_BEGIN_ALLOW_THREADS;
2991 err = self->db->set_h_ffactor(self->db, ffactor);
2992 MYDB_END_ALLOW_THREADS;
2993 RETURN_IF_ERR();
2994 RETURN_NONE();
2995}
2996
Jesus Cea6557aac2010-03-22 14:22:26 +00002997static PyObject*
2998DB_get_h_ffactor(DBObject* self)
2999{
3000 int err;
3001 u_int32_t ffactor;
3002
3003 CHECK_DB_NOT_CLOSED(self);
3004
3005 MYDB_BEGIN_ALLOW_THREADS;
3006 err = self->db->get_h_ffactor(self->db, &ffactor);
3007 MYDB_END_ALLOW_THREADS;
3008 RETURN_IF_ERR();
3009 return NUMBER_FromLong(ffactor);
3010}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003011
3012static PyObject*
3013DB_set_h_nelem(DBObject* self, PyObject* args)
3014{
3015 int err, nelem;
3016
3017 if (!PyArg_ParseTuple(args,"i:set_h_nelem", &nelem))
3018 return NULL;
3019 CHECK_DB_NOT_CLOSED(self);
3020
3021 MYDB_BEGIN_ALLOW_THREADS;
3022 err = self->db->set_h_nelem(self->db, nelem);
3023 MYDB_END_ALLOW_THREADS;
3024 RETURN_IF_ERR();
3025 RETURN_NONE();
3026}
3027
Jesus Cea6557aac2010-03-22 14:22:26 +00003028static PyObject*
3029DB_get_h_nelem(DBObject* self)
3030{
3031 int err;
3032 u_int32_t nelem;
3033
3034 CHECK_DB_NOT_CLOSED(self);
3035
3036 MYDB_BEGIN_ALLOW_THREADS;
3037 err = self->db->get_h_nelem(self->db, &nelem);
3038 MYDB_END_ALLOW_THREADS;
3039 RETURN_IF_ERR();
3040 return NUMBER_FromLong(nelem);
3041}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003042
3043static PyObject*
3044DB_set_lorder(DBObject* self, PyObject* args)
3045{
3046 int err, lorder;
3047
3048 if (!PyArg_ParseTuple(args,"i:set_lorder", &lorder))
3049 return NULL;
3050 CHECK_DB_NOT_CLOSED(self);
3051
3052 MYDB_BEGIN_ALLOW_THREADS;
3053 err = self->db->set_lorder(self->db, lorder);
3054 MYDB_END_ALLOW_THREADS;
3055 RETURN_IF_ERR();
3056 RETURN_NONE();
3057}
3058
Jesus Cea6557aac2010-03-22 14:22:26 +00003059static PyObject*
3060DB_get_lorder(DBObject* self)
3061{
3062 int err;
3063 int lorder;
3064
3065 CHECK_DB_NOT_CLOSED(self);
3066
3067 MYDB_BEGIN_ALLOW_THREADS;
3068 err = self->db->get_lorder(self->db, &lorder);
3069 MYDB_END_ALLOW_THREADS;
3070 RETURN_IF_ERR();
3071 return NUMBER_FromLong(lorder);
3072}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003073
3074static PyObject*
3075DB_set_pagesize(DBObject* self, PyObject* args)
3076{
3077 int err, pagesize;
3078
3079 if (!PyArg_ParseTuple(args,"i:set_pagesize", &pagesize))
3080 return NULL;
3081 CHECK_DB_NOT_CLOSED(self);
3082
3083 MYDB_BEGIN_ALLOW_THREADS;
3084 err = self->db->set_pagesize(self->db, pagesize);
3085 MYDB_END_ALLOW_THREADS;
3086 RETURN_IF_ERR();
3087 RETURN_NONE();
3088}
3089
Jesus Cea6557aac2010-03-22 14:22:26 +00003090static PyObject*
3091DB_get_pagesize(DBObject* self)
3092{
3093 int err;
3094 u_int32_t pagesize;
3095
3096 CHECK_DB_NOT_CLOSED(self);
3097
3098 MYDB_BEGIN_ALLOW_THREADS;
3099 err = self->db->get_pagesize(self->db, &pagesize);
3100 MYDB_END_ALLOW_THREADS;
3101 RETURN_IF_ERR();
3102 return NUMBER_FromLong(pagesize);
3103}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003104
3105static PyObject*
3106DB_set_re_delim(DBObject* self, PyObject* args)
3107{
3108 int err;
3109 char delim;
3110
3111 if (!PyArg_ParseTuple(args,"b:set_re_delim", &delim)) {
3112 PyErr_Clear();
3113 if (!PyArg_ParseTuple(args,"c:set_re_delim", &delim))
3114 return NULL;
3115 }
3116
3117 CHECK_DB_NOT_CLOSED(self);
3118
3119 MYDB_BEGIN_ALLOW_THREADS;
3120 err = self->db->set_re_delim(self->db, delim);
3121 MYDB_END_ALLOW_THREADS;
3122 RETURN_IF_ERR();
3123 RETURN_NONE();
3124}
3125
Jesus Cea6557aac2010-03-22 14:22:26 +00003126static PyObject*
3127DB_get_re_delim(DBObject* self)
3128{
3129 int err, re_delim;
3130
3131 CHECK_DB_NOT_CLOSED(self);
3132
3133 MYDB_BEGIN_ALLOW_THREADS;
3134 err = self->db->get_re_delim(self->db, &re_delim);
3135 MYDB_END_ALLOW_THREADS;
3136 RETURN_IF_ERR();
3137 return NUMBER_FromLong(re_delim);
3138}
Jesus Cea6557aac2010-03-22 14:22:26 +00003139
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003140static PyObject*
3141DB_set_re_len(DBObject* self, PyObject* args)
3142{
3143 int err, len;
3144
3145 if (!PyArg_ParseTuple(args,"i:set_re_len", &len))
3146 return NULL;
3147 CHECK_DB_NOT_CLOSED(self);
3148
3149 MYDB_BEGIN_ALLOW_THREADS;
3150 err = self->db->set_re_len(self->db, len);
3151 MYDB_END_ALLOW_THREADS;
3152 RETURN_IF_ERR();
3153 RETURN_NONE();
3154}
3155
Jesus Cea6557aac2010-03-22 14:22:26 +00003156static PyObject*
3157DB_get_re_len(DBObject* self)
3158{
3159 int err;
3160 u_int32_t re_len;
3161
3162 CHECK_DB_NOT_CLOSED(self);
3163
3164 MYDB_BEGIN_ALLOW_THREADS;
3165 err = self->db->get_re_len(self->db, &re_len);
3166 MYDB_END_ALLOW_THREADS;
3167 RETURN_IF_ERR();
3168 return NUMBER_FromLong(re_len);
3169}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003170
3171static PyObject*
3172DB_set_re_pad(DBObject* self, PyObject* args)
3173{
3174 int err;
3175 char pad;
3176
3177 if (!PyArg_ParseTuple(args,"b:set_re_pad", &pad)) {
3178 PyErr_Clear();
3179 if (!PyArg_ParseTuple(args,"c:set_re_pad", &pad))
3180 return NULL;
3181 }
3182 CHECK_DB_NOT_CLOSED(self);
3183
3184 MYDB_BEGIN_ALLOW_THREADS;
3185 err = self->db->set_re_pad(self->db, pad);
3186 MYDB_END_ALLOW_THREADS;
3187 RETURN_IF_ERR();
3188 RETURN_NONE();
3189}
3190
Jesus Cea6557aac2010-03-22 14:22:26 +00003191static PyObject*
3192DB_get_re_pad(DBObject* self)
3193{
3194 int err, re_pad;
3195
3196 CHECK_DB_NOT_CLOSED(self);
3197
3198 MYDB_BEGIN_ALLOW_THREADS;
3199 err = self->db->get_re_pad(self->db, &re_pad);
3200 MYDB_END_ALLOW_THREADS;
3201 RETURN_IF_ERR();
3202 return NUMBER_FromLong(re_pad);
3203}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003204
3205static PyObject*
3206DB_set_re_source(DBObject* self, PyObject* args)
3207{
3208 int err;
Jesus Cea6557aac2010-03-22 14:22:26 +00003209 char *source;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003210
Jesus Cea6557aac2010-03-22 14:22:26 +00003211 if (!PyArg_ParseTuple(args,"s:set_re_source", &source))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003212 return NULL;
3213 CHECK_DB_NOT_CLOSED(self);
3214
3215 MYDB_BEGIN_ALLOW_THREADS;
Jesus Cea6557aac2010-03-22 14:22:26 +00003216 err = self->db->set_re_source(self->db, source);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003217 MYDB_END_ALLOW_THREADS;
3218 RETURN_IF_ERR();
3219 RETURN_NONE();
3220}
3221
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003222static PyObject*
Jesus Cea6557aac2010-03-22 14:22:26 +00003223DB_get_re_source(DBObject* self)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003224{
3225 int err;
Jesus Cea6557aac2010-03-22 14:22:26 +00003226 const char *source;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003227
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003228 CHECK_DB_NOT_CLOSED(self);
3229
3230 MYDB_BEGIN_ALLOW_THREADS;
Jesus Cea6557aac2010-03-22 14:22:26 +00003231 err = self->db->get_re_source(self->db, &source);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003232 MYDB_END_ALLOW_THREADS;
3233 RETURN_IF_ERR();
Jesus Cea6557aac2010-03-22 14:22:26 +00003234 return PyBytes_FromString(source);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003235}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003236
3237static PyObject*
Gregory P. Smith8b7e9172004-12-13 09:51:23 +00003238DB_stat(DBObject* self, PyObject* args, PyObject* kwargs)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003239{
3240 int err, flags = 0, type;
3241 void* sp;
3242 PyObject* d;
Gregory P. Smith8b7e9172004-12-13 09:51:23 +00003243 PyObject* txnobj = NULL;
3244 DB_TXN *txn = NULL;
Gregory P. Smith2fa06792006-09-19 17:35:04 +00003245 static char* kwnames[] = { "flags", "txn", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003246
Gregory P. Smith8b7e9172004-12-13 09:51:23 +00003247 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|iO:stat", kwnames,
3248 &flags, &txnobj))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003249 return NULL;
Gregory P. Smith8b7e9172004-12-13 09:51:23 +00003250 if (!checkTxnObj(txnobj, &txn))
3251 return NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003252 CHECK_DB_NOT_CLOSED(self);
3253
3254 MYDB_BEGIN_ALLOW_THREADS;
Gregory P. Smith8b7e9172004-12-13 09:51:23 +00003255 err = self->db->stat(self->db, txn, &sp, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003256 MYDB_END_ALLOW_THREADS;
3257 RETURN_IF_ERR();
3258
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003259 /* Turn the stat structure into a dictionary */
3260 type = _DB_get_type(self);
3261 if ((type == -1) || ((d = PyDict_New()) == NULL)) {
3262 free(sp);
3263 return NULL;
3264 }
3265
3266#define MAKE_HASH_ENTRY(name) _addIntToDict(d, #name, ((DB_HASH_STAT*)sp)->hash_##name)
3267#define MAKE_BT_ENTRY(name) _addIntToDict(d, #name, ((DB_BTREE_STAT*)sp)->bt_##name)
3268#define MAKE_QUEUE_ENTRY(name) _addIntToDict(d, #name, ((DB_QUEUE_STAT*)sp)->qs_##name)
3269
3270 switch (type) {
3271 case DB_HASH:
3272 MAKE_HASH_ENTRY(magic);
3273 MAKE_HASH_ENTRY(version);
3274 MAKE_HASH_ENTRY(nkeys);
3275 MAKE_HASH_ENTRY(ndata);
Jesus Ceaef9764f2008-05-13 18:45:46 +00003276#if (DBVER >= 46)
3277 MAKE_HASH_ENTRY(pagecnt);
3278#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003279 MAKE_HASH_ENTRY(pagesize);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003280 MAKE_HASH_ENTRY(ffactor);
3281 MAKE_HASH_ENTRY(buckets);
3282 MAKE_HASH_ENTRY(free);
3283 MAKE_HASH_ENTRY(bfree);
3284 MAKE_HASH_ENTRY(bigpages);
3285 MAKE_HASH_ENTRY(big_bfree);
3286 MAKE_HASH_ENTRY(overflows);
3287 MAKE_HASH_ENTRY(ovfl_free);
3288 MAKE_HASH_ENTRY(dup);
3289 MAKE_HASH_ENTRY(dup_free);
3290 break;
3291
3292 case DB_BTREE:
3293 case DB_RECNO:
3294 MAKE_BT_ENTRY(magic);
3295 MAKE_BT_ENTRY(version);
3296 MAKE_BT_ENTRY(nkeys);
3297 MAKE_BT_ENTRY(ndata);
Jesus Ceaef9764f2008-05-13 18:45:46 +00003298#if (DBVER >= 46)
3299 MAKE_BT_ENTRY(pagecnt);
3300#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003301 MAKE_BT_ENTRY(pagesize);
3302 MAKE_BT_ENTRY(minkey);
3303 MAKE_BT_ENTRY(re_len);
3304 MAKE_BT_ENTRY(re_pad);
3305 MAKE_BT_ENTRY(levels);
3306 MAKE_BT_ENTRY(int_pg);
3307 MAKE_BT_ENTRY(leaf_pg);
3308 MAKE_BT_ENTRY(dup_pg);
3309 MAKE_BT_ENTRY(over_pg);
Jesus Ceaef9764f2008-05-13 18:45:46 +00003310 MAKE_BT_ENTRY(empty_pg);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003311 MAKE_BT_ENTRY(free);
3312 MAKE_BT_ENTRY(int_pgfree);
3313 MAKE_BT_ENTRY(leaf_pgfree);
3314 MAKE_BT_ENTRY(dup_pgfree);
3315 MAKE_BT_ENTRY(over_pgfree);
3316 break;
3317
3318 case DB_QUEUE:
3319 MAKE_QUEUE_ENTRY(magic);
3320 MAKE_QUEUE_ENTRY(version);
3321 MAKE_QUEUE_ENTRY(nkeys);
3322 MAKE_QUEUE_ENTRY(ndata);
3323 MAKE_QUEUE_ENTRY(pagesize);
Jesus Ceaef9764f2008-05-13 18:45:46 +00003324 MAKE_QUEUE_ENTRY(extentsize);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003325 MAKE_QUEUE_ENTRY(pages);
3326 MAKE_QUEUE_ENTRY(re_len);
3327 MAKE_QUEUE_ENTRY(re_pad);
3328 MAKE_QUEUE_ENTRY(pgfree);
3329#if (DBVER == 31)
3330 MAKE_QUEUE_ENTRY(start);
3331#endif
3332 MAKE_QUEUE_ENTRY(first_recno);
3333 MAKE_QUEUE_ENTRY(cur_recno);
3334 break;
3335
3336 default:
3337 PyErr_SetString(PyExc_TypeError, "Unknown DB type, unable to stat");
3338 Py_DECREF(d);
3339 d = NULL;
3340 }
3341
3342#undef MAKE_HASH_ENTRY
3343#undef MAKE_BT_ENTRY
3344#undef MAKE_QUEUE_ENTRY
3345
3346 free(sp);
3347 return d;
3348}
3349
Jesus Cea6557aac2010-03-22 14:22:26 +00003350static PyObject*
3351DB_stat_print(DBObject* self, PyObject* args, PyObject *kwargs)
3352{
3353 int err;
3354 int flags=0;
3355 static char* kwnames[] = { "flags", NULL };
3356
3357 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:stat_print",
3358 kwnames, &flags))
3359 {
3360 return NULL;
3361 }
3362 CHECK_DB_NOT_CLOSED(self);
3363 MYDB_BEGIN_ALLOW_THREADS;
3364 err = self->db->stat_print(self->db, flags);
3365 MYDB_END_ALLOW_THREADS;
3366 RETURN_IF_ERR();
3367 RETURN_NONE();
3368}
Jesus Cea6557aac2010-03-22 14:22:26 +00003369
3370
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003371static PyObject*
3372DB_sync(DBObject* self, PyObject* args)
3373{
3374 int err;
3375 int flags = 0;
3376
3377 if (!PyArg_ParseTuple(args,"|i:sync", &flags ))
3378 return NULL;
3379 CHECK_DB_NOT_CLOSED(self);
3380
3381 MYDB_BEGIN_ALLOW_THREADS;
3382 err = self->db->sync(self->db, flags);
3383 MYDB_END_ALLOW_THREADS;
3384 RETURN_IF_ERR();
3385 RETURN_NONE();
3386}
3387
3388
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003389static PyObject*
3390DB_truncate(DBObject* self, PyObject* args, PyObject* kwargs)
3391{
3392 int err, flags=0;
3393 u_int32_t count=0;
3394 PyObject* txnobj = NULL;
3395 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003396 static char* kwnames[] = { "txn", "flags", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003397
3398 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Oi:cursor", kwnames,
3399 &txnobj, &flags))
3400 return NULL;
3401 CHECK_DB_NOT_CLOSED(self);
3402 if (!checkTxnObj(txnobj, &txn))
3403 return NULL;
3404
3405 MYDB_BEGIN_ALLOW_THREADS;
3406 err = self->db->truncate(self->db, txn, &count, flags);
3407 MYDB_END_ALLOW_THREADS;
3408 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00003409 return NUMBER_FromLong(count);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003410}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003411
3412
3413static PyObject*
3414DB_upgrade(DBObject* self, PyObject* args)
3415{
3416 int err, flags=0;
3417 char *filename;
3418
3419 if (!PyArg_ParseTuple(args,"s|i:upgrade", &filename, &flags))
3420 return NULL;
3421 CHECK_DB_NOT_CLOSED(self);
3422
3423 MYDB_BEGIN_ALLOW_THREADS;
3424 err = self->db->upgrade(self->db, filename, flags);
3425 MYDB_END_ALLOW_THREADS;
3426 RETURN_IF_ERR();
3427 RETURN_NONE();
3428}
3429
3430
3431static PyObject*
3432DB_verify(DBObject* self, PyObject* args, PyObject* kwargs)
3433{
3434 int err, flags=0;
3435 char* fileName;
3436 char* dbName=NULL;
3437 char* outFileName=NULL;
3438 FILE* outFile=NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003439 static char* kwnames[] = { "filename", "dbname", "outfile", "flags",
Jeremy Hyltonaf68c872005-12-10 18:50:16 +00003440 NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003441
3442 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|zzi:verify", kwnames,
3443 &fileName, &dbName, &outFileName, &flags))
3444 return NULL;
3445
3446 CHECK_DB_NOT_CLOSED(self);
3447 if (outFileName)
3448 outFile = fopen(outFileName, "w");
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003449 /* XXX(nnorwitz): it should probably be an exception if outFile
3450 can't be opened. */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003451
Jesus Ceaef9764f2008-05-13 18:45:46 +00003452 { /* DB.verify acts as a DB handle destructor (like close) */
3453 PyObject *error;
3454
Jesus Cea5cd5f122008-09-23 18:54:08 +00003455 error=DB_close_internal(self, 0, 1);
Jesus Cea6557aac2010-03-22 14:22:26 +00003456 if (error) {
Serhiy Storchakaaffac002015-07-24 08:05:45 +03003457 if (outFile)
3458 fclose(outFile);
3459 return error;
Jesus Ceaef9764f2008-05-13 18:45:46 +00003460 }
Serhiy Storchakaaffac002015-07-24 08:05:45 +03003461 }
Gregory P. Smith41631e82003-09-21 00:08:14 +00003462
Jesus Cea5cd5f122008-09-23 18:54:08 +00003463 MYDB_BEGIN_ALLOW_THREADS;
3464 err = self->db->verify(self->db, fileName, dbName, outFile, flags);
3465 MYDB_END_ALLOW_THREADS;
3466
3467 self->db = NULL; /* Implicit close; related objects already released */
3468
3469 if (outFile)
3470 fclose(outFile);
3471
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003472 RETURN_IF_ERR();
3473 RETURN_NONE();
3474}
3475
3476
3477static PyObject*
3478DB_set_get_returns_none(DBObject* self, PyObject* args)
3479{
3480 int flags=0;
Gregory P. Smith455d46f2003-07-09 04:45:59 +00003481 int oldValue=0;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003482
3483 if (!PyArg_ParseTuple(args,"i:set_get_returns_none", &flags))
3484 return NULL;
3485 CHECK_DB_NOT_CLOSED(self);
3486
Gregory P. Smith455d46f2003-07-09 04:45:59 +00003487 if (self->moduleFlags.getReturnsNone)
3488 ++oldValue;
3489 if (self->moduleFlags.cursorSetReturnsNone)
3490 ++oldValue;
3491 self->moduleFlags.getReturnsNone = (flags >= 1);
3492 self->moduleFlags.cursorSetReturnsNone = (flags >= 2);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00003493 return NUMBER_FromLong(oldValue);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003494}
3495
Barry Warsaw9a0d7792002-12-30 20:53:52 +00003496static PyObject*
3497DB_set_encrypt(DBObject* self, PyObject* args, PyObject* kwargs)
3498{
3499 int err;
3500 u_int32_t flags=0;
3501 char *passwd = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003502 static char* kwnames[] = { "passwd", "flags", NULL };
Barry Warsaw9a0d7792002-12-30 20:53:52 +00003503
3504 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|i:set_encrypt", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003505 &passwd, &flags)) {
3506 return NULL;
Barry Warsaw9a0d7792002-12-30 20:53:52 +00003507 }
3508
3509 MYDB_BEGIN_ALLOW_THREADS;
3510 err = self->db->set_encrypt(self->db, passwd, flags);
3511 MYDB_END_ALLOW_THREADS;
3512
3513 RETURN_IF_ERR();
3514 RETURN_NONE();
3515}
Jesus Cea6557aac2010-03-22 14:22:26 +00003516
Jesus Cea6557aac2010-03-22 14:22:26 +00003517static PyObject*
3518DB_get_encrypt_flags(DBObject* self)
3519{
3520 int err;
3521 u_int32_t flags;
3522
3523 MYDB_BEGIN_ALLOW_THREADS;
3524 err = self->db->get_encrypt_flags(self->db, &flags);
3525 MYDB_END_ALLOW_THREADS;
3526
3527 RETURN_IF_ERR();
3528
3529 return NUMBER_FromLong(flags);
3530}
Jesus Cea6557aac2010-03-22 14:22:26 +00003531
Barry Warsaw9a0d7792002-12-30 20:53:52 +00003532
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003533
3534/*-------------------------------------------------------------- */
3535/* Mapping and Dictionary-like access routines */
3536
Martin v. Löwis70ee3cc2006-06-12 04:26:31 +00003537Py_ssize_t DB_length(PyObject* _self)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003538{
3539 int err;
Gregory P. Smith3c228b12006-06-05 23:59:37 +00003540 Py_ssize_t size = 0;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003541 void* sp;
Martin v. Löwis70ee3cc2006-06-12 04:26:31 +00003542 DBObject* self = (DBObject*)_self;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003543
3544 if (self->db == NULL) {
Thomas Woutersb3153832006-03-08 01:47:19 +00003545 PyObject *t = Py_BuildValue("(is)", 0, "DB object has been closed");
Jesus Ceac5a11fa2008-07-23 11:38:42 +00003546 if (t) {
3547 PyErr_SetObject(DBError, t);
3548 Py_DECREF(t);
3549 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003550 return -1;
3551 }
3552
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003553 MYDB_BEGIN_ALLOW_THREADS;
Jesus Cea6557aac2010-03-22 14:22:26 +00003554 err = self->db->stat(self->db, /*txnid*/ NULL, &sp, 0);
Jesus Cea6557aac2010-03-22 14:22:26 +00003555 MYDB_END_ALLOW_THREADS;
Gregory P. Smith3c228b12006-06-05 23:59:37 +00003556
3557 /* All the stat structures have matching fields upto the ndata field,
3558 so we can use any of them for the type cast */
3559 size = ((DB_BTREE_STAT*)sp)->bt_ndata;
3560
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003561 if (err)
3562 return -1;
3563
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003564 free(sp);
3565 return size;
3566}
3567
3568
3569PyObject* DB_subscript(DBObject* self, PyObject* keyobj)
3570{
3571 int err;
3572 PyObject* retval;
3573 DBT key;
3574 DBT data;
3575
3576 CHECK_DB_NOT_CLOSED(self);
3577 if (!make_key_dbt(self, keyobj, &key, NULL))
3578 return NULL;
3579
3580 CLEAR_DBT(data);
3581 if (CHECK_DBFLAG(self, DB_THREAD)) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00003582 /* Tell Berkeley DB to malloc the return value (thread safe) */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003583 data.flags = DB_DBT_MALLOC;
3584 }
3585 MYDB_BEGIN_ALLOW_THREADS;
3586 err = self->db->get(self->db, NULL, &key, &data, 0);
3587 MYDB_END_ALLOW_THREADS;
3588 if (err == DB_NOTFOUND || err == DB_KEYEMPTY) {
3589 PyErr_SetObject(PyExc_KeyError, keyobj);
3590 retval = NULL;
3591 }
3592 else if (makeDBError(err)) {
3593 retval = NULL;
3594 }
3595 else {
Jesus Ceaef9764f2008-05-13 18:45:46 +00003596 retval = Build_PyString(data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003597 FREE_DBT(data);
3598 }
3599
3600 FREE_DBT(key);
3601 return retval;
3602}
3603
3604
3605static int
3606DB_ass_sub(DBObject* self, PyObject* keyobj, PyObject* dataobj)
3607{
3608 DBT key, data;
3609 int retval;
3610 int flags = 0;
3611
3612 if (self->db == NULL) {
Thomas Woutersb3153832006-03-08 01:47:19 +00003613 PyObject *t = Py_BuildValue("(is)", 0, "DB object has been closed");
Jesus Ceac5a11fa2008-07-23 11:38:42 +00003614 if (t) {
3615 PyErr_SetObject(DBError, t);
3616 Py_DECREF(t);
3617 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003618 return -1;
3619 }
3620
3621 if (!make_key_dbt(self, keyobj, &key, NULL))
3622 return -1;
3623
3624 if (dataobj != NULL) {
3625 if (!make_dbt(dataobj, &data))
3626 retval = -1;
3627 else {
3628 if (self->setflags & (DB_DUP|DB_DUPSORT))
Barry Warsaw9a0d7792002-12-30 20:53:52 +00003629 /* dictionaries shouldn't have duplicate keys */
3630 flags = DB_NOOVERWRITE;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003631 retval = _DB_put(self, NULL, &key, &data, flags);
3632
3633 if ((retval == -1) && (self->setflags & (DB_DUP|DB_DUPSORT))) {
Barry Warsaw9a0d7792002-12-30 20:53:52 +00003634 /* try deleting any old record that matches and then PUT it
3635 * again... */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003636 _DB_delete(self, NULL, &key, 0);
3637 PyErr_Clear();
3638 retval = _DB_put(self, NULL, &key, &data, flags);
3639 }
3640 }
3641 }
3642 else {
3643 /* dataobj == NULL, so delete the key */
3644 retval = _DB_delete(self, NULL, &key, 0);
3645 }
3646 FREE_DBT(key);
3647 return retval;
3648}
3649
3650
3651static PyObject*
Jesus Cea6557aac2010-03-22 14:22:26 +00003652_DB_has_key(DBObject* self, PyObject* keyobj, PyObject* txnobj)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003653{
3654 int err;
Jesus Cea6557aac2010-03-22 14:22:26 +00003655 DBT key;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003656 DB_TXN *txn = NULL;
Jesus Cea4907d272008-08-31 14:00:51 +00003657
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003658 CHECK_DB_NOT_CLOSED(self);
3659 if (!make_key_dbt(self, keyobj, &key, NULL))
3660 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00003661 if (!checkTxnObj(txnobj, &txn)) {
3662 FREE_DBT(key);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003663 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00003664 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003665
Jesus Cea6557aac2010-03-22 14:22:26 +00003666#if (DBVER < 46)
Gregory P. Smith8b7e9172004-12-13 09:51:23 +00003667 /* This causes DB_BUFFER_SMALL to be returned when the db has the key because
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003668 it has a record but can't allocate a buffer for the data. This saves
3669 having to deal with data we won't be using.
3670 */
Jesus Cea6557aac2010-03-22 14:22:26 +00003671 {
3672 DBT data ;
3673 CLEAR_DBT(data);
3674 data.flags = DB_DBT_USERMEM;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003675
Jesus Cea6557aac2010-03-22 14:22:26 +00003676 MYDB_BEGIN_ALLOW_THREADS;
3677 err = self->db->get(self->db, txn, &key, &data, 0);
3678 MYDB_END_ALLOW_THREADS;
3679 }
3680#else
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003681 MYDB_BEGIN_ALLOW_THREADS;
Jesus Cea6557aac2010-03-22 14:22:26 +00003682 err = self->db->exists(self->db, txn, &key, 0);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003683 MYDB_END_ALLOW_THREADS;
Jesus Cea6557aac2010-03-22 14:22:26 +00003684#endif
3685
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003686 FREE_DBT(key);
Gregory P. Smithe9477062005-06-04 06:46:59 +00003687
Jesus Cea6557aac2010-03-22 14:22:26 +00003688 /*
3689 ** DB_BUFFER_SMALL is only used if we use "get".
3690 ** We can drop it when we only use "exists",
Martin Panter8d496ad2016-06-02 10:35:44 +00003691 ** when we drop support for Berkeley DB < 4.6.
Jesus Cea6557aac2010-03-22 14:22:26 +00003692 */
Gregory P. Smithe9477062005-06-04 06:46:59 +00003693 if (err == DB_BUFFER_SMALL || err == 0) {
Jesus Cea6557aac2010-03-22 14:22:26 +00003694 Py_INCREF(Py_True);
3695 return Py_True;
Gregory P. Smithe9477062005-06-04 06:46:59 +00003696 } else if (err == DB_NOTFOUND || err == DB_KEYEMPTY) {
Jesus Cea6557aac2010-03-22 14:22:26 +00003697 Py_INCREF(Py_False);
3698 return Py_False;
Gregory P. Smithe9477062005-06-04 06:46:59 +00003699 }
3700
3701 makeDBError(err);
3702 return NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003703}
3704
Jesus Cea6557aac2010-03-22 14:22:26 +00003705static PyObject*
3706DB_has_key(DBObject* self, PyObject* args, PyObject* kwargs)
3707{
3708 PyObject* keyobj;
3709 PyObject* txnobj = NULL;
3710 static char* kwnames[] = {"key","txn", NULL};
3711
3712 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O:has_key", kwnames,
3713 &keyobj, &txnobj))
3714 return NULL;
3715
3716 return _DB_has_key(self, keyobj, txnobj);
3717}
3718
3719
3720static int DB_contains(DBObject* self, PyObject* keyobj)
3721{
3722 PyObject* result;
3723 int result2 = 0;
3724
3725 result = _DB_has_key(self, keyobj, NULL) ;
3726 if (result == NULL) {
3727 return -1; /* Propague exception */
3728 }
3729 if (result != Py_False) {
3730 result2 = 1;
3731 }
3732
3733 Py_DECREF(result);
3734 return result2;
3735}
3736
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003737
3738#define _KEYS_LIST 1
3739#define _VALUES_LIST 2
3740#define _ITEMS_LIST 3
3741
3742static PyObject*
3743_DB_make_list(DBObject* self, DB_TXN* txn, int type)
3744{
3745 int err, dbtype;
3746 DBT key;
3747 DBT data;
3748 DBC *cursor;
3749 PyObject* list;
3750 PyObject* item = NULL;
3751
3752 CHECK_DB_NOT_CLOSED(self);
3753 CLEAR_DBT(key);
3754 CLEAR_DBT(data);
3755
3756 dbtype = _DB_get_type(self);
3757 if (dbtype == -1)
3758 return NULL;
3759
3760 list = PyList_New(0);
Thomas Woutersb3153832006-03-08 01:47:19 +00003761 if (list == NULL)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003762 return NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003763
3764 /* get a cursor */
3765 MYDB_BEGIN_ALLOW_THREADS;
Gregory P. Smith442c9fc2004-09-04 01:36:59 +00003766 err = self->db->cursor(self->db, txn, &cursor, 0);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003767 MYDB_END_ALLOW_THREADS;
Thomas Woutersb3153832006-03-08 01:47:19 +00003768 if (makeDBError(err)) {
3769 Py_DECREF(list);
3770 return NULL;
3771 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003772
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003773 while (1) { /* use the cursor to traverse the DB, collecting items */
3774 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00003775 err = _DBC_get(cursor, &key, &data, DB_NEXT);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003776 MYDB_END_ALLOW_THREADS;
3777
3778 if (err) {
3779 /* for any error, break out of the loop */
3780 break;
3781 }
3782
3783 switch (type) {
3784 case _KEYS_LIST:
3785 switch(dbtype) {
3786 case DB_BTREE:
3787 case DB_HASH:
3788 default:
Jesus Ceaef9764f2008-05-13 18:45:46 +00003789 item = Build_PyString(key.data, key.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003790 break;
3791 case DB_RECNO:
3792 case DB_QUEUE:
Jesus Ceac5a11fa2008-07-23 11:38:42 +00003793 item = NUMBER_FromLong(*((db_recno_t*)key.data));
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003794 break;
3795 }
3796 break;
3797
3798 case _VALUES_LIST:
Jesus Ceaef9764f2008-05-13 18:45:46 +00003799 item = Build_PyString(data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003800 break;
3801
3802 case _ITEMS_LIST:
3803 switch(dbtype) {
3804 case DB_BTREE:
3805 case DB_HASH:
3806 default:
Jesus Ceaef9764f2008-05-13 18:45:46 +00003807 item = BuildValue_SS(key.data, key.size, data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003808 break;
3809 case DB_RECNO:
3810 case DB_QUEUE:
Jesus Ceaef9764f2008-05-13 18:45:46 +00003811 item = BuildValue_IS(*((db_recno_t*)key.data), data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003812 break;
3813 }
3814 break;
Thomas Woutersb3153832006-03-08 01:47:19 +00003815 default:
3816 PyErr_Format(PyExc_ValueError, "Unknown key type 0x%x", type);
3817 item = NULL;
3818 break;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003819 }
3820 if (item == NULL) {
3821 Py_DECREF(list);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003822 list = NULL;
3823 goto done;
3824 }
Jesus Ceac5a11fa2008-07-23 11:38:42 +00003825 if (PyList_Append(list, item)) {
3826 Py_DECREF(list);
3827 Py_DECREF(item);
3828 list = NULL;
3829 goto done;
3830 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003831 Py_DECREF(item);
3832 }
3833
Gregory P. Smithe9477062005-06-04 06:46:59 +00003834 /* DB_NOTFOUND || DB_KEYEMPTY is okay, it means we got to the end */
3835 if (err != DB_NOTFOUND && err != DB_KEYEMPTY && makeDBError(err)) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003836 Py_DECREF(list);
3837 list = NULL;
3838 }
3839
3840 done:
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003841 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00003842 _DBC_close(cursor);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003843 MYDB_END_ALLOW_THREADS;
3844 return list;
3845}
3846
3847
3848static PyObject*
3849DB_keys(DBObject* self, PyObject* args)
3850{
3851 PyObject* txnobj = NULL;
3852 DB_TXN *txn = NULL;
3853
Georg Brandl96a8c392006-05-29 21:04:52 +00003854 if (!PyArg_UnpackTuple(args, "keys", 0, 1, &txnobj))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003855 return NULL;
3856 if (!checkTxnObj(txnobj, &txn))
3857 return NULL;
3858 return _DB_make_list(self, txn, _KEYS_LIST);
3859}
3860
3861
3862static PyObject*
3863DB_items(DBObject* self, PyObject* args)
3864{
3865 PyObject* txnobj = NULL;
3866 DB_TXN *txn = NULL;
3867
Georg Brandl96a8c392006-05-29 21:04:52 +00003868 if (!PyArg_UnpackTuple(args, "items", 0, 1, &txnobj))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003869 return NULL;
3870 if (!checkTxnObj(txnobj, &txn))
3871 return NULL;
3872 return _DB_make_list(self, txn, _ITEMS_LIST);
3873}
3874
3875
3876static PyObject*
3877DB_values(DBObject* self, PyObject* args)
3878{
3879 PyObject* txnobj = NULL;
3880 DB_TXN *txn = NULL;
3881
Georg Brandl96a8c392006-05-29 21:04:52 +00003882 if (!PyArg_UnpackTuple(args, "values", 0, 1, &txnobj))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003883 return NULL;
3884 if (!checkTxnObj(txnobj, &txn))
3885 return NULL;
3886 return _DB_make_list(self, txn, _VALUES_LIST);
3887}
3888
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003889/* --------------------------------------------------------------------- */
Jesus Cea6557aac2010-03-22 14:22:26 +00003890/* DBLogCursor methods */
3891
3892
3893static PyObject*
3894DBLogCursor_close_internal(DBLogCursorObject* self)
3895{
3896 int err = 0;
3897
3898 if (self->logc != NULL) {
3899 EXTRACT_FROM_DOUBLE_LINKED_LIST(self);
3900
3901 MYDB_BEGIN_ALLOW_THREADS;
3902 err = self->logc->close(self->logc, 0);
3903 MYDB_END_ALLOW_THREADS;
3904 self->logc = NULL;
3905 }
3906 RETURN_IF_ERR();
3907 RETURN_NONE();
3908}
3909
3910static PyObject*
3911DBLogCursor_close(DBLogCursorObject* self)
3912{
3913 return DBLogCursor_close_internal(self);
3914}
3915
3916
3917static PyObject*
3918_DBLogCursor_get(DBLogCursorObject* self, int flag, DB_LSN *lsn2)
3919{
3920 int err;
3921 DBT data;
3922 DB_LSN lsn = {0, 0};
3923 PyObject *dummy, *retval;
3924
3925 CLEAR_DBT(data);
3926 data.flags = DB_DBT_MALLOC; /* Berkeley DB must do the malloc */
3927
3928 CHECK_LOGCURSOR_NOT_CLOSED(self);
3929
3930 if (lsn2)
3931 lsn = *lsn2;
3932
3933 MYDB_BEGIN_ALLOW_THREADS;
3934 err = self->logc->get(self->logc, &lsn, &data, flag);
3935 MYDB_END_ALLOW_THREADS;
3936
3937 if (err == DB_NOTFOUND) {
3938 Py_INCREF(Py_None);
3939 retval = Py_None;
3940 }
3941 else if (makeDBError(err)) {
3942 retval = NULL;
3943 }
3944 else {
3945 retval = dummy = BuildValue_S(data.data, data.size);
3946 if (dummy) {
3947 retval = Py_BuildValue("(ii)O", lsn.file, lsn.offset, dummy);
3948 Py_DECREF(dummy);
3949 }
3950 }
3951
3952 FREE_DBT(data);
3953 return retval;
3954}
3955
3956static PyObject*
3957DBLogCursor_current(DBLogCursorObject* self)
3958{
3959 return _DBLogCursor_get(self, DB_CURRENT, NULL);
3960}
3961
3962static PyObject*
3963DBLogCursor_first(DBLogCursorObject* self)
3964{
3965 return _DBLogCursor_get(self, DB_FIRST, NULL);
3966}
3967
3968static PyObject*
3969DBLogCursor_last(DBLogCursorObject* self)
3970{
3971 return _DBLogCursor_get(self, DB_LAST, NULL);
3972}
3973
3974static PyObject*
3975DBLogCursor_next(DBLogCursorObject* self)
3976{
3977 return _DBLogCursor_get(self, DB_NEXT, NULL);
3978}
3979
3980static PyObject*
3981DBLogCursor_prev(DBLogCursorObject* self)
3982{
3983 return _DBLogCursor_get(self, DB_PREV, NULL);
3984}
3985
3986static PyObject*
3987DBLogCursor_set(DBLogCursorObject* self, PyObject* args)
3988{
3989 DB_LSN lsn;
3990
3991 if (!PyArg_ParseTuple(args, "(ii):set", &lsn.file, &lsn.offset))
3992 return NULL;
3993
3994 return _DBLogCursor_get(self, DB_SET, &lsn);
3995}
3996
3997
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07003998/* --------------------------------------------------------------------- */
3999/* DBSite methods */
4000
4001
4002#if (DBVER >= 52)
4003static PyObject*
4004DBSite_close_internal(DBSiteObject* self)
4005{
4006 int err = 0;
4007
4008 if (self->site != NULL) {
4009 EXTRACT_FROM_DOUBLE_LINKED_LIST(self);
4010
4011 MYDB_BEGIN_ALLOW_THREADS;
4012 err = self->site->close(self->site);
4013 MYDB_END_ALLOW_THREADS;
4014 self->site = NULL;
4015 }
4016 RETURN_IF_ERR();
4017 RETURN_NONE();
4018}
4019
4020static PyObject*
4021DBSite_close(DBSiteObject* self)
4022{
4023 return DBSite_close_internal(self);
4024}
4025
4026static PyObject*
4027DBSite_remove(DBSiteObject* self)
4028{
4029 int err = 0;
4030
4031 CHECK_SITE_NOT_CLOSED(self);
4032
4033 MYDB_BEGIN_ALLOW_THREADS;
4034 err = self->site->remove(self->site);
4035 MYDB_END_ALLOW_THREADS;
4036
4037 RETURN_IF_ERR();
4038 RETURN_NONE();
4039}
4040
4041static PyObject*
4042DBSite_get_eid(DBSiteObject* self)
4043{
4044 int err = 0;
4045 int eid;
4046
4047 CHECK_SITE_NOT_CLOSED(self);
4048
4049 MYDB_BEGIN_ALLOW_THREADS;
4050 err = self->site->get_eid(self->site, &eid);
4051 MYDB_END_ALLOW_THREADS;
4052
4053 RETURN_IF_ERR();
4054 return NUMBER_FromLong(eid);
4055}
4056
4057static PyObject*
4058DBSite_get_address(DBSiteObject* self)
4059{
4060 int err = 0;
4061 const char *host;
4062 u_int port;
4063
4064 CHECK_SITE_NOT_CLOSED(self);
4065
4066 MYDB_BEGIN_ALLOW_THREADS;
4067 err = self->site->get_address(self->site, &host, &port);
4068 MYDB_END_ALLOW_THREADS;
4069
4070 RETURN_IF_ERR();
4071
4072 return Py_BuildValue("(sI)", host, port);
4073}
4074
4075static PyObject*
4076DBSite_get_config(DBSiteObject* self, PyObject* args, PyObject* kwargs)
4077{
4078 int err = 0;
4079 u_int32_t which, value;
4080 static char* kwnames[] = { "which", NULL };
4081
4082 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i:get_config", kwnames,
4083 &which))
4084 return NULL;
4085
4086 CHECK_SITE_NOT_CLOSED(self);
4087
4088 MYDB_BEGIN_ALLOW_THREADS;
4089 err = self->site->get_config(self->site, which, &value);
4090 MYDB_END_ALLOW_THREADS;
4091
4092 RETURN_IF_ERR();
4093
4094 if (value) {
4095 Py_INCREF(Py_True);
4096 return Py_True;
4097 } else {
4098 Py_INCREF(Py_False);
4099 return Py_False;
4100 }
4101}
4102
4103static PyObject*
4104DBSite_set_config(DBSiteObject* self, PyObject* args, PyObject* kwargs)
4105{
4106 int err = 0;
4107 u_int32_t which, value;
4108 PyObject *valueO;
4109 static char* kwnames[] = { "which", "value", NULL };
4110
4111 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "iO:set_config", kwnames,
4112 &which, &valueO))
4113 return NULL;
4114
4115 CHECK_SITE_NOT_CLOSED(self);
4116
4117 value = PyObject_IsTrue(valueO);
4118
4119 MYDB_BEGIN_ALLOW_THREADS;
4120 err = self->site->set_config(self->site, which, value);
4121 MYDB_END_ALLOW_THREADS;
4122
4123 RETURN_IF_ERR();
4124 RETURN_NONE();
4125}
4126#endif
4127
Jesus Cea6557aac2010-03-22 14:22:26 +00004128
4129/* --------------------------------------------------------------------- */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004130/* DBCursor methods */
4131
4132
4133static PyObject*
Jesus Ceaef9764f2008-05-13 18:45:46 +00004134DBC_close_internal(DBCursorObject* self)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004135{
4136 int err = 0;
4137
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004138 if (self->dbc != NULL) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00004139 EXTRACT_FROM_DOUBLE_LINKED_LIST(self);
4140 if (self->txn) {
4141 EXTRACT_FROM_DOUBLE_LINKED_LIST_TXN(self);
4142 self->txn=NULL;
4143 }
4144
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004145 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004146 err = _DBC_close(self->dbc);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004147 MYDB_END_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004148 self->dbc = NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004149 }
4150 RETURN_IF_ERR();
4151 RETURN_NONE();
4152}
4153
Jesus Ceaef9764f2008-05-13 18:45:46 +00004154static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00004155DBC_close(DBCursorObject* self)
Jesus Ceaef9764f2008-05-13 18:45:46 +00004156{
Jesus Ceaef9764f2008-05-13 18:45:46 +00004157 return DBC_close_internal(self);
4158}
4159
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004160
4161static PyObject*
4162DBC_count(DBCursorObject* self, PyObject* args)
4163{
4164 int err = 0;
4165 db_recno_t count;
4166 int flags = 0;
4167
4168 if (!PyArg_ParseTuple(args, "|i:count", &flags))
4169 return NULL;
4170
4171 CHECK_CURSOR_NOT_CLOSED(self);
4172
4173 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004174 err = _DBC_count(self->dbc, &count, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004175 MYDB_END_ALLOW_THREADS;
4176 RETURN_IF_ERR();
4177
Jesus Ceac5a11fa2008-07-23 11:38:42 +00004178 return NUMBER_FromLong(count);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004179}
4180
4181
4182static PyObject*
4183DBC_current(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4184{
4185 return _DBCursor_get(self,DB_CURRENT,args,kwargs,"|iii:current");
4186}
4187
4188
4189static PyObject*
4190DBC_delete(DBCursorObject* self, PyObject* args)
4191{
4192 int err, flags=0;
4193
4194 if (!PyArg_ParseTuple(args, "|i:delete", &flags))
4195 return NULL;
4196
4197 CHECK_CURSOR_NOT_CLOSED(self);
4198
4199 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004200 err = _DBC_del(self->dbc, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004201 MYDB_END_ALLOW_THREADS;
4202 RETURN_IF_ERR();
4203
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004204 RETURN_NONE();
4205}
4206
4207
4208static PyObject*
4209DBC_dup(DBCursorObject* self, PyObject* args)
4210{
4211 int err, flags =0;
4212 DBC* dbc = NULL;
4213
4214 if (!PyArg_ParseTuple(args, "|i:dup", &flags))
4215 return NULL;
4216
4217 CHECK_CURSOR_NOT_CLOSED(self);
4218
4219 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004220 err = _DBC_dup(self->dbc, &dbc, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004221 MYDB_END_ALLOW_THREADS;
4222 RETURN_IF_ERR();
4223
Jesus Ceaef9764f2008-05-13 18:45:46 +00004224 return (PyObject*) newDBCursorObject(dbc, self->txn, self->mydb);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004225}
4226
4227static PyObject*
4228DBC_first(DBCursorObject* self, PyObject* args, PyObject* kwargs)
4229{
4230 return _DBCursor_get(self,DB_FIRST,args,kwargs,"|iii:first");
4231}
4232
4233
4234static PyObject*
4235DBC_get(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4236{
Martin v. Löwisb2c7aff2002-11-23 11:26:07 +00004237 int err, flags=0;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004238 PyObject* keyobj = NULL;
4239 PyObject* dataobj = NULL;
4240 PyObject* retval = NULL;
4241 int dlen = -1;
4242 int doff = -1;
4243 DBT key, data;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00004244 static char* kwnames[] = { "key","data", "flags", "dlen", "doff",
Jeremy Hyltonaf68c872005-12-10 18:50:16 +00004245 NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004246
4247 CLEAR_DBT(key);
4248 CLEAR_DBT(data);
4249 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|ii:get", &kwnames[2],
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004250 &flags, &dlen, &doff))
Barry Warsaw9a0d7792002-12-30 20:53:52 +00004251 {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004252 PyErr_Clear();
Barry Warsaw9a0d7792002-12-30 20:53:52 +00004253 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Oi|ii:get",
Jesus Cea4907d272008-08-31 14:00:51 +00004254 &kwnames[1],
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004255 &keyobj, &flags, &dlen, &doff))
Barry Warsaw9a0d7792002-12-30 20:53:52 +00004256 {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004257 PyErr_Clear();
Barry Warsaw9a0d7792002-12-30 20:53:52 +00004258 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OOi|ii:get",
4259 kwnames, &keyobj, &dataobj,
4260 &flags, &dlen, &doff))
4261 {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004262 return NULL;
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004263 }
4264 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004265 }
4266
4267 CHECK_CURSOR_NOT_CLOSED(self);
4268
4269 if (keyobj && !make_key_dbt(self->mydb, keyobj, &key, NULL))
4270 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004271 if ( (dataobj && !make_dbt(dataobj, &data)) ||
4272 (!add_partial_dbt(&data, dlen, doff)) )
4273 {
Jesus Ceaef9764f2008-05-13 18:45:46 +00004274 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004275 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004276 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004277
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004278 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004279 err = _DBC_get(self->dbc, &key, &data, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004280 MYDB_END_ALLOW_THREADS;
4281
Gregory P. Smithe9477062005-06-04 06:46:59 +00004282 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004283 && self->mydb->moduleFlags.getReturnsNone) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004284 Py_INCREF(Py_None);
4285 retval = Py_None;
4286 }
4287 else if (makeDBError(err)) {
4288 retval = NULL;
4289 }
4290 else {
4291 switch (_DB_get_type(self->mydb)) {
4292 case -1:
4293 retval = NULL;
4294 break;
4295 case DB_BTREE:
4296 case DB_HASH:
4297 default:
Jesus Ceaef9764f2008-05-13 18:45:46 +00004298 retval = BuildValue_SS(key.data, key.size, data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004299 break;
4300 case DB_RECNO:
4301 case DB_QUEUE:
Jesus Ceaef9764f2008-05-13 18:45:46 +00004302 retval = BuildValue_IS(*((db_recno_t*)key.data), data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004303 break;
4304 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004305 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00004306 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004307 return retval;
4308}
4309
Gregory P. Smith19699a92004-06-28 04:06:49 +00004310static PyObject*
4311DBC_pget(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4312{
4313 int err, flags=0;
4314 PyObject* keyobj = NULL;
4315 PyObject* dataobj = NULL;
4316 PyObject* retval = NULL;
4317 int dlen = -1;
4318 int doff = -1;
4319 DBT key, pkey, data;
Gregory P. Smith372b5832006-06-05 18:48:21 +00004320 static char* kwnames_keyOnly[] = { "key", "flags", "dlen", "doff", NULL };
4321 static char* kwnames[] = { "key", "data", "flags", "dlen", "doff", NULL };
Gregory P. Smith19699a92004-06-28 04:06:49 +00004322
4323 CLEAR_DBT(key);
4324 CLEAR_DBT(data);
4325 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|ii:pget", &kwnames[2],
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004326 &flags, &dlen, &doff))
Gregory P. Smith19699a92004-06-28 04:06:49 +00004327 {
4328 PyErr_Clear();
4329 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Oi|ii:pget",
Jesus Cea6557aac2010-03-22 14:22:26 +00004330 kwnames_keyOnly,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004331 &keyobj, &flags, &dlen, &doff))
Gregory P. Smith19699a92004-06-28 04:06:49 +00004332 {
4333 PyErr_Clear();
4334 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OOi|ii:pget",
4335 kwnames, &keyobj, &dataobj,
4336 &flags, &dlen, &doff))
4337 {
4338 return NULL;
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004339 }
4340 }
Gregory P. Smith19699a92004-06-28 04:06:49 +00004341 }
4342
4343 CHECK_CURSOR_NOT_CLOSED(self);
4344
4345 if (keyobj && !make_key_dbt(self->mydb, keyobj, &key, NULL))
4346 return NULL;
4347 if ( (dataobj && !make_dbt(dataobj, &data)) ||
4348 (!add_partial_dbt(&data, dlen, doff)) ) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00004349 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Gregory P. Smith19699a92004-06-28 04:06:49 +00004350 return NULL;
4351 }
4352
Gregory P. Smith19699a92004-06-28 04:06:49 +00004353 CLEAR_DBT(pkey);
4354 pkey.flags = DB_DBT_MALLOC;
4355
4356 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004357 err = _DBC_pget(self->dbc, &key, &pkey, &data, flags);
Gregory P. Smith19699a92004-06-28 04:06:49 +00004358 MYDB_END_ALLOW_THREADS;
4359
Gregory P. Smithe9477062005-06-04 06:46:59 +00004360 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004361 && self->mydb->moduleFlags.getReturnsNone) {
Gregory P. Smith19699a92004-06-28 04:06:49 +00004362 Py_INCREF(Py_None);
4363 retval = Py_None;
4364 }
4365 else if (makeDBError(err)) {
4366 retval = NULL;
4367 }
4368 else {
4369 PyObject *pkeyObj;
4370 PyObject *dataObj;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004371 dataObj = Build_PyString(data.data, data.size);
Gregory P. Smith19699a92004-06-28 04:06:49 +00004372
4373 if (self->mydb->primaryDBType == DB_RECNO ||
4374 self->mydb->primaryDBType == DB_QUEUE)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00004375 pkeyObj = NUMBER_FromLong(*(int *)pkey.data);
Gregory P. Smith19699a92004-06-28 04:06:49 +00004376 else
Jesus Ceaef9764f2008-05-13 18:45:46 +00004377 pkeyObj = Build_PyString(pkey.data, pkey.size);
Gregory P. Smith19699a92004-06-28 04:06:49 +00004378
Gregory P. Smith4e414d82006-01-24 19:55:02 +00004379 if (key.data && key.size) /* return key, pkey and data */
Gregory P. Smith19699a92004-06-28 04:06:49 +00004380 {
4381 PyObject *keyObj;
4382 int type = _DB_get_type(self->mydb);
4383 if (type == DB_RECNO || type == DB_QUEUE)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00004384 keyObj = NUMBER_FromLong(*(int *)key.data);
Gregory P. Smith19699a92004-06-28 04:06:49 +00004385 else
Jesus Ceaef9764f2008-05-13 18:45:46 +00004386 keyObj = Build_PyString(key.data, key.size);
Gregory P. Smith4e414d82006-01-24 19:55:02 +00004387 retval = PyTuple_Pack(3, keyObj, pkeyObj, dataObj);
Thomas Woutersb3153832006-03-08 01:47:19 +00004388 Py_DECREF(keyObj);
Jesus Ceaef9764f2008-05-13 18:45:46 +00004389 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Gregory P. Smith19699a92004-06-28 04:06:49 +00004390 }
4391 else /* return just the pkey and data */
4392 {
Gregory P. Smith4e414d82006-01-24 19:55:02 +00004393 retval = PyTuple_Pack(2, pkeyObj, dataObj);
Gregory P. Smith19699a92004-06-28 04:06:49 +00004394 }
Thomas Woutersb3153832006-03-08 01:47:19 +00004395 Py_DECREF(dataObj);
4396 Py_DECREF(pkeyObj);
Gregory P. Smith19699a92004-06-28 04:06:49 +00004397 FREE_DBT(pkey);
Gregory P. Smith19699a92004-06-28 04:06:49 +00004398 }
4399 /* the only time REALLOC should be set is if we used an integer
4400 * key that make_key_dbt malloc'd for us. always free these. */
Jesus Ceaef9764f2008-05-13 18:45:46 +00004401 if (key.flags & DB_DBT_REALLOC) { /* 'make_key_dbt' could do a 'malloc' */
Gregory P. Smith19699a92004-06-28 04:06:49 +00004402 FREE_DBT(key);
4403 }
4404 return retval;
4405}
4406
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004407
4408static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00004409DBC_get_recno(DBCursorObject* self)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004410{
4411 int err;
4412 db_recno_t recno;
4413 DBT key;
4414 DBT data;
4415
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004416 CHECK_CURSOR_NOT_CLOSED(self);
4417
4418 CLEAR_DBT(key);
4419 CLEAR_DBT(data);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004420
4421 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004422 err = _DBC_get(self->dbc, &key, &data, DB_GET_RECNO);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004423 MYDB_END_ALLOW_THREADS;
4424 RETURN_IF_ERR();
4425
4426 recno = *((db_recno_t*)data.data);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00004427 return NUMBER_FromLong(recno);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004428}
4429
4430
4431static PyObject*
4432DBC_last(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4433{
4434 return _DBCursor_get(self,DB_LAST,args,kwargs,"|iii:last");
4435}
4436
4437
4438static PyObject*
4439DBC_next(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4440{
4441 return _DBCursor_get(self,DB_NEXT,args,kwargs,"|iii:next");
4442}
4443
4444
4445static PyObject*
4446DBC_prev(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4447{
4448 return _DBCursor_get(self,DB_PREV,args,kwargs,"|iii:prev");
4449}
4450
4451
4452static PyObject*
4453DBC_put(DBCursorObject* self, PyObject* args, PyObject* kwargs)
4454{
4455 int err, flags = 0;
4456 PyObject* keyobj, *dataobj;
4457 DBT key, data;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00004458 static char* kwnames[] = { "key", "data", "flags", "dlen", "doff",
Jeremy Hyltonaf68c872005-12-10 18:50:16 +00004459 NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004460 int dlen = -1;
4461 int doff = -1;
4462
4463 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|iii:put", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004464 &keyobj, &dataobj, &flags, &dlen, &doff))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004465 return NULL;
4466
4467 CHECK_CURSOR_NOT_CLOSED(self);
4468
4469 if (!make_key_dbt(self->mydb, keyobj, &key, NULL))
4470 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004471 if (!make_dbt(dataobj, &data) ||
4472 !add_partial_dbt(&data, dlen, doff) )
4473 {
Jesus Ceaef9764f2008-05-13 18:45:46 +00004474 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004475 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004476 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004477
4478 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004479 err = _DBC_put(self->dbc, &key, &data, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004480 MYDB_END_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004481 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004482 RETURN_IF_ERR();
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004483 RETURN_NONE();
4484}
4485
4486
4487static PyObject*
4488DBC_set(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4489{
4490 int err, flags = 0;
4491 DBT key, data;
4492 PyObject* retval, *keyobj;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00004493 static char* kwnames[] = { "key", "flags", "dlen", "doff", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004494 int dlen = -1;
4495 int doff = -1;
4496
4497 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|iii:set", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004498 &keyobj, &flags, &dlen, &doff))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004499 return NULL;
4500
4501 CHECK_CURSOR_NOT_CLOSED(self);
4502
4503 if (!make_key_dbt(self->mydb, keyobj, &key, NULL))
4504 return NULL;
4505
4506 CLEAR_DBT(data);
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004507 if (!add_partial_dbt(&data, dlen, doff)) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00004508 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004509 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004510 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004511
4512 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004513 err = _DBC_get(self->dbc, &key, &data, flags|DB_SET);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004514 MYDB_END_ALLOW_THREADS;
Gregory P. Smithe9477062005-06-04 06:46:59 +00004515 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004516 && self->mydb->moduleFlags.cursorSetReturnsNone) {
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004517 Py_INCREF(Py_None);
4518 retval = Py_None;
4519 }
4520 else if (makeDBError(err)) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004521 retval = NULL;
4522 }
4523 else {
4524 switch (_DB_get_type(self->mydb)) {
4525 case -1:
4526 retval = NULL;
4527 break;
4528 case DB_BTREE:
4529 case DB_HASH:
4530 default:
Jesus Ceaef9764f2008-05-13 18:45:46 +00004531 retval = BuildValue_SS(key.data, key.size, data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004532 break;
4533 case DB_RECNO:
4534 case DB_QUEUE:
Jesus Ceaef9764f2008-05-13 18:45:46 +00004535 retval = BuildValue_IS(*((db_recno_t*)key.data), data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004536 break;
4537 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00004538 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004539 }
Gregory P. Smith19699a92004-06-28 04:06:49 +00004540 /* the only time REALLOC should be set is if we used an integer
4541 * key that make_key_dbt malloc'd for us. always free these. */
4542 if (key.flags & DB_DBT_REALLOC) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00004543 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Gregory P. Smith19699a92004-06-28 04:06:49 +00004544 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004545
4546 return retval;
4547}
4548
4549
4550static PyObject*
4551DBC_set_range(DBCursorObject* self, PyObject* args, PyObject* kwargs)
4552{
4553 int err, flags = 0;
4554 DBT key, data;
4555 PyObject* retval, *keyobj;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00004556 static char* kwnames[] = { "key", "flags", "dlen", "doff", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004557 int dlen = -1;
4558 int doff = -1;
4559
4560 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|iii:set_range", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004561 &keyobj, &flags, &dlen, &doff))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004562 return NULL;
4563
4564 CHECK_CURSOR_NOT_CLOSED(self);
4565
4566 if (!make_key_dbt(self->mydb, keyobj, &key, NULL))
4567 return NULL;
4568
4569 CLEAR_DBT(data);
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004570 if (!add_partial_dbt(&data, dlen, doff)) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00004571 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004572 return NULL;
4573 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004574 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004575 err = _DBC_get(self->dbc, &key, &data, flags|DB_SET_RANGE);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004576 MYDB_END_ALLOW_THREADS;
Gregory P. Smithe9477062005-06-04 06:46:59 +00004577 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004578 && self->mydb->moduleFlags.cursorSetReturnsNone) {
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004579 Py_INCREF(Py_None);
4580 retval = Py_None;
4581 }
4582 else if (makeDBError(err)) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004583 retval = NULL;
4584 }
4585 else {
4586 switch (_DB_get_type(self->mydb)) {
4587 case -1:
4588 retval = NULL;
4589 break;
4590 case DB_BTREE:
4591 case DB_HASH:
4592 default:
Jesus Ceaef9764f2008-05-13 18:45:46 +00004593 retval = BuildValue_SS(key.data, key.size, data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004594 break;
4595 case DB_RECNO:
4596 case DB_QUEUE:
Jesus Ceaef9764f2008-05-13 18:45:46 +00004597 retval = BuildValue_IS(*((db_recno_t*)key.data), data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004598 break;
4599 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00004600 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004601 }
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004602 /* the only time REALLOC should be set is if we used an integer
Gregory P. Smith19699a92004-06-28 04:06:49 +00004603 * key that make_key_dbt malloc'd for us. always free these. */
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004604 if (key.flags & DB_DBT_REALLOC) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00004605 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004606 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004607
4608 return retval;
4609}
4610
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004611static PyObject*
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004612_DBC_get_set_both(DBCursorObject* self, PyObject* keyobj, PyObject* dataobj,
4613 int flags, unsigned int returnsNone)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004614{
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004615 int err;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004616 DBT key, data;
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004617 PyObject* retval;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004618
Gregory P. Smith7441e652003-11-03 21:35:31 +00004619 /* the caller did this: CHECK_CURSOR_NOT_CLOSED(self); */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004620 if (!make_key_dbt(self->mydb, keyobj, &key, NULL))
4621 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004622 if (!make_dbt(dataobj, &data)) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00004623 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004624 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004625 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004626
4627 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004628 err = _DBC_get(self->dbc, &key, &data, flags|DB_GET_BOTH);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004629 MYDB_END_ALLOW_THREADS;
Gregory P. Smithe9477062005-06-04 06:46:59 +00004630 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY) && returnsNone) {
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004631 Py_INCREF(Py_None);
4632 retval = Py_None;
4633 }
4634 else if (makeDBError(err)) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004635 retval = NULL;
4636 }
4637 else {
4638 switch (_DB_get_type(self->mydb)) {
4639 case -1:
4640 retval = NULL;
4641 break;
4642 case DB_BTREE:
4643 case DB_HASH:
4644 default:
Jesus Ceaef9764f2008-05-13 18:45:46 +00004645 retval = BuildValue_SS(key.data, key.size, data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004646 break;
4647 case DB_RECNO:
4648 case DB_QUEUE:
Jesus Ceaef9764f2008-05-13 18:45:46 +00004649 retval = BuildValue_IS(*((db_recno_t*)key.data), data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004650 break;
4651 }
4652 }
4653
Jesus Ceaef9764f2008-05-13 18:45:46 +00004654 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004655 return retval;
4656}
4657
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004658static PyObject*
4659DBC_get_both(DBCursorObject* self, PyObject* args)
4660{
4661 int flags=0;
4662 PyObject *keyobj, *dataobj;
4663
4664 if (!PyArg_ParseTuple(args, "OO|i:get_both", &keyobj, &dataobj, &flags))
4665 return NULL;
4666
Gregory P. Smith7441e652003-11-03 21:35:31 +00004667 /* if the cursor is closed, self->mydb may be invalid */
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004668 CHECK_CURSOR_NOT_CLOSED(self);
4669
4670 return _DBC_get_set_both(self, keyobj, dataobj, flags,
4671 self->mydb->moduleFlags.getReturnsNone);
4672}
4673
Gregory P. Smithbe0db8b2003-10-01 06:48:51 +00004674/* Return size of entry */
4675static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00004676DBC_get_current_size(DBCursorObject* self)
Gregory P. Smithbe0db8b2003-10-01 06:48:51 +00004677{
4678 int err, flags=DB_CURRENT;
4679 PyObject* retval = NULL;
4680 DBT key, data;
4681
Gregory P. Smithbe0db8b2003-10-01 06:48:51 +00004682 CHECK_CURSOR_NOT_CLOSED(self);
4683 CLEAR_DBT(key);
4684 CLEAR_DBT(data);
4685
Gregory P. Smith8b7e9172004-12-13 09:51:23 +00004686 /* We don't allocate any memory, forcing a DB_BUFFER_SMALL error and thus
Gregory P. Smithbe0db8b2003-10-01 06:48:51 +00004687 getting the record size. */
4688 data.flags = DB_DBT_USERMEM;
4689 data.ulen = 0;
4690 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004691 err = _DBC_get(self->dbc, &key, &data, flags);
Gregory P. Smithbe0db8b2003-10-01 06:48:51 +00004692 MYDB_END_ALLOW_THREADS;
Gregory P. Smith8b7e9172004-12-13 09:51:23 +00004693 if (err == DB_BUFFER_SMALL || !err) {
4694 /* DB_BUFFER_SMALL means positive size, !err means zero length value */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00004695 retval = NUMBER_FromLong((long)data.size);
Gregory P. Smithbe0db8b2003-10-01 06:48:51 +00004696 err = 0;
4697 }
4698
Gregory P. Smithbe0db8b2003-10-01 06:48:51 +00004699 RETURN_IF_ERR();
4700 return retval;
4701}
4702
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004703static PyObject*
4704DBC_set_both(DBCursorObject* self, PyObject* args)
4705{
4706 int flags=0;
4707 PyObject *keyobj, *dataobj;
4708
4709 if (!PyArg_ParseTuple(args, "OO|i:set_both", &keyobj, &dataobj, &flags))
4710 return NULL;
4711
Gregory P. Smith7441e652003-11-03 21:35:31 +00004712 /* if the cursor is closed, self->mydb may be invalid */
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004713 CHECK_CURSOR_NOT_CLOSED(self);
4714
4715 return _DBC_get_set_both(self, keyobj, dataobj, flags,
4716 self->mydb->moduleFlags.cursorSetReturnsNone);
4717}
4718
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004719
4720static PyObject*
4721DBC_set_recno(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4722{
4723 int err, irecno, flags=0;
4724 db_recno_t recno;
4725 DBT key, data;
4726 PyObject* retval;
4727 int dlen = -1;
4728 int doff = -1;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00004729 static char* kwnames[] = { "recno","flags", "dlen", "doff", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004730
4731 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|iii:set_recno", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004732 &irecno, &flags, &dlen, &doff))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004733 return NULL;
4734
4735 CHECK_CURSOR_NOT_CLOSED(self);
4736
4737 CLEAR_DBT(key);
4738 recno = (db_recno_t) irecno;
Barry Warsaw9a0d7792002-12-30 20:53:52 +00004739 /* use allocated space so DB will be able to realloc room for the real
4740 * key */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004741 key.data = malloc(sizeof(db_recno_t));
4742 if (key.data == NULL) {
4743 PyErr_SetString(PyExc_MemoryError, "Key memory allocation failed");
4744 return NULL;
4745 }
4746 key.size = sizeof(db_recno_t);
4747 key.ulen = key.size;
4748 memcpy(key.data, &recno, sizeof(db_recno_t));
4749 key.flags = DB_DBT_REALLOC;
4750
4751 CLEAR_DBT(data);
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004752 if (!add_partial_dbt(&data, dlen, doff)) {
4753 FREE_DBT(key);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004754 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004755 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004756
4757 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004758 err = _DBC_get(self->dbc, &key, &data, flags|DB_SET_RECNO);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004759 MYDB_END_ALLOW_THREADS;
Gregory P. Smithe9477062005-06-04 06:46:59 +00004760 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004761 && self->mydb->moduleFlags.cursorSetReturnsNone) {
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004762 Py_INCREF(Py_None);
4763 retval = Py_None;
4764 }
4765 else if (makeDBError(err)) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004766 retval = NULL;
4767 }
4768 else { /* Can only be used for BTrees, so no need to return int key */
Jesus Ceaef9764f2008-05-13 18:45:46 +00004769 retval = BuildValue_SS(key.data, key.size, data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004770 }
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004771 FREE_DBT(key);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004772
4773 return retval;
4774}
4775
4776
4777static PyObject*
4778DBC_consume(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4779{
4780 return _DBCursor_get(self,DB_CONSUME,args,kwargs,"|iii:consume");
4781}
4782
4783
4784static PyObject*
4785DBC_next_dup(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4786{
4787 return _DBCursor_get(self,DB_NEXT_DUP,args,kwargs,"|iii:next_dup");
4788}
4789
4790
4791static PyObject*
4792DBC_next_nodup(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4793{
4794 return _DBCursor_get(self,DB_NEXT_NODUP,args,kwargs,"|iii:next_nodup");
4795}
4796
Jesus Cea6557aac2010-03-22 14:22:26 +00004797#if (DBVER >= 46)
4798static PyObject*
4799DBC_prev_dup(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4800{
4801 return _DBCursor_get(self,DB_PREV_DUP,args,kwargs,"|iii:prev_dup");
4802}
4803#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004804
4805static PyObject*
4806DBC_prev_nodup(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4807{
4808 return _DBCursor_get(self,DB_PREV_NODUP,args,kwargs,"|iii:prev_nodup");
4809}
4810
4811
4812static PyObject*
4813DBC_join_item(DBCursorObject* self, PyObject* args)
4814{
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004815 int err, flags=0;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004816 DBT key, data;
4817 PyObject* retval;
4818
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004819 if (!PyArg_ParseTuple(args, "|i:join_item", &flags))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004820 return NULL;
4821
4822 CHECK_CURSOR_NOT_CLOSED(self);
4823
4824 CLEAR_DBT(key);
4825 CLEAR_DBT(data);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004826
4827 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004828 err = _DBC_get(self->dbc, &key, &data, flags | DB_JOIN_ITEM);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004829 MYDB_END_ALLOW_THREADS;
Gregory P. Smithe9477062005-06-04 06:46:59 +00004830 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004831 && self->mydb->moduleFlags.getReturnsNone) {
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004832 Py_INCREF(Py_None);
4833 retval = Py_None;
4834 }
4835 else if (makeDBError(err)) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004836 retval = NULL;
4837 }
4838 else {
Jesus Ceaef9764f2008-05-13 18:45:46 +00004839 retval = BuildValue_S(key.data, key.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004840 }
4841
4842 return retval;
4843}
4844
4845
Jesus Cea6557aac2010-03-22 14:22:26 +00004846#if (DBVER >= 46)
4847static PyObject*
4848DBC_set_priority(DBCursorObject* self, PyObject* args, PyObject* kwargs)
4849{
4850 int err, priority;
4851 static char* kwnames[] = { "priority", NULL };
4852
4853 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i:set_priority", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004854 &priority))
Jesus Cea6557aac2010-03-22 14:22:26 +00004855 return NULL;
4856
4857 CHECK_CURSOR_NOT_CLOSED(self);
4858
4859 MYDB_BEGIN_ALLOW_THREADS;
4860 err = self->dbc->set_priority(self->dbc, priority);
4861 MYDB_END_ALLOW_THREADS;
4862 RETURN_IF_ERR();
4863 RETURN_NONE();
4864}
4865
4866
4867static PyObject*
4868DBC_get_priority(DBCursorObject* self)
4869{
4870 int err;
4871 DB_CACHE_PRIORITY priority;
4872
4873 CHECK_CURSOR_NOT_CLOSED(self);
4874
4875 MYDB_BEGIN_ALLOW_THREADS;
4876 err = self->dbc->get_priority(self->dbc, &priority);
4877 MYDB_END_ALLOW_THREADS;
4878 RETURN_IF_ERR();
4879 return NUMBER_FromLong(priority);
4880}
4881#endif
4882
4883
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004884
4885/* --------------------------------------------------------------------- */
4886/* DBEnv methods */
4887
4888
4889static PyObject*
Jesus Ceaef9764f2008-05-13 18:45:46 +00004890DBEnv_close_internal(DBEnvObject* self, int flags)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004891{
Jesus Ceaef9764f2008-05-13 18:45:46 +00004892 PyObject *dummy;
4893 int err;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004894
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004895 if (!self->closed) { /* Don't close more than once */
Jesus Ceaef9764f2008-05-13 18:45:46 +00004896 while(self->children_txns) {
Jesus Cea6557aac2010-03-22 14:22:26 +00004897 dummy = DBTxn_abort_discard_internal(self->children_txns, 0);
4898 Py_XDECREF(dummy);
Jesus Ceaef9764f2008-05-13 18:45:46 +00004899 }
4900 while(self->children_dbs) {
Jesus Cea6557aac2010-03-22 14:22:26 +00004901 dummy = DB_close_internal(self->children_dbs, 0, 0);
4902 Py_XDECREF(dummy);
4903 }
4904 while(self->children_logcursors) {
4905 dummy = DBLogCursor_close_internal(self->children_logcursors);
4906 Py_XDECREF(dummy);
Jesus Ceaef9764f2008-05-13 18:45:46 +00004907 }
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07004908#if (DBVER >= 52)
4909 while(self->children_sites) {
4910 dummy = DBSite_close_internal(self->children_sites);
4911 Py_XDECREF(dummy);
4912 }
4913#endif
Jesus Ceaac25fab2008-09-03 17:50:32 +00004914 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00004915
Jesus Ceaac25fab2008-09-03 17:50:32 +00004916 self->closed = 1;
4917 if (self->db_env) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004918 MYDB_BEGIN_ALLOW_THREADS;
4919 err = self->db_env->close(self->db_env, flags);
4920 MYDB_END_ALLOW_THREADS;
4921 /* after calling DBEnv->close, regardless of error, this DBEnv
Jesus Ceaef9764f2008-05-13 18:45:46 +00004922 * may not be accessed again (Berkeley DB docs). */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004923 self->db_env = NULL;
4924 RETURN_IF_ERR();
4925 }
4926 RETURN_NONE();
4927}
4928
Jesus Ceaef9764f2008-05-13 18:45:46 +00004929static PyObject*
4930DBEnv_close(DBEnvObject* self, PyObject* args)
4931{
4932 int flags = 0;
4933
4934 if (!PyArg_ParseTuple(args, "|i:close", &flags))
4935 return NULL;
Jesus Cea5cd5f122008-09-23 18:54:08 +00004936 return DBEnv_close_internal(self, flags);
Jesus Ceaef9764f2008-05-13 18:45:46 +00004937}
4938
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004939
4940static PyObject*
4941DBEnv_open(DBEnvObject* self, PyObject* args)
4942{
4943 int err, flags=0, mode=0660;
4944 char *db_home;
4945
4946 if (!PyArg_ParseTuple(args, "z|ii:open", &db_home, &flags, &mode))
4947 return NULL;
4948
4949 CHECK_ENV_NOT_CLOSED(self);
4950
4951 MYDB_BEGIN_ALLOW_THREADS;
4952 err = self->db_env->open(self->db_env, db_home, flags, mode);
4953 MYDB_END_ALLOW_THREADS;
4954 RETURN_IF_ERR();
4955 self->closed = 0;
4956 self->flags = flags;
4957 RETURN_NONE();
4958}
4959
4960
4961static PyObject*
Jesus Cea6557aac2010-03-22 14:22:26 +00004962DBEnv_memp_stat(DBEnvObject* self, PyObject* args, PyObject *kwargs)
4963{
4964 int err;
4965 DB_MPOOL_STAT *gsp;
4966 DB_MPOOL_FSTAT **fsp, **fsp2;
4967 PyObject* d = NULL, *d2, *d3, *r;
4968 u_int32_t flags = 0;
4969 static char* kwnames[] = { "flags", NULL };
4970
4971 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:memp_stat",
4972 kwnames, &flags))
4973 return NULL;
4974
4975 CHECK_ENV_NOT_CLOSED(self);
4976
4977 MYDB_BEGIN_ALLOW_THREADS;
4978 err = self->db_env->memp_stat(self->db_env, &gsp, &fsp, flags);
4979 MYDB_END_ALLOW_THREADS;
4980 RETURN_IF_ERR();
4981
4982 /* Turn the stat structure into a dictionary */
4983 d = PyDict_New();
4984 if (d == NULL) {
4985 if (gsp)
4986 free(gsp);
4987 return NULL;
4988 }
4989
4990#define MAKE_ENTRY(name) _addIntToDict(d, #name, gsp->st_##name)
4991
4992 MAKE_ENTRY(gbytes);
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07004993 MAKE_ENTRY(bytes);
Jesus Cea6557aac2010-03-22 14:22:26 +00004994 MAKE_ENTRY(ncache);
4995#if (DBVER >= 46)
4996 MAKE_ENTRY(max_ncache);
4997#endif
4998 MAKE_ENTRY(regsize);
Jesus Cea6557aac2010-03-22 14:22:26 +00004999 MAKE_ENTRY(mmapsize);
5000 MAKE_ENTRY(maxopenfd);
5001 MAKE_ENTRY(maxwrite);
5002 MAKE_ENTRY(maxwrite_sleep);
Jesus Cea6557aac2010-03-22 14:22:26 +00005003 MAKE_ENTRY(map);
5004 MAKE_ENTRY(cache_hit);
5005 MAKE_ENTRY(cache_miss);
5006 MAKE_ENTRY(page_create);
5007 MAKE_ENTRY(page_in);
5008 MAKE_ENTRY(page_out);
5009 MAKE_ENTRY(ro_evict);
5010 MAKE_ENTRY(rw_evict);
5011 MAKE_ENTRY(page_trickle);
5012 MAKE_ENTRY(pages);
5013 MAKE_ENTRY(page_clean);
5014 MAKE_ENTRY(page_dirty);
5015 MAKE_ENTRY(hash_buckets);
5016 MAKE_ENTRY(hash_searches);
5017 MAKE_ENTRY(hash_longest);
5018 MAKE_ENTRY(hash_examined);
5019 MAKE_ENTRY(hash_nowait);
5020 MAKE_ENTRY(hash_wait);
5021#if (DBVER >= 45)
5022 MAKE_ENTRY(hash_max_nowait);
5023#endif
5024 MAKE_ENTRY(hash_max_wait);
5025 MAKE_ENTRY(region_wait);
5026 MAKE_ENTRY(region_nowait);
5027#if (DBVER >= 45)
5028 MAKE_ENTRY(mvcc_frozen);
5029 MAKE_ENTRY(mvcc_thawed);
5030 MAKE_ENTRY(mvcc_freed);
5031#endif
5032 MAKE_ENTRY(alloc);
5033 MAKE_ENTRY(alloc_buckets);
5034 MAKE_ENTRY(alloc_max_buckets);
5035 MAKE_ENTRY(alloc_pages);
5036 MAKE_ENTRY(alloc_max_pages);
5037#if (DBVER >= 45)
5038 MAKE_ENTRY(io_wait);
5039#endif
5040#if (DBVER >= 48)
5041 MAKE_ENTRY(sync_interrupted);
5042#endif
5043
5044#undef MAKE_ENTRY
5045 free(gsp);
5046
5047 d2 = PyDict_New();
5048 if (d2 == NULL) {
5049 Py_DECREF(d);
5050 if (fsp)
5051 free(fsp);
5052 return NULL;
5053 }
5054#define MAKE_ENTRY(name) _addIntToDict(d3, #name, (*fsp2)->st_##name)
5055 for(fsp2=fsp;*fsp2; fsp2++) {
5056 d3 = PyDict_New();
5057 if (d3 == NULL) {
5058 Py_DECREF(d);
5059 Py_DECREF(d2);
5060 if (fsp)
5061 free(fsp);
5062 return NULL;
5063 }
5064 MAKE_ENTRY(pagesize);
5065 MAKE_ENTRY(cache_hit);
5066 MAKE_ENTRY(cache_miss);
5067 MAKE_ENTRY(map);
5068 MAKE_ENTRY(page_create);
5069 MAKE_ENTRY(page_in);
5070 MAKE_ENTRY(page_out);
5071 if(PyDict_SetItemString(d2, (*fsp2)->file_name, d3)) {
5072 Py_DECREF(d);
5073 Py_DECREF(d2);
5074 Py_DECREF(d3);
5075 if (fsp)
5076 free(fsp);
5077 return NULL;
5078 }
5079 Py_DECREF(d3);
5080 }
5081
5082#undef MAKE_ENTRY
5083 free(fsp);
5084
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07005085 r = PyTuple_Pack(2, d, d2);
Jesus Cea6557aac2010-03-22 14:22:26 +00005086 Py_DECREF(d);
5087 Py_DECREF(d2);
5088 return r;
5089}
5090
Jesus Cea6557aac2010-03-22 14:22:26 +00005091static PyObject*
5092DBEnv_memp_stat_print(DBEnvObject* self, PyObject* args, PyObject *kwargs)
5093{
5094 int err;
5095 int flags=0;
5096 static char* kwnames[] = { "flags", NULL };
5097
5098 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:memp_stat_print",
5099 kwnames, &flags))
5100 {
5101 return NULL;
5102 }
5103 CHECK_ENV_NOT_CLOSED(self);
5104 MYDB_BEGIN_ALLOW_THREADS;
5105 err = self->db_env->memp_stat_print(self->db_env, flags);
5106 MYDB_END_ALLOW_THREADS;
5107 RETURN_IF_ERR();
5108 RETURN_NONE();
5109}
Jesus Cea6557aac2010-03-22 14:22:26 +00005110
5111
5112static PyObject*
5113DBEnv_memp_trickle(DBEnvObject* self, PyObject* args)
5114{
5115 int err, percent, nwrotep;
5116
5117 if (!PyArg_ParseTuple(args, "i:memp_trickle", &percent))
5118 return NULL;
5119 CHECK_ENV_NOT_CLOSED(self);
5120 MYDB_BEGIN_ALLOW_THREADS;
5121 err = self->db_env->memp_trickle(self->db_env, percent, &nwrotep);
5122 MYDB_END_ALLOW_THREADS;
5123 RETURN_IF_ERR();
5124 return NUMBER_FromLong(nwrotep);
5125}
5126
5127static PyObject*
5128DBEnv_memp_sync(DBEnvObject* self, PyObject* args)
5129{
5130 int err;
5131 DB_LSN lsn = {0, 0};
5132 DB_LSN *lsn_p = NULL;
5133
5134 if (!PyArg_ParseTuple(args, "|(ii):memp_sync", &lsn.file, &lsn.offset))
5135 return NULL;
5136 if ((lsn.file!=0) || (lsn.offset!=0)) {
5137 lsn_p = &lsn;
5138 }
5139 CHECK_ENV_NOT_CLOSED(self);
5140 MYDB_BEGIN_ALLOW_THREADS;
5141 err = self->db_env->memp_sync(self->db_env, lsn_p);
5142 MYDB_END_ALLOW_THREADS;
5143 RETURN_IF_ERR();
5144 RETURN_NONE();
5145}
5146
5147static PyObject*
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005148DBEnv_remove(DBEnvObject* self, PyObject* args)
5149{
5150 int err, flags=0;
5151 char *db_home;
5152
5153 if (!PyArg_ParseTuple(args, "s|i:remove", &db_home, &flags))
5154 return NULL;
5155 CHECK_ENV_NOT_CLOSED(self);
5156 MYDB_BEGIN_ALLOW_THREADS;
5157 err = self->db_env->remove(self->db_env, db_home, flags);
5158 MYDB_END_ALLOW_THREADS;
5159 RETURN_IF_ERR();
5160 RETURN_NONE();
5161}
5162
Barry Warsaw9a0d7792002-12-30 20:53:52 +00005163static PyObject*
5164DBEnv_dbremove(DBEnvObject* self, PyObject* args, PyObject* kwargs)
5165{
5166 int err;
5167 u_int32_t flags=0;
5168 char *file = NULL;
5169 char *database = NULL;
5170 PyObject *txnobj = NULL;
5171 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00005172 static char* kwnames[] = { "file", "database", "txn", "flags",
Jeremy Hyltonaf68c872005-12-10 18:50:16 +00005173 NULL };
Barry Warsaw9a0d7792002-12-30 20:53:52 +00005174
Gregory P. Smith641cddf2006-07-28 01:35:25 +00005175 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|zOi:dbremove", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00005176 &file, &database, &txnobj, &flags)) {
5177 return NULL;
Barry Warsaw9a0d7792002-12-30 20:53:52 +00005178 }
5179 if (!checkTxnObj(txnobj, &txn)) {
5180 return NULL;
5181 }
5182 CHECK_ENV_NOT_CLOSED(self);
5183 MYDB_BEGIN_ALLOW_THREADS;
5184 err = self->db_env->dbremove(self->db_env, txn, file, database, flags);
5185 MYDB_END_ALLOW_THREADS;
5186 RETURN_IF_ERR();
5187 RETURN_NONE();
5188}
5189
5190static PyObject*
5191DBEnv_dbrename(DBEnvObject* self, PyObject* args, PyObject* kwargs)
5192{
5193 int err;
5194 u_int32_t flags=0;
5195 char *file = NULL;
5196 char *database = NULL;
5197 char *newname = NULL;
5198 PyObject *txnobj = NULL;
5199 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00005200 static char* kwnames[] = { "file", "database", "newname", "txn",
Jeremy Hyltonaf68c872005-12-10 18:50:16 +00005201 "flags", NULL };
Barry Warsaw9a0d7792002-12-30 20:53:52 +00005202
Gregory P. Smith641cddf2006-07-28 01:35:25 +00005203 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "szs|Oi:dbrename", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00005204 &file, &database, &newname, &txnobj, &flags)) {
5205 return NULL;
Barry Warsaw9a0d7792002-12-30 20:53:52 +00005206 }
5207 if (!checkTxnObj(txnobj, &txn)) {
5208 return NULL;
5209 }
5210 CHECK_ENV_NOT_CLOSED(self);
5211 MYDB_BEGIN_ALLOW_THREADS;
5212 err = self->db_env->dbrename(self->db_env, txn, file, database, newname,
5213 flags);
5214 MYDB_END_ALLOW_THREADS;
5215 RETURN_IF_ERR();
5216 RETURN_NONE();
5217}
5218
Jesus Cea6557aac2010-03-22 14:22:26 +00005219
5220
Barry Warsaw9a0d7792002-12-30 20:53:52 +00005221static PyObject*
5222DBEnv_set_encrypt(DBEnvObject* self, PyObject* args, PyObject* kwargs)
5223{
5224 int err;
5225 u_int32_t flags=0;
5226 char *passwd = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00005227 static char* kwnames[] = { "passwd", "flags", NULL };
Barry Warsaw9a0d7792002-12-30 20:53:52 +00005228
5229 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|i:set_encrypt", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00005230 &passwd, &flags)) {
5231 return NULL;
Barry Warsaw9a0d7792002-12-30 20:53:52 +00005232 }
5233
5234 MYDB_BEGIN_ALLOW_THREADS;
5235 err = self->db_env->set_encrypt(self->db_env, passwd, flags);
5236 MYDB_END_ALLOW_THREADS;
5237
5238 RETURN_IF_ERR();
5239 RETURN_NONE();
5240}
Jesus Cea6557aac2010-03-22 14:22:26 +00005241
Jesus Cea6557aac2010-03-22 14:22:26 +00005242static PyObject*
5243DBEnv_get_encrypt_flags(DBEnvObject* self)
5244{
5245 int err;
5246 u_int32_t flags;
5247
5248 CHECK_ENV_NOT_CLOSED(self);
5249
5250 MYDB_BEGIN_ALLOW_THREADS;
5251 err = self->db_env->get_encrypt_flags(self->db_env, &flags);
5252 MYDB_END_ALLOW_THREADS;
5253
5254 RETURN_IF_ERR();
5255
5256 return NUMBER_FromLong(flags);
5257}
5258
5259static PyObject*
5260DBEnv_get_timeout(DBEnvObject* self, PyObject* args, PyObject* kwargs)
5261{
5262 int err;
5263 int flag;
5264 u_int32_t timeout;
5265 static char* kwnames[] = {"flag", NULL };
5266
5267 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i:get_timeout", kwnames,
5268 &flag)) {
5269 return NULL;
5270 }
5271 CHECK_ENV_NOT_CLOSED(self);
5272
5273 MYDB_BEGIN_ALLOW_THREADS;
5274 err = self->db_env->get_timeout(self->db_env, &timeout, flag);
5275 MYDB_END_ALLOW_THREADS;
5276 RETURN_IF_ERR();
5277 return NUMBER_FromLong(timeout);
5278}
Jesus Cea6557aac2010-03-22 14:22:26 +00005279
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005280
Gregory P. Smithfe11d3e2003-03-27 17:23:29 +00005281static PyObject*
5282DBEnv_set_timeout(DBEnvObject* self, PyObject* args, PyObject* kwargs)
5283{
5284 int err;
5285 u_int32_t flags=0;
5286 u_int32_t timeout = 0;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00005287 static char* kwnames[] = { "timeout", "flags", NULL };
Gregory P. Smithfe11d3e2003-03-27 17:23:29 +00005288
5289 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ii:set_timeout", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00005290 &timeout, &flags)) {
5291 return NULL;
Gregory P. Smithfe11d3e2003-03-27 17:23:29 +00005292 }
5293
5294 MYDB_BEGIN_ALLOW_THREADS;
5295 err = self->db_env->set_timeout(self->db_env, (db_timeout_t)timeout, flags);
5296 MYDB_END_ALLOW_THREADS;
5297
5298 RETURN_IF_ERR();
5299 RETURN_NONE();
5300}
Gregory P. Smithfe11d3e2003-03-27 17:23:29 +00005301
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005302static PyObject*
Gregory P. Smith6676f6e2003-08-28 21:50:30 +00005303DBEnv_set_shm_key(DBEnvObject* self, PyObject* args)
5304{
5305 int err;
5306 long shm_key = 0;
5307
5308 if (!PyArg_ParseTuple(args, "l:set_shm_key", &shm_key))
5309 return NULL;
5310 CHECK_ENV_NOT_CLOSED(self);
5311
5312 err = self->db_env->set_shm_key(self->db_env, shm_key);
5313 RETURN_IF_ERR();
5314 RETURN_NONE();
5315}
5316
Jesus Cea6557aac2010-03-22 14:22:26 +00005317static PyObject*
5318DBEnv_get_shm_key(DBEnvObject* self)
5319{
5320 int err;
5321 long shm_key;
5322
5323 CHECK_ENV_NOT_CLOSED(self);
5324
5325 MYDB_BEGIN_ALLOW_THREADS;
5326 err = self->db_env->get_shm_key(self->db_env, &shm_key);
5327 MYDB_END_ALLOW_THREADS;
5328
5329 RETURN_IF_ERR();
5330
5331 return NUMBER_FromLong(shm_key);
5332}
Jesus Cea6557aac2010-03-22 14:22:26 +00005333
5334#if (DBVER >= 46)
5335static PyObject*
5336DBEnv_set_cache_max(DBEnvObject* self, PyObject* args)
5337{
5338 int err, gbytes, bytes;
5339
5340 if (!PyArg_ParseTuple(args, "ii:set_cache_max",
5341 &gbytes, &bytes))
5342 return NULL;
5343 CHECK_ENV_NOT_CLOSED(self);
5344
5345 MYDB_BEGIN_ALLOW_THREADS;
5346 err = self->db_env->set_cache_max(self->db_env, gbytes, bytes);
5347 MYDB_END_ALLOW_THREADS;
5348 RETURN_IF_ERR();
5349 RETURN_NONE();
5350}
5351
5352static PyObject*
5353DBEnv_get_cache_max(DBEnvObject* self)
5354{
5355 int err;
5356 u_int32_t gbytes, bytes;
5357
5358 CHECK_ENV_NOT_CLOSED(self);
5359
5360 MYDB_BEGIN_ALLOW_THREADS;
5361 err = self->db_env->get_cache_max(self->db_env, &gbytes, &bytes);
5362 MYDB_END_ALLOW_THREADS;
5363
5364 RETURN_IF_ERR();
5365
5366 return Py_BuildValue("(ii)", gbytes, bytes);
5367}
5368#endif
5369
5370#if (DBVER >= 46)
5371static PyObject*
5372DBEnv_set_thread_count(DBEnvObject* self, PyObject* args)
5373{
5374 int err;
5375 u_int32_t count;
5376
5377 if (!PyArg_ParseTuple(args, "i:set_thread_count", &count))
5378 return NULL;
5379 CHECK_ENV_NOT_CLOSED(self);
5380
5381 MYDB_BEGIN_ALLOW_THREADS;
5382 err = self->db_env->set_thread_count(self->db_env, count);
5383 MYDB_END_ALLOW_THREADS;
5384 RETURN_IF_ERR();
5385 RETURN_NONE();
5386}
5387
5388static PyObject*
5389DBEnv_get_thread_count(DBEnvObject* self)
5390{
5391 int err;
5392 u_int32_t count;
5393
5394 CHECK_ENV_NOT_CLOSED(self);
5395
5396 MYDB_BEGIN_ALLOW_THREADS;
5397 err = self->db_env->get_thread_count(self->db_env, &count);
5398 MYDB_END_ALLOW_THREADS;
5399 RETURN_IF_ERR();
5400 return NUMBER_FromLong(count);
5401}
5402#endif
5403
Gregory P. Smith6676f6e2003-08-28 21:50:30 +00005404static PyObject*
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005405DBEnv_set_cachesize(DBEnvObject* self, PyObject* args)
5406{
5407 int err, gbytes=0, bytes=0, ncache=0;
5408
5409 if (!PyArg_ParseTuple(args, "ii|i:set_cachesize",
5410 &gbytes, &bytes, &ncache))
5411 return NULL;
5412 CHECK_ENV_NOT_CLOSED(self);
5413
5414 MYDB_BEGIN_ALLOW_THREADS;
5415 err = self->db_env->set_cachesize(self->db_env, gbytes, bytes, ncache);
5416 MYDB_END_ALLOW_THREADS;
5417 RETURN_IF_ERR();
5418 RETURN_NONE();
5419}
5420
Jesus Cea6557aac2010-03-22 14:22:26 +00005421static PyObject*
5422DBEnv_get_cachesize(DBEnvObject* self)
5423{
5424 int err;
5425 u_int32_t gbytes, bytes;
5426 int ncache;
5427
5428 CHECK_ENV_NOT_CLOSED(self);
5429
5430 MYDB_BEGIN_ALLOW_THREADS;
5431 err = self->db_env->get_cachesize(self->db_env, &gbytes, &bytes, &ncache);
5432 MYDB_END_ALLOW_THREADS;
5433
5434 RETURN_IF_ERR();
5435
5436 return Py_BuildValue("(iii)", gbytes, bytes, ncache);
5437}
Jesus Cea6557aac2010-03-22 14:22:26 +00005438
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005439
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005440static PyObject*
5441DBEnv_set_flags(DBEnvObject* self, PyObject* args)
5442{
5443 int err, flags=0, onoff=0;
5444
5445 if (!PyArg_ParseTuple(args, "ii:set_flags",
5446 &flags, &onoff))
5447 return NULL;
5448 CHECK_ENV_NOT_CLOSED(self);
5449
5450 MYDB_BEGIN_ALLOW_THREADS;
5451 err = self->db_env->set_flags(self->db_env, flags, onoff);
5452 MYDB_END_ALLOW_THREADS;
5453 RETURN_IF_ERR();
5454 RETURN_NONE();
5455}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005456
Jesus Cea6557aac2010-03-22 14:22:26 +00005457static PyObject*
5458DBEnv_get_flags(DBEnvObject* self)
5459{
5460 int err;
5461 u_int32_t flags;
5462
5463 CHECK_ENV_NOT_CLOSED(self);
5464
5465 MYDB_BEGIN_ALLOW_THREADS;
5466 err = self->db_env->get_flags(self->db_env, &flags);
5467 MYDB_END_ALLOW_THREADS;
5468 RETURN_IF_ERR();
5469 return NUMBER_FromLong(flags);
5470}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005471
Jesus Ceaca3939c2008-05-22 15:27:38 +00005472#if (DBVER >= 47)
5473static PyObject*
5474DBEnv_log_set_config(DBEnvObject* self, PyObject* args)
5475{
5476 int err, flags, onoff;
5477
5478 if (!PyArg_ParseTuple(args, "ii:log_set_config",
5479 &flags, &onoff))
5480 return NULL;
5481 CHECK_ENV_NOT_CLOSED(self);
5482
5483 MYDB_BEGIN_ALLOW_THREADS;
5484 err = self->db_env->log_set_config(self->db_env, flags, onoff);
5485 MYDB_END_ALLOW_THREADS;
5486 RETURN_IF_ERR();
5487 RETURN_NONE();
5488}
Jesus Cea6557aac2010-03-22 14:22:26 +00005489
5490static PyObject*
5491DBEnv_log_get_config(DBEnvObject* self, PyObject* args)
5492{
5493 int err, flag, onoff;
5494
5495 if (!PyArg_ParseTuple(args, "i:log_get_config", &flag))
5496 return NULL;
5497 CHECK_ENV_NOT_CLOSED(self);
5498
5499 MYDB_BEGIN_ALLOW_THREADS;
5500 err = self->db_env->log_get_config(self->db_env, flag, &onoff);
5501 MYDB_END_ALLOW_THREADS;
5502 RETURN_IF_ERR();
5503 return PyBool_FromLong(onoff);
5504}
Jesus Ceaca3939c2008-05-22 15:27:38 +00005505#endif /* DBVER >= 47 */
5506
Jesus Cea6557aac2010-03-22 14:22:26 +00005507#if (DBVER >= 44)
5508static PyObject*
5509DBEnv_mutex_set_max(DBEnvObject* self, PyObject* args)
5510{
5511 int err;
5512 int value;
5513
5514 if (!PyArg_ParseTuple(args, "i:mutex_set_max", &value))
5515 return NULL;
5516
5517 CHECK_ENV_NOT_CLOSED(self);
5518
5519 MYDB_BEGIN_ALLOW_THREADS;
5520 err = self->db_env->mutex_set_max(self->db_env, value);
5521 MYDB_END_ALLOW_THREADS;
5522
5523 RETURN_IF_ERR();
5524 RETURN_NONE();
5525}
5526
5527static PyObject*
5528DBEnv_mutex_get_max(DBEnvObject* self)
5529{
5530 int err;
5531 u_int32_t value;
5532
5533 CHECK_ENV_NOT_CLOSED(self);
5534
5535 MYDB_BEGIN_ALLOW_THREADS;
5536 err = self->db_env->mutex_get_max(self->db_env, &value);
5537 MYDB_END_ALLOW_THREADS;
5538
5539 RETURN_IF_ERR();
5540
5541 return NUMBER_FromLong(value);
5542}
5543
5544static PyObject*
5545DBEnv_mutex_set_align(DBEnvObject* self, PyObject* args)
5546{
5547 int err;
5548 int align;
5549
5550 if (!PyArg_ParseTuple(args, "i:mutex_set_align", &align))
5551 return NULL;
5552
5553 CHECK_ENV_NOT_CLOSED(self);
5554
5555 MYDB_BEGIN_ALLOW_THREADS;
5556 err = self->db_env->mutex_set_align(self->db_env, align);
5557 MYDB_END_ALLOW_THREADS;
5558
5559 RETURN_IF_ERR();
5560 RETURN_NONE();
5561}
5562
5563static PyObject*
5564DBEnv_mutex_get_align(DBEnvObject* self)
5565{
5566 int err;
5567 u_int32_t align;
5568
5569 CHECK_ENV_NOT_CLOSED(self);
5570
5571 MYDB_BEGIN_ALLOW_THREADS;
5572 err = self->db_env->mutex_get_align(self->db_env, &align);
5573 MYDB_END_ALLOW_THREADS;
5574
5575 RETURN_IF_ERR();
5576
5577 return NUMBER_FromLong(align);
5578}
5579
5580static PyObject*
5581DBEnv_mutex_set_increment(DBEnvObject* self, PyObject* args)
5582{
5583 int err;
5584 int increment;
5585
5586 if (!PyArg_ParseTuple(args, "i:mutex_set_increment", &increment))
5587 return NULL;
5588
5589 CHECK_ENV_NOT_CLOSED(self);
5590
5591 MYDB_BEGIN_ALLOW_THREADS;
5592 err = self->db_env->mutex_set_increment(self->db_env, increment);
5593 MYDB_END_ALLOW_THREADS;
5594
5595 RETURN_IF_ERR();
5596 RETURN_NONE();
5597}
5598
5599static PyObject*
5600DBEnv_mutex_get_increment(DBEnvObject* self)
5601{
5602 int err;
5603 u_int32_t increment;
5604
5605 CHECK_ENV_NOT_CLOSED(self);
5606
5607 MYDB_BEGIN_ALLOW_THREADS;
5608 err = self->db_env->mutex_get_increment(self->db_env, &increment);
5609 MYDB_END_ALLOW_THREADS;
5610
5611 RETURN_IF_ERR();
5612
5613 return NUMBER_FromLong(increment);
5614}
5615
5616static PyObject*
5617DBEnv_mutex_set_tas_spins(DBEnvObject* self, PyObject* args)
5618{
5619 int err;
5620 int tas_spins;
5621
5622 if (!PyArg_ParseTuple(args, "i:mutex_set_tas_spins", &tas_spins))
5623 return NULL;
5624
5625 CHECK_ENV_NOT_CLOSED(self);
5626
5627 MYDB_BEGIN_ALLOW_THREADS;
5628 err = self->db_env->mutex_set_tas_spins(self->db_env, tas_spins);
5629 MYDB_END_ALLOW_THREADS;
5630
5631 RETURN_IF_ERR();
5632 RETURN_NONE();
5633}
5634
5635static PyObject*
5636DBEnv_mutex_get_tas_spins(DBEnvObject* self)
5637{
5638 int err;
5639 u_int32_t tas_spins;
5640
5641 CHECK_ENV_NOT_CLOSED(self);
5642
5643 MYDB_BEGIN_ALLOW_THREADS;
5644 err = self->db_env->mutex_get_tas_spins(self->db_env, &tas_spins);
5645 MYDB_END_ALLOW_THREADS;
5646
5647 RETURN_IF_ERR();
5648
5649 return NUMBER_FromLong(tas_spins);
5650}
5651#endif
Jesus Ceaca3939c2008-05-22 15:27:38 +00005652
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005653static PyObject*
5654DBEnv_set_data_dir(DBEnvObject* self, PyObject* args)
5655{
5656 int err;
5657 char *dir;
5658
5659 if (!PyArg_ParseTuple(args, "s:set_data_dir", &dir))
5660 return NULL;
5661 CHECK_ENV_NOT_CLOSED(self);
5662
5663 MYDB_BEGIN_ALLOW_THREADS;
5664 err = self->db_env->set_data_dir(self->db_env, dir);
5665 MYDB_END_ALLOW_THREADS;
5666 RETURN_IF_ERR();
5667 RETURN_NONE();
5668}
5669
Jesus Cea6557aac2010-03-22 14:22:26 +00005670static PyObject*
5671DBEnv_get_data_dirs(DBEnvObject* self)
5672{
5673 int err;
5674 PyObject *tuple;
5675 PyObject *item;
5676 const char **dirpp;
5677 int size, i;
5678
5679 CHECK_ENV_NOT_CLOSED(self);
5680
5681 MYDB_BEGIN_ALLOW_THREADS;
5682 err = self->db_env->get_data_dirs(self->db_env, &dirpp);
5683 MYDB_END_ALLOW_THREADS;
5684
5685 RETURN_IF_ERR();
5686
5687 /*
5688 ** Calculate size. Python C API
5689 ** actually allows for tuple resizing,
5690 ** but this is simple enough.
5691 */
5692 for (size=0; *(dirpp+size) ; size++);
5693
5694 tuple = PyTuple_New(size);
5695 if (!tuple)
5696 return NULL;
5697
5698 for (i=0; i<size; i++) {
5699 item = PyBytes_FromString (*(dirpp+i));
5700 if (item == NULL) {
5701 Py_DECREF(tuple);
5702 tuple = NULL;
5703 break;
5704 }
5705 PyTuple_SET_ITEM(tuple, i, item);
5706 }
5707 return tuple;
5708}
Jesus Cea6557aac2010-03-22 14:22:26 +00005709
5710#if (DBVER >= 44)
5711static PyObject*
5712DBEnv_set_lg_filemode(DBEnvObject* self, PyObject* args)
5713{
5714 int err, filemode;
5715
5716 if (!PyArg_ParseTuple(args, "i:set_lg_filemode", &filemode))
5717 return NULL;
5718 CHECK_ENV_NOT_CLOSED(self);
5719
5720 MYDB_BEGIN_ALLOW_THREADS;
5721 err = self->db_env->set_lg_filemode(self->db_env, filemode);
5722 MYDB_END_ALLOW_THREADS;
5723 RETURN_IF_ERR();
5724 RETURN_NONE();
5725}
5726
5727static PyObject*
5728DBEnv_get_lg_filemode(DBEnvObject* self)
5729{
5730 int err, filemode;
5731
5732 CHECK_ENV_NOT_CLOSED(self);
5733
5734 MYDB_BEGIN_ALLOW_THREADS;
5735 err = self->db_env->get_lg_filemode(self->db_env, &filemode);
5736 MYDB_END_ALLOW_THREADS;
5737 RETURN_IF_ERR();
5738 return NUMBER_FromLong(filemode);
5739}
5740#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005741
5742static PyObject*
5743DBEnv_set_lg_bsize(DBEnvObject* self, PyObject* args)
5744{
5745 int err, lg_bsize;
5746
5747 if (!PyArg_ParseTuple(args, "i:set_lg_bsize", &lg_bsize))
5748 return NULL;
5749 CHECK_ENV_NOT_CLOSED(self);
5750
5751 MYDB_BEGIN_ALLOW_THREADS;
5752 err = self->db_env->set_lg_bsize(self->db_env, lg_bsize);
5753 MYDB_END_ALLOW_THREADS;
5754 RETURN_IF_ERR();
5755 RETURN_NONE();
5756}
5757
Jesus Cea6557aac2010-03-22 14:22:26 +00005758static PyObject*
5759DBEnv_get_lg_bsize(DBEnvObject* self)
5760{
5761 int err;
5762 u_int32_t lg_bsize;
5763
5764 CHECK_ENV_NOT_CLOSED(self);
5765
5766 MYDB_BEGIN_ALLOW_THREADS;
5767 err = self->db_env->get_lg_bsize(self->db_env, &lg_bsize);
5768 MYDB_END_ALLOW_THREADS;
5769 RETURN_IF_ERR();
5770 return NUMBER_FromLong(lg_bsize);
5771}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005772
5773static PyObject*
5774DBEnv_set_lg_dir(DBEnvObject* self, PyObject* args)
5775{
5776 int err;
5777 char *dir;
5778
5779 if (!PyArg_ParseTuple(args, "s:set_lg_dir", &dir))
5780 return NULL;
5781 CHECK_ENV_NOT_CLOSED(self);
5782
5783 MYDB_BEGIN_ALLOW_THREADS;
5784 err = self->db_env->set_lg_dir(self->db_env, dir);
5785 MYDB_END_ALLOW_THREADS;
5786 RETURN_IF_ERR();
5787 RETURN_NONE();
5788}
5789
Jesus Cea6557aac2010-03-22 14:22:26 +00005790static PyObject*
5791DBEnv_get_lg_dir(DBEnvObject* self)
5792{
5793 int err;
5794 const char *dirp;
5795
5796 CHECK_ENV_NOT_CLOSED(self);
5797
5798 MYDB_BEGIN_ALLOW_THREADS;
5799 err = self->db_env->get_lg_dir(self->db_env, &dirp);
5800 MYDB_END_ALLOW_THREADS;
5801 RETURN_IF_ERR();
5802 return PyBytes_FromString(dirp);
5803}
Jesus Cea6557aac2010-03-22 14:22:26 +00005804
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005805static PyObject*
5806DBEnv_set_lg_max(DBEnvObject* self, PyObject* args)
5807{
5808 int err, lg_max;
5809
5810 if (!PyArg_ParseTuple(args, "i:set_lg_max", &lg_max))
5811 return NULL;
5812 CHECK_ENV_NOT_CLOSED(self);
5813
5814 MYDB_BEGIN_ALLOW_THREADS;
5815 err = self->db_env->set_lg_max(self->db_env, lg_max);
5816 MYDB_END_ALLOW_THREADS;
5817 RETURN_IF_ERR();
5818 RETURN_NONE();
5819}
5820
Jesus Ceaef9764f2008-05-13 18:45:46 +00005821static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00005822DBEnv_get_lg_max(DBEnvObject* self)
Jesus Ceaef9764f2008-05-13 18:45:46 +00005823{
5824 int err;
5825 u_int32_t lg_max;
5826
Jesus Ceaef9764f2008-05-13 18:45:46 +00005827 CHECK_ENV_NOT_CLOSED(self);
5828
5829 MYDB_BEGIN_ALLOW_THREADS;
5830 err = self->db_env->get_lg_max(self->db_env, &lg_max);
5831 MYDB_END_ALLOW_THREADS;
5832 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00005833 return NUMBER_FromLong(lg_max);
Jesus Ceaef9764f2008-05-13 18:45:46 +00005834}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005835
5836static PyObject*
Gregory P. Smithe9477062005-06-04 06:46:59 +00005837DBEnv_set_lg_regionmax(DBEnvObject* self, PyObject* args)
5838{
5839 int err, lg_max;
5840
5841 if (!PyArg_ParseTuple(args, "i:set_lg_regionmax", &lg_max))
5842 return NULL;
5843 CHECK_ENV_NOT_CLOSED(self);
5844
5845 MYDB_BEGIN_ALLOW_THREADS;
5846 err = self->db_env->set_lg_regionmax(self->db_env, lg_max);
5847 MYDB_END_ALLOW_THREADS;
5848 RETURN_IF_ERR();
5849 RETURN_NONE();
5850}
5851
Jesus Cea6557aac2010-03-22 14:22:26 +00005852static PyObject*
5853DBEnv_get_lg_regionmax(DBEnvObject* self)
5854{
5855 int err;
5856 u_int32_t lg_regionmax;
5857
5858 CHECK_ENV_NOT_CLOSED(self);
5859
5860 MYDB_BEGIN_ALLOW_THREADS;
5861 err = self->db_env->get_lg_regionmax(self->db_env, &lg_regionmax);
5862 MYDB_END_ALLOW_THREADS;
5863 RETURN_IF_ERR();
5864 return NUMBER_FromLong(lg_regionmax);
5865}
Jesus Cea6557aac2010-03-22 14:22:26 +00005866
5867#if (DBVER >= 47)
5868static PyObject*
5869DBEnv_set_lk_partitions(DBEnvObject* self, PyObject* args)
5870{
5871 int err, lk_partitions;
5872
5873 if (!PyArg_ParseTuple(args, "i:set_lk_partitions", &lk_partitions))
5874 return NULL;
5875 CHECK_ENV_NOT_CLOSED(self);
5876
5877 MYDB_BEGIN_ALLOW_THREADS;
5878 err = self->db_env->set_lk_partitions(self->db_env, lk_partitions);
5879 MYDB_END_ALLOW_THREADS;
5880 RETURN_IF_ERR();
5881 RETURN_NONE();
5882}
5883
5884static PyObject*
5885DBEnv_get_lk_partitions(DBEnvObject* self)
5886{
5887 int err;
5888 u_int32_t lk_partitions;
5889
5890 CHECK_ENV_NOT_CLOSED(self);
5891
5892 MYDB_BEGIN_ALLOW_THREADS;
5893 err = self->db_env->get_lk_partitions(self->db_env, &lk_partitions);
5894 MYDB_END_ALLOW_THREADS;
5895 RETURN_IF_ERR();
5896 return NUMBER_FromLong(lk_partitions);
5897}
5898#endif
Gregory P. Smithe9477062005-06-04 06:46:59 +00005899
5900static PyObject*
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005901DBEnv_set_lk_detect(DBEnvObject* self, PyObject* args)
5902{
5903 int err, lk_detect;
5904
5905 if (!PyArg_ParseTuple(args, "i:set_lk_detect", &lk_detect))
5906 return NULL;
5907 CHECK_ENV_NOT_CLOSED(self);
5908
5909 MYDB_BEGIN_ALLOW_THREADS;
5910 err = self->db_env->set_lk_detect(self->db_env, lk_detect);
5911 MYDB_END_ALLOW_THREADS;
5912 RETURN_IF_ERR();
5913 RETURN_NONE();
5914}
5915
Jesus Cea6557aac2010-03-22 14:22:26 +00005916static PyObject*
5917DBEnv_get_lk_detect(DBEnvObject* self)
5918{
5919 int err;
5920 u_int32_t lk_detect;
5921
5922 CHECK_ENV_NOT_CLOSED(self);
5923
5924 MYDB_BEGIN_ALLOW_THREADS;
5925 err = self->db_env->get_lk_detect(self->db_env, &lk_detect);
5926 MYDB_END_ALLOW_THREADS;
5927 RETURN_IF_ERR();
5928 return NUMBER_FromLong(lk_detect);
5929}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005930
Gregory P. Smith8b96a352007-01-05 01:59:42 +00005931#if (DBVER < 45)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005932static PyObject*
5933DBEnv_set_lk_max(DBEnvObject* self, PyObject* args)
5934{
5935 int err, max;
5936
5937 if (!PyArg_ParseTuple(args, "i:set_lk_max", &max))
5938 return NULL;
5939 CHECK_ENV_NOT_CLOSED(self);
5940
5941 MYDB_BEGIN_ALLOW_THREADS;
5942 err = self->db_env->set_lk_max(self->db_env, max);
5943 MYDB_END_ALLOW_THREADS;
5944 RETURN_IF_ERR();
5945 RETURN_NONE();
5946}
Gregory P. Smith8b96a352007-01-05 01:59:42 +00005947#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005948
5949
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005950
5951static PyObject*
5952DBEnv_set_lk_max_locks(DBEnvObject* self, PyObject* args)
5953{
5954 int err, max;
5955
5956 if (!PyArg_ParseTuple(args, "i:set_lk_max_locks", &max))
5957 return NULL;
5958 CHECK_ENV_NOT_CLOSED(self);
5959
5960 MYDB_BEGIN_ALLOW_THREADS;
5961 err = self->db_env->set_lk_max_locks(self->db_env, max);
5962 MYDB_END_ALLOW_THREADS;
5963 RETURN_IF_ERR();
5964 RETURN_NONE();
5965}
5966
Jesus Cea6557aac2010-03-22 14:22:26 +00005967static PyObject*
5968DBEnv_get_lk_max_locks(DBEnvObject* self)
5969{
5970 int err;
5971 u_int32_t lk_max;
5972
5973 CHECK_ENV_NOT_CLOSED(self);
5974
5975 MYDB_BEGIN_ALLOW_THREADS;
5976 err = self->db_env->get_lk_max_locks(self->db_env, &lk_max);
5977 MYDB_END_ALLOW_THREADS;
5978 RETURN_IF_ERR();
5979 return NUMBER_FromLong(lk_max);
5980}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005981
5982static PyObject*
5983DBEnv_set_lk_max_lockers(DBEnvObject* self, PyObject* args)
5984{
5985 int err, max;
5986
5987 if (!PyArg_ParseTuple(args, "i:set_lk_max_lockers", &max))
5988 return NULL;
5989 CHECK_ENV_NOT_CLOSED(self);
5990
5991 MYDB_BEGIN_ALLOW_THREADS;
5992 err = self->db_env->set_lk_max_lockers(self->db_env, max);
5993 MYDB_END_ALLOW_THREADS;
5994 RETURN_IF_ERR();
5995 RETURN_NONE();
5996}
5997
Jesus Cea6557aac2010-03-22 14:22:26 +00005998static PyObject*
5999DBEnv_get_lk_max_lockers(DBEnvObject* self)
6000{
6001 int err;
6002 u_int32_t lk_max;
6003
6004 CHECK_ENV_NOT_CLOSED(self);
6005
6006 MYDB_BEGIN_ALLOW_THREADS;
6007 err = self->db_env->get_lk_max_lockers(self->db_env, &lk_max);
6008 MYDB_END_ALLOW_THREADS;
6009 RETURN_IF_ERR();
6010 return NUMBER_FromLong(lk_max);
6011}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006012
6013static PyObject*
6014DBEnv_set_lk_max_objects(DBEnvObject* self, PyObject* args)
6015{
6016 int err, max;
6017
6018 if (!PyArg_ParseTuple(args, "i:set_lk_max_objects", &max))
6019 return NULL;
6020 CHECK_ENV_NOT_CLOSED(self);
6021
6022 MYDB_BEGIN_ALLOW_THREADS;
6023 err = self->db_env->set_lk_max_objects(self->db_env, max);
6024 MYDB_END_ALLOW_THREADS;
6025 RETURN_IF_ERR();
6026 RETURN_NONE();
6027}
6028
Jesus Cea6557aac2010-03-22 14:22:26 +00006029static PyObject*
6030DBEnv_get_lk_max_objects(DBEnvObject* self)
6031{
6032 int err;
6033 u_int32_t lk_max;
6034
6035 CHECK_ENV_NOT_CLOSED(self);
6036
6037 MYDB_BEGIN_ALLOW_THREADS;
6038 err = self->db_env->get_lk_max_objects(self->db_env, &lk_max);
6039 MYDB_END_ALLOW_THREADS;
6040 RETURN_IF_ERR();
6041 return NUMBER_FromLong(lk_max);
6042}
Jesus Cea6557aac2010-03-22 14:22:26 +00006043
Jesus Cea6557aac2010-03-22 14:22:26 +00006044static PyObject*
6045DBEnv_get_mp_mmapsize(DBEnvObject* self)
6046{
6047 int err;
6048 size_t mmapsize;
6049
6050 CHECK_ENV_NOT_CLOSED(self);
6051
6052 MYDB_BEGIN_ALLOW_THREADS;
6053 err = self->db_env->get_mp_mmapsize(self->db_env, &mmapsize);
6054 MYDB_END_ALLOW_THREADS;
6055 RETURN_IF_ERR();
6056 return NUMBER_FromLong(mmapsize);
6057}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006058
6059static PyObject*
6060DBEnv_set_mp_mmapsize(DBEnvObject* self, PyObject* args)
6061{
6062 int err, mp_mmapsize;
6063
6064 if (!PyArg_ParseTuple(args, "i:set_mp_mmapsize", &mp_mmapsize))
6065 return NULL;
6066 CHECK_ENV_NOT_CLOSED(self);
6067
6068 MYDB_BEGIN_ALLOW_THREADS;
6069 err = self->db_env->set_mp_mmapsize(self->db_env, mp_mmapsize);
6070 MYDB_END_ALLOW_THREADS;
6071 RETURN_IF_ERR();
6072 RETURN_NONE();
6073}
6074
6075
6076static PyObject*
6077DBEnv_set_tmp_dir(DBEnvObject* self, PyObject* args)
6078{
6079 int err;
6080 char *dir;
6081
6082 if (!PyArg_ParseTuple(args, "s:set_tmp_dir", &dir))
6083 return NULL;
6084 CHECK_ENV_NOT_CLOSED(self);
6085
6086 MYDB_BEGIN_ALLOW_THREADS;
6087 err = self->db_env->set_tmp_dir(self->db_env, dir);
6088 MYDB_END_ALLOW_THREADS;
6089 RETURN_IF_ERR();
6090 RETURN_NONE();
6091}
6092
Jesus Cea6557aac2010-03-22 14:22:26 +00006093static PyObject*
6094DBEnv_get_tmp_dir(DBEnvObject* self)
6095{
6096 int err;
6097 const char *dirpp;
6098
6099 CHECK_ENV_NOT_CLOSED(self);
6100
6101 MYDB_BEGIN_ALLOW_THREADS;
6102 err = self->db_env->get_tmp_dir(self->db_env, &dirpp);
6103 MYDB_END_ALLOW_THREADS;
6104
6105 RETURN_IF_ERR();
6106
6107 return PyBytes_FromString(dirpp);
6108}
Jesus Cea6557aac2010-03-22 14:22:26 +00006109
Jesus Ceaef9764f2008-05-13 18:45:46 +00006110static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00006111DBEnv_txn_recover(DBEnvObject* self)
Jesus Ceaef9764f2008-05-13 18:45:46 +00006112{
6113 int flags = DB_FIRST;
6114 int err, i;
6115 PyObject *list, *tuple, *gid;
6116 DBTxnObject *txn;
6117#define PREPLIST_LEN 16
6118 DB_PREPLIST preplist[PREPLIST_LEN];
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07006119#if (DBVER < 48) || (DBVER >= 52)
Jesus Ceaef9764f2008-05-13 18:45:46 +00006120 long retp;
Matthias Klose54cc5392010-03-15 12:46:18 +00006121#else
6122 u_int32_t retp;
6123#endif
Jesus Ceaef9764f2008-05-13 18:45:46 +00006124
Jesus Ceaef9764f2008-05-13 18:45:46 +00006125 CHECK_ENV_NOT_CLOSED(self);
6126
6127 list=PyList_New(0);
6128 if (!list)
6129 return NULL;
6130 while (!0) {
6131 MYDB_BEGIN_ALLOW_THREADS
6132 err=self->db_env->txn_recover(self->db_env,
6133 preplist, PREPLIST_LEN, &retp, flags);
6134#undef PREPLIST_LEN
6135 MYDB_END_ALLOW_THREADS
6136 if (err) {
6137 Py_DECREF(list);
6138 RETURN_IF_ERR();
6139 }
6140 if (!retp) break;
6141 flags=DB_NEXT; /* Prepare for next loop pass */
6142 for (i=0; i<retp; i++) {
Christian Heimes593daf52008-05-26 12:51:38 +00006143 gid=PyBytes_FromStringAndSize((char *)(preplist[i].gid),
Matthias Klose54cc5392010-03-15 12:46:18 +00006144 DB_GID_SIZE);
Jesus Ceaef9764f2008-05-13 18:45:46 +00006145 if (!gid) {
6146 Py_DECREF(list);
6147 return NULL;
6148 }
Jesus Cea6557aac2010-03-22 14:22:26 +00006149 txn=newDBTxnObject(self, NULL, preplist[i].txn, 0);
Jesus Ceaef9764f2008-05-13 18:45:46 +00006150 if (!txn) {
6151 Py_DECREF(list);
6152 Py_DECREF(gid);
6153 return NULL;
6154 }
6155 txn->flag_prepare=1; /* Recover state */
6156 tuple=PyTuple_New(2);
6157 if (!tuple) {
6158 Py_DECREF(list);
6159 Py_DECREF(gid);
6160 Py_DECREF(txn);
6161 return NULL;
6162 }
6163 if (PyTuple_SetItem(tuple, 0, gid)) {
6164 Py_DECREF(list);
6165 Py_DECREF(gid);
6166 Py_DECREF(txn);
6167 Py_DECREF(tuple);
6168 return NULL;
6169 }
6170 if (PyTuple_SetItem(tuple, 1, (PyObject *)txn)) {
6171 Py_DECREF(list);
6172 Py_DECREF(txn);
6173 Py_DECREF(tuple); /* This delete the "gid" also */
6174 return NULL;
6175 }
6176 if (PyList_Append(list, tuple)) {
6177 Py_DECREF(list);
6178 Py_DECREF(tuple);/* This delete the "gid" and the "txn" also */
6179 return NULL;
6180 }
6181 Py_DECREF(tuple);
6182 }
6183 }
6184 return list;
6185}
Jesus Ceaef9764f2008-05-13 18:45:46 +00006186
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006187static PyObject*
6188DBEnv_txn_begin(DBEnvObject* self, PyObject* args, PyObject* kwargs)
6189{
6190 int flags = 0;
6191 PyObject* txnobj = NULL;
6192 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00006193 static char* kwnames[] = { "parent", "flags", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006194
6195 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Oi:txn_begin", kwnames,
6196 &txnobj, &flags))
6197 return NULL;
6198
6199 if (!checkTxnObj(txnobj, &txn))
6200 return NULL;
6201 CHECK_ENV_NOT_CLOSED(self);
6202
Jesus Ceaef9764f2008-05-13 18:45:46 +00006203 return (PyObject*)newDBTxnObject(self, (DBTxnObject *)txnobj, NULL, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006204}
6205
6206
6207static PyObject*
6208DBEnv_txn_checkpoint(DBEnvObject* self, PyObject* args)
6209{
6210 int err, kbyte=0, min=0, flags=0;
6211
6212 if (!PyArg_ParseTuple(args, "|iii:txn_checkpoint", &kbyte, &min, &flags))
6213 return NULL;
6214 CHECK_ENV_NOT_CLOSED(self);
6215
6216 MYDB_BEGIN_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006217 err = self->db_env->txn_checkpoint(self->db_env, kbyte, min, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006218 MYDB_END_ALLOW_THREADS;
6219 RETURN_IF_ERR();
6220 RETURN_NONE();
6221}
6222
Jesus Cea6557aac2010-03-22 14:22:26 +00006223static PyObject*
6224DBEnv_get_tx_max(DBEnvObject* self)
6225{
6226 int err;
6227 u_int32_t max;
6228
6229 CHECK_ENV_NOT_CLOSED(self);
6230
6231 MYDB_BEGIN_ALLOW_THREADS;
6232 err = self->db_env->get_tx_max(self->db_env, &max);
6233 MYDB_END_ALLOW_THREADS;
6234 RETURN_IF_ERR();
6235 return PyLong_FromUnsignedLong(max);
6236}
Jesus Cea6557aac2010-03-22 14:22:26 +00006237
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006238static PyObject*
6239DBEnv_set_tx_max(DBEnvObject* self, PyObject* args)
6240{
6241 int err, max;
6242
6243 if (!PyArg_ParseTuple(args, "i:set_tx_max", &max))
6244 return NULL;
6245 CHECK_ENV_NOT_CLOSED(self);
6246
Jesus Cea6557aac2010-03-22 14:22:26 +00006247 MYDB_BEGIN_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006248 err = self->db_env->set_tx_max(self->db_env, max);
Jesus Cea6557aac2010-03-22 14:22:26 +00006249 MYDB_END_ALLOW_THREADS;
Gregory P. Smith8a474042006-01-27 07:05:40 +00006250 RETURN_IF_ERR();
6251 RETURN_NONE();
6252}
6253
Jesus Cea6557aac2010-03-22 14:22:26 +00006254static PyObject*
6255DBEnv_get_tx_timestamp(DBEnvObject* self)
6256{
6257 int err;
6258 time_t timestamp;
6259
6260 CHECK_ENV_NOT_CLOSED(self);
6261
6262 MYDB_BEGIN_ALLOW_THREADS;
6263 err = self->db_env->get_tx_timestamp(self->db_env, &timestamp);
6264 MYDB_END_ALLOW_THREADS;
6265 RETURN_IF_ERR();
6266 return NUMBER_FromLong(timestamp);
6267}
Jesus Cea6557aac2010-03-22 14:22:26 +00006268
Gregory P. Smith8a474042006-01-27 07:05:40 +00006269static PyObject*
6270DBEnv_set_tx_timestamp(DBEnvObject* self, PyObject* args)
6271{
6272 int err;
Thomas Wouters9d63cca2006-03-01 01:01:55 +00006273 long stamp;
6274 time_t timestamp;
Gregory P. Smith8a474042006-01-27 07:05:40 +00006275
Thomas Wouters9d63cca2006-03-01 01:01:55 +00006276 if (!PyArg_ParseTuple(args, "l:set_tx_timestamp", &stamp))
Gregory P. Smith8a474042006-01-27 07:05:40 +00006277 return NULL;
6278 CHECK_ENV_NOT_CLOSED(self);
Thomas Wouters9d63cca2006-03-01 01:01:55 +00006279 timestamp = (time_t)stamp;
Jesus Cea6557aac2010-03-22 14:22:26 +00006280 MYDB_BEGIN_ALLOW_THREADS;
Thomas Wouters9d63cca2006-03-01 01:01:55 +00006281 err = self->db_env->set_tx_timestamp(self->db_env, &timestamp);
Jesus Cea6557aac2010-03-22 14:22:26 +00006282 MYDB_END_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006283 RETURN_IF_ERR();
6284 RETURN_NONE();
6285}
6286
6287
6288static PyObject*
6289DBEnv_lock_detect(DBEnvObject* self, PyObject* args)
6290{
6291 int err, atype, flags=0;
6292 int aborted = 0;
6293
6294 if (!PyArg_ParseTuple(args, "i|i:lock_detect", &atype, &flags))
6295 return NULL;
6296 CHECK_ENV_NOT_CLOSED(self);
6297
6298 MYDB_BEGIN_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006299 err = self->db_env->lock_detect(self->db_env, flags, atype, &aborted);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006300 MYDB_END_ALLOW_THREADS;
6301 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00006302 return NUMBER_FromLong(aborted);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006303}
6304
6305
6306static PyObject*
6307DBEnv_lock_get(DBEnvObject* self, PyObject* args)
6308{
6309 int flags=0;
6310 int locker, lock_mode;
6311 DBT obj;
6312 PyObject* objobj;
6313
6314 if (!PyArg_ParseTuple(args, "iOi|i:lock_get", &locker, &objobj, &lock_mode, &flags))
6315 return NULL;
6316
6317
6318 if (!make_dbt(objobj, &obj))
6319 return NULL;
6320
6321 return (PyObject*)newDBLockObject(self, locker, &obj, lock_mode, flags);
6322}
6323
6324
6325static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00006326DBEnv_lock_id(DBEnvObject* self)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006327{
6328 int err;
6329 u_int32_t theID;
6330
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006331 CHECK_ENV_NOT_CLOSED(self);
6332 MYDB_BEGIN_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006333 err = self->db_env->lock_id(self->db_env, &theID);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006334 MYDB_END_ALLOW_THREADS;
6335 RETURN_IF_ERR();
6336
Jesus Ceac5a11fa2008-07-23 11:38:42 +00006337 return NUMBER_FromLong((long)theID);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006338}
6339
Gregory P. Smithac11e022007-11-05 02:56:31 +00006340static PyObject*
6341DBEnv_lock_id_free(DBEnvObject* self, PyObject* args)
6342{
6343 int err;
6344 u_int32_t theID;
6345
6346 if (!PyArg_ParseTuple(args, "I:lock_id_free", &theID))
6347 return NULL;
6348
6349 CHECK_ENV_NOT_CLOSED(self);
6350 MYDB_BEGIN_ALLOW_THREADS;
6351 err = self->db_env->lock_id_free(self->db_env, theID);
6352 MYDB_END_ALLOW_THREADS;
6353 RETURN_IF_ERR();
6354 RETURN_NONE();
6355}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006356
6357static PyObject*
6358DBEnv_lock_put(DBEnvObject* self, PyObject* args)
6359{
6360 int err;
6361 DBLockObject* dblockobj;
6362
6363 if (!PyArg_ParseTuple(args, "O!:lock_put", &DBLock_Type, &dblockobj))
6364 return NULL;
6365
6366 CHECK_ENV_NOT_CLOSED(self);
6367 MYDB_BEGIN_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006368 err = self->db_env->lock_put(self->db_env, &dblockobj->lock);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006369 MYDB_END_ALLOW_THREADS;
6370 RETURN_IF_ERR();
6371 RETURN_NONE();
6372}
6373
Gregory P. Smithdb8a8072006-06-05 01:56:15 +00006374#if (DBVER >= 44)
6375static PyObject*
Jesus Cea6557aac2010-03-22 14:22:26 +00006376DBEnv_fileid_reset(DBEnvObject* self, PyObject* args, PyObject* kwargs)
6377{
6378 int err;
6379 char *file;
6380 u_int32_t flags = 0;
6381 static char* kwnames[] = { "file", "flags", NULL};
6382
6383 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "z|i:fileid_reset", kwnames,
6384 &file, &flags))
6385 return NULL;
6386 CHECK_ENV_NOT_CLOSED(self);
6387
6388 MYDB_BEGIN_ALLOW_THREADS;
6389 err = self->db_env->fileid_reset(self->db_env, file, flags);
6390 MYDB_END_ALLOW_THREADS;
6391 RETURN_IF_ERR();
6392 RETURN_NONE();
6393}
6394
6395static PyObject*
Gregory P. Smithdb8a8072006-06-05 01:56:15 +00006396DBEnv_lsn_reset(DBEnvObject* self, PyObject* args, PyObject* kwargs)
6397{
6398 int err;
6399 char *file;
6400 u_int32_t flags = 0;
6401 static char* kwnames[] = { "file", "flags", NULL};
6402
6403 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "z|i:lsn_reset", kwnames,
6404 &file, &flags))
6405 return NULL;
6406 CHECK_ENV_NOT_CLOSED(self);
6407
6408 MYDB_BEGIN_ALLOW_THREADS;
6409 err = self->db_env->lsn_reset(self->db_env, file, flags);
6410 MYDB_END_ALLOW_THREADS;
6411 RETURN_IF_ERR();
6412 RETURN_NONE();
6413}
6414#endif /* DBVER >= 4.4 */
6415
Jesus Cea6557aac2010-03-22 14:22:26 +00006416
Jesus Cea6557aac2010-03-22 14:22:26 +00006417static PyObject*
6418DBEnv_stat_print(DBEnvObject* self, PyObject* args, PyObject *kwargs)
6419{
6420 int err;
6421 int flags=0;
6422 static char* kwnames[] = { "flags", NULL };
6423
6424 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:stat_print",
6425 kwnames, &flags))
6426 {
6427 return NULL;
6428 }
6429 CHECK_ENV_NOT_CLOSED(self);
6430 MYDB_BEGIN_ALLOW_THREADS;
6431 err = self->db_env->stat_print(self->db_env, flags);
6432 MYDB_END_ALLOW_THREADS;
6433 RETURN_IF_ERR();
6434 RETURN_NONE();
6435}
Jesus Cea6557aac2010-03-22 14:22:26 +00006436
6437
Gregory P. Smith76a82e82006-06-05 01:39:52 +00006438static PyObject*
6439DBEnv_log_stat(DBEnvObject* self, PyObject* args)
6440{
6441 int err;
6442 DB_LOG_STAT* statp = NULL;
6443 PyObject* d = NULL;
6444 u_int32_t flags = 0;
6445
6446 if (!PyArg_ParseTuple(args, "|i:log_stat", &flags))
6447 return NULL;
6448 CHECK_ENV_NOT_CLOSED(self);
6449
6450 MYDB_BEGIN_ALLOW_THREADS;
6451 err = self->db_env->log_stat(self->db_env, &statp, flags);
6452 MYDB_END_ALLOW_THREADS;
6453 RETURN_IF_ERR();
6454
6455 /* Turn the stat structure into a dictionary */
6456 d = PyDict_New();
6457 if (d == NULL) {
6458 if (statp)
6459 free(statp);
6460 return NULL;
6461 }
6462
6463#define MAKE_ENTRY(name) _addIntToDict(d, #name, statp->st_##name)
6464
6465 MAKE_ENTRY(magic);
6466 MAKE_ENTRY(version);
6467 MAKE_ENTRY(mode);
6468 MAKE_ENTRY(lg_bsize);
6469#if (DBVER >= 44)
6470 MAKE_ENTRY(lg_size);
6471 MAKE_ENTRY(record);
6472#endif
Gregory P. Smith76a82e82006-06-05 01:39:52 +00006473 MAKE_ENTRY(w_mbytes);
6474 MAKE_ENTRY(w_bytes);
6475 MAKE_ENTRY(wc_mbytes);
6476 MAKE_ENTRY(wc_bytes);
6477 MAKE_ENTRY(wcount);
6478 MAKE_ENTRY(wcount_fill);
6479#if (DBVER >= 44)
6480 MAKE_ENTRY(rcount);
6481#endif
6482 MAKE_ENTRY(scount);
6483 MAKE_ENTRY(cur_file);
6484 MAKE_ENTRY(cur_offset);
6485 MAKE_ENTRY(disk_file);
6486 MAKE_ENTRY(disk_offset);
6487 MAKE_ENTRY(maxcommitperflush);
6488 MAKE_ENTRY(mincommitperflush);
6489 MAKE_ENTRY(regsize);
6490 MAKE_ENTRY(region_wait);
6491 MAKE_ENTRY(region_nowait);
6492
6493#undef MAKE_ENTRY
6494 free(statp);
6495 return d;
6496} /* DBEnv_log_stat */
Gregory P. Smith76a82e82006-06-05 01:39:52 +00006497
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006498
Jesus Cea6557aac2010-03-22 14:22:26 +00006499static PyObject*
6500DBEnv_log_stat_print(DBEnvObject* self, PyObject* args, PyObject *kwargs)
6501{
6502 int err;
6503 int flags=0;
6504 static char* kwnames[] = { "flags", NULL };
6505
6506 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:log_stat_print",
6507 kwnames, &flags))
6508 {
6509 return NULL;
6510 }
6511 CHECK_ENV_NOT_CLOSED(self);
6512 MYDB_BEGIN_ALLOW_THREADS;
6513 err = self->db_env->log_stat_print(self->db_env, flags);
6514 MYDB_END_ALLOW_THREADS;
6515 RETURN_IF_ERR();
6516 RETURN_NONE();
6517}
Jesus Cea6557aac2010-03-22 14:22:26 +00006518
6519
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006520static PyObject*
6521DBEnv_lock_stat(DBEnvObject* self, PyObject* args)
6522{
6523 int err;
6524 DB_LOCK_STAT* sp;
6525 PyObject* d = NULL;
Martin v. Löwisb2c7aff2002-11-23 11:26:07 +00006526 u_int32_t flags = 0;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006527
6528 if (!PyArg_ParseTuple(args, "|i:lock_stat", &flags))
6529 return NULL;
6530 CHECK_ENV_NOT_CLOSED(self);
6531
6532 MYDB_BEGIN_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006533 err = self->db_env->lock_stat(self->db_env, &sp, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006534 MYDB_END_ALLOW_THREADS;
6535 RETURN_IF_ERR();
6536
6537 /* Turn the stat structure into a dictionary */
6538 d = PyDict_New();
6539 if (d == NULL) {
6540 free(sp);
6541 return NULL;
6542 }
6543
6544#define MAKE_ENTRY(name) _addIntToDict(d, #name, sp->st_##name)
6545
Jesus Ceaef9764f2008-05-13 18:45:46 +00006546 MAKE_ENTRY(id);
6547 MAKE_ENTRY(cur_maxid);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006548 MAKE_ENTRY(nmodes);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006549 MAKE_ENTRY(maxlocks);
6550 MAKE_ENTRY(maxlockers);
6551 MAKE_ENTRY(maxobjects);
6552 MAKE_ENTRY(nlocks);
6553 MAKE_ENTRY(maxnlocks);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006554 MAKE_ENTRY(nlockers);
6555 MAKE_ENTRY(maxnlockers);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006556 MAKE_ENTRY(nobjects);
6557 MAKE_ENTRY(maxnobjects);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006558 MAKE_ENTRY(nrequests);
6559 MAKE_ENTRY(nreleases);
Jesus Ceaef9764f2008-05-13 18:45:46 +00006560#if (DBVER >= 44)
6561 MAKE_ENTRY(nupgrade);
6562 MAKE_ENTRY(ndowngrade);
6563#endif
Gregory P. Smith29602d22006-01-24 09:46:48 +00006564#if (DBVER < 44)
6565 MAKE_ENTRY(nnowaits); /* these were renamed in 4.4 */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006566 MAKE_ENTRY(nconflicts);
Gregory P. Smith29602d22006-01-24 09:46:48 +00006567#else
6568 MAKE_ENTRY(lock_nowait);
6569 MAKE_ENTRY(lock_wait);
6570#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006571 MAKE_ENTRY(ndeadlocks);
Jesus Ceaef9764f2008-05-13 18:45:46 +00006572 MAKE_ENTRY(locktimeout);
6573 MAKE_ENTRY(txntimeout);
Jesus Ceaef9764f2008-05-13 18:45:46 +00006574 MAKE_ENTRY(nlocktimeouts);
6575 MAKE_ENTRY(ntxntimeouts);
Jesus Ceaef9764f2008-05-13 18:45:46 +00006576#if (DBVER >= 46)
6577 MAKE_ENTRY(objs_wait);
6578 MAKE_ENTRY(objs_nowait);
6579 MAKE_ENTRY(lockers_wait);
6580 MAKE_ENTRY(lockers_nowait);
Jesus Ceaca3939c2008-05-22 15:27:38 +00006581#if (DBVER >= 47)
6582 MAKE_ENTRY(lock_wait);
6583 MAKE_ENTRY(lock_nowait);
6584#else
Jesus Ceaef9764f2008-05-13 18:45:46 +00006585 MAKE_ENTRY(locks_wait);
6586 MAKE_ENTRY(locks_nowait);
Jesus Ceaca3939c2008-05-22 15:27:38 +00006587#endif
Jesus Ceaef9764f2008-05-13 18:45:46 +00006588 MAKE_ENTRY(hash_len);
6589#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006590 MAKE_ENTRY(regsize);
6591 MAKE_ENTRY(region_wait);
6592 MAKE_ENTRY(region_nowait);
6593
6594#undef MAKE_ENTRY
6595 free(sp);
6596 return d;
6597}
6598
Jesus Cea6557aac2010-03-22 14:22:26 +00006599static PyObject*
6600DBEnv_lock_stat_print(DBEnvObject* self, PyObject* args, PyObject *kwargs)
6601{
6602 int err;
6603 int flags=0;
6604 static char* kwnames[] = { "flags", NULL };
6605
6606 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:lock_stat_print",
6607 kwnames, &flags))
6608 {
6609 return NULL;
6610 }
6611 CHECK_ENV_NOT_CLOSED(self);
6612 MYDB_BEGIN_ALLOW_THREADS;
6613 err = self->db_env->lock_stat_print(self->db_env, flags);
6614 MYDB_END_ALLOW_THREADS;
6615 RETURN_IF_ERR();
6616 RETURN_NONE();
6617}
Jesus Cea6557aac2010-03-22 14:22:26 +00006618
6619
6620static PyObject*
6621DBEnv_log_cursor(DBEnvObject* self)
6622{
6623 int err;
6624 DB_LOGC* dblogc;
6625
6626 CHECK_ENV_NOT_CLOSED(self);
6627
6628 MYDB_BEGIN_ALLOW_THREADS;
6629 err = self->db_env->log_cursor(self->db_env, &dblogc, 0);
6630 MYDB_END_ALLOW_THREADS;
6631 RETURN_IF_ERR();
6632 return (PyObject*) newDBLogCursorObject(dblogc, self);
6633}
6634
6635
Jesus Ceaef9764f2008-05-13 18:45:46 +00006636static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00006637DBEnv_log_flush(DBEnvObject* self)
Jesus Ceaef9764f2008-05-13 18:45:46 +00006638{
6639 int err;
6640
Jesus Ceaef9764f2008-05-13 18:45:46 +00006641 CHECK_ENV_NOT_CLOSED(self);
6642
6643 MYDB_BEGIN_ALLOW_THREADS
6644 err = self->db_env->log_flush(self->db_env, NULL);
6645 MYDB_END_ALLOW_THREADS
6646
6647 RETURN_IF_ERR();
6648 RETURN_NONE();
6649}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006650
6651static PyObject*
Jesus Cea6557aac2010-03-22 14:22:26 +00006652DBEnv_log_file(DBEnvObject* self, PyObject* args)
6653{
6654 int err;
6655 DB_LSN lsn = {0, 0};
6656 int size = 20;
6657 char *name = NULL;
6658 PyObject *retval;
6659
6660 if (!PyArg_ParseTuple(args, "(ii):log_file", &lsn.file, &lsn.offset))
6661 return NULL;
6662
6663 CHECK_ENV_NOT_CLOSED(self);
6664
6665 do {
6666 name = malloc(size);
6667 if (!name) {
6668 PyErr_NoMemory();
6669 return NULL;
6670 }
6671 MYDB_BEGIN_ALLOW_THREADS;
6672 err = self->db_env->log_file(self->db_env, &lsn, name, size);
6673 MYDB_END_ALLOW_THREADS;
6674 if (err == EINVAL) {
6675 free(name);
6676 size *= 2;
6677 } else if (err) {
6678 free(name);
6679 RETURN_IF_ERR();
6680 assert(0); /* Unreachable... supposely */
6681 return NULL;
6682 }
6683/*
6684** If the final buffer we try is too small, we will
6685** get this exception:
6686** DBInvalidArgError:
6687** (22, 'Invalid argument -- DB_ENV->log_file: name buffer is too short')
6688*/
6689 } while ((err == EINVAL) && (size<(1<<17)));
6690
6691 RETURN_IF_ERR(); /* Maybe the size is not the problem */
6692
6693 retval = Py_BuildValue("s", name);
6694 free(name);
6695 return retval;
6696}
6697
6698
6699#if (DBVER >= 44)
6700static PyObject*
6701DBEnv_log_printf(DBEnvObject* self, PyObject* args, PyObject *kwargs)
6702{
6703 int err;
6704 char *string;
6705 PyObject *txnobj = NULL;
6706 DB_TXN *txn = NULL;
6707 static char* kwnames[] = {"string", "txn", NULL };
6708
6709 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|O:log_printf", kwnames,
6710 &string, &txnobj))
6711 return NULL;
6712
6713 CHECK_ENV_NOT_CLOSED(self);
6714
6715 if (!checkTxnObj(txnobj, &txn))
6716 return NULL;
6717
6718 /*
6719 ** Do not use the format string directly, to avoid attacks.
6720 */
6721 MYDB_BEGIN_ALLOW_THREADS;
6722 err = self->db_env->log_printf(self->db_env, txn, "%s", string);
6723 MYDB_END_ALLOW_THREADS;
6724
6725 RETURN_IF_ERR();
6726 RETURN_NONE();
6727}
6728#endif
6729
6730
6731static PyObject*
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006732DBEnv_log_archive(DBEnvObject* self, PyObject* args)
6733{
6734 int flags=0;
6735 int err;
Gregory P. Smith3dd20022006-06-05 00:31:01 +00006736 char **log_list = NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006737 PyObject* list;
6738 PyObject* item = NULL;
6739
6740 if (!PyArg_ParseTuple(args, "|i:log_archive", &flags))
6741 return NULL;
6742
6743 CHECK_ENV_NOT_CLOSED(self);
6744 MYDB_BEGIN_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006745 err = self->db_env->log_archive(self->db_env, &log_list, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006746 MYDB_END_ALLOW_THREADS;
6747 RETURN_IF_ERR();
6748
Gregory P. Smithbad47452006-06-05 00:33:35 +00006749 list = PyList_New(0);
6750 if (list == NULL) {
6751 if (log_list)
6752 free(log_list);
6753 return NULL;
6754 }
6755
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006756 if (log_list) {
Gregory P. Smith3dd20022006-06-05 00:31:01 +00006757 char **log_list_start;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006758 for (log_list_start = log_list; *log_list != NULL; ++log_list) {
Christian Heimes593daf52008-05-26 12:51:38 +00006759 item = PyBytes_FromString (*log_list);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006760 if (item == NULL) {
6761 Py_DECREF(list);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006762 list = NULL;
6763 break;
6764 }
Jesus Ceac5a11fa2008-07-23 11:38:42 +00006765 if (PyList_Append(list, item)) {
6766 Py_DECREF(list);
6767 list = NULL;
6768 Py_DECREF(item);
6769 break;
6770 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006771 Py_DECREF(item);
6772 }
6773 free(log_list_start);
6774 }
6775 return list;
6776}
6777
6778
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07006779#if (DBVER >= 52)
6780static PyObject*
6781DBEnv_repmgr_site(DBEnvObject* self, PyObject* args, PyObject *kwargs)
6782{
6783 int err;
6784 DB_SITE* site;
6785 char *host;
6786 u_int port;
6787 static char* kwnames[] = {"host", "port", NULL};
6788
6789 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "si:repmgr_site", kwnames,
6790 &host, &port))
6791 return NULL;
6792
6793 CHECK_ENV_NOT_CLOSED(self);
6794
6795 MYDB_BEGIN_ALLOW_THREADS;
6796 err = self->db_env->repmgr_site(self->db_env, host, port, &site, 0);
6797 MYDB_END_ALLOW_THREADS;
6798 RETURN_IF_ERR();
6799 return (PyObject*) newDBSiteObject(site, self);
6800}
6801
6802static PyObject*
6803DBEnv_repmgr_site_by_eid(DBEnvObject* self, PyObject* args, PyObject *kwargs)
6804{
6805 int err;
6806 DB_SITE* site;
6807 int eid;
6808 static char* kwnames[] = {"eid", NULL};
6809
6810 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i:repmgr_site_by_eid",
6811 kwnames, &eid))
6812 return NULL;
6813
6814 CHECK_ENV_NOT_CLOSED(self);
6815
6816 MYDB_BEGIN_ALLOW_THREADS;
6817 err = self->db_env->repmgr_site_by_eid(self->db_env, eid, &site);
6818 MYDB_END_ALLOW_THREADS;
6819 RETURN_IF_ERR();
6820 return (PyObject*) newDBSiteObject(site, self);
6821}
6822#endif
6823
6824
Jesus Cea6557aac2010-03-22 14:22:26 +00006825#if (DBVER >= 44)
6826static PyObject*
6827DBEnv_mutex_stat(DBEnvObject* self, PyObject* args)
6828{
6829 int err;
6830 DB_MUTEX_STAT* statp = NULL;
6831 PyObject* d = NULL;
6832 u_int32_t flags = 0;
6833
6834 if (!PyArg_ParseTuple(args, "|i:mutex_stat", &flags))
6835 return NULL;
6836 CHECK_ENV_NOT_CLOSED(self);
6837
6838 MYDB_BEGIN_ALLOW_THREADS;
6839 err = self->db_env->mutex_stat(self->db_env, &statp, flags);
6840 MYDB_END_ALLOW_THREADS;
6841 RETURN_IF_ERR();
6842
6843 /* Turn the stat structure into a dictionary */
6844 d = PyDict_New();
6845 if (d == NULL) {
6846 if (statp)
6847 free(statp);
6848 return NULL;
6849 }
6850
6851#define MAKE_ENTRY(name) _addIntToDict(d, #name, statp->st_##name)
6852
6853 MAKE_ENTRY(mutex_align);
6854 MAKE_ENTRY(mutex_tas_spins);
6855 MAKE_ENTRY(mutex_cnt);
6856 MAKE_ENTRY(mutex_free);
6857 MAKE_ENTRY(mutex_inuse);
6858 MAKE_ENTRY(mutex_inuse_max);
6859 MAKE_ENTRY(regsize);
6860 MAKE_ENTRY(region_wait);
6861 MAKE_ENTRY(region_nowait);
6862
6863#undef MAKE_ENTRY
6864 free(statp);
6865 return d;
6866}
6867#endif
6868
6869
6870#if (DBVER >= 44)
6871static PyObject*
6872DBEnv_mutex_stat_print(DBEnvObject* self, PyObject* args, PyObject *kwargs)
6873{
6874 int err;
6875 int flags=0;
6876 static char* kwnames[] = { "flags", NULL };
6877
6878 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:mutex_stat_print",
6879 kwnames, &flags))
6880 {
6881 return NULL;
6882 }
6883 CHECK_ENV_NOT_CLOSED(self);
6884 MYDB_BEGIN_ALLOW_THREADS;
6885 err = self->db_env->mutex_stat_print(self->db_env, flags);
6886 MYDB_END_ALLOW_THREADS;
6887 RETURN_IF_ERR();
6888 RETURN_NONE();
6889}
6890#endif
6891
6892
Jesus Cea6557aac2010-03-22 14:22:26 +00006893static PyObject*
6894DBEnv_txn_stat_print(DBEnvObject* self, PyObject* args, PyObject *kwargs)
6895{
6896 int err;
6897 int flags=0;
6898 static char* kwnames[] = { "flags", NULL };
6899
6900 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:stat_print",
6901 kwnames, &flags))
6902 {
6903 return NULL;
6904 }
6905
6906 CHECK_ENV_NOT_CLOSED(self);
6907
6908 MYDB_BEGIN_ALLOW_THREADS;
6909 err = self->db_env->txn_stat_print(self->db_env, flags);
6910 MYDB_END_ALLOW_THREADS;
6911 RETURN_IF_ERR();
6912 RETURN_NONE();
6913}
Jesus Cea6557aac2010-03-22 14:22:26 +00006914
6915
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006916static PyObject*
6917DBEnv_txn_stat(DBEnvObject* self, PyObject* args)
6918{
6919 int err;
6920 DB_TXN_STAT* sp;
6921 PyObject* d = NULL;
Martin v. Löwisb2c7aff2002-11-23 11:26:07 +00006922 u_int32_t flags=0;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006923
6924 if (!PyArg_ParseTuple(args, "|i:txn_stat", &flags))
6925 return NULL;
6926 CHECK_ENV_NOT_CLOSED(self);
6927
6928 MYDB_BEGIN_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006929 err = self->db_env->txn_stat(self->db_env, &sp, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006930 MYDB_END_ALLOW_THREADS;
6931 RETURN_IF_ERR();
6932
6933 /* Turn the stat structure into a dictionary */
6934 d = PyDict_New();
6935 if (d == NULL) {
6936 free(sp);
6937 return NULL;
6938 }
6939
Jesus Ceaef9764f2008-05-13 18:45:46 +00006940#define MAKE_ENTRY(name) _addIntToDict(d, #name, sp->st_##name)
6941#define MAKE_TIME_T_ENTRY(name) _addTimeTToDict(d, #name, sp->st_##name)
6942#define MAKE_DB_LSN_ENTRY(name) _addDB_lsnToDict(d, #name, sp->st_##name)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006943
Jesus Ceaef9764f2008-05-13 18:45:46 +00006944 MAKE_DB_LSN_ENTRY(last_ckp);
Kristján Valur Jónssonbd77c032007-04-26 15:24:54 +00006945 MAKE_TIME_T_ENTRY(time_ckp);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006946 MAKE_ENTRY(last_txnid);
6947 MAKE_ENTRY(maxtxns);
6948 MAKE_ENTRY(nactive);
6949 MAKE_ENTRY(maxnactive);
Jesus Ceaef9764f2008-05-13 18:45:46 +00006950#if (DBVER >= 45)
6951 MAKE_ENTRY(nsnapshot);
6952 MAKE_ENTRY(maxnsnapshot);
6953#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006954 MAKE_ENTRY(nbegins);
6955 MAKE_ENTRY(naborts);
6956 MAKE_ENTRY(ncommits);
Jesus Ceaef9764f2008-05-13 18:45:46 +00006957 MAKE_ENTRY(nrestores);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006958 MAKE_ENTRY(regsize);
6959 MAKE_ENTRY(region_wait);
6960 MAKE_ENTRY(region_nowait);
6961
Jesus Ceaef9764f2008-05-13 18:45:46 +00006962#undef MAKE_DB_LSN_ENTRY
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006963#undef MAKE_ENTRY
Kristján Valur Jónssonbd77c032007-04-26 15:24:54 +00006964#undef MAKE_TIME_T_ENTRY
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006965 free(sp);
6966 return d;
6967}
6968
6969
6970static PyObject*
6971DBEnv_set_get_returns_none(DBEnvObject* self, PyObject* args)
6972{
6973 int flags=0;
Gregory P. Smith455d46f2003-07-09 04:45:59 +00006974 int oldValue=0;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006975
6976 if (!PyArg_ParseTuple(args,"i:set_get_returns_none", &flags))
6977 return NULL;
6978 CHECK_ENV_NOT_CLOSED(self);
6979
Gregory P. Smith455d46f2003-07-09 04:45:59 +00006980 if (self->moduleFlags.getReturnsNone)
6981 ++oldValue;
6982 if (self->moduleFlags.cursorSetReturnsNone)
6983 ++oldValue;
6984 self->moduleFlags.getReturnsNone = (flags >= 1);
6985 self->moduleFlags.cursorSetReturnsNone = (flags >= 2);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00006986 return NUMBER_FromLong(oldValue);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006987}
6988
Jesus Ceac5a11fa2008-07-23 11:38:42 +00006989static PyObject*
6990DBEnv_get_private(DBEnvObject* self)
6991{
6992 /* We can give out the private field even if dbenv is closed */
Jesus Cea4907d272008-08-31 14:00:51 +00006993 Py_INCREF(self->private_obj);
6994 return self->private_obj;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00006995}
6996
6997static PyObject*
Jesus Cea4907d272008-08-31 14:00:51 +00006998DBEnv_set_private(DBEnvObject* self, PyObject* private_obj)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00006999{
7000 /* We can set the private field even if dbenv is closed */
Jesus Cea4907d272008-08-31 14:00:51 +00007001 Py_INCREF(private_obj);
Serhiy Storchaka763a61c2016-04-10 18:05:12 +03007002 Py_SETREF(self->private_obj, private_obj);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007003 RETURN_NONE();
7004}
7005
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07007006#if (DBVER >= 47)
7007static PyObject*
7008DBEnv_set_intermediate_dir_mode(DBEnvObject* self, PyObject* args)
7009{
7010 int err;
7011 const char *mode;
7012
7013 if (!PyArg_ParseTuple(args,"s:set_intermediate_dir_mode", &mode))
7014 return NULL;
7015
7016 CHECK_ENV_NOT_CLOSED(self);
7017
7018 MYDB_BEGIN_ALLOW_THREADS;
7019 err = self->db_env->set_intermediate_dir_mode(self->db_env, mode);
7020 MYDB_END_ALLOW_THREADS;
7021 RETURN_IF_ERR();
7022 RETURN_NONE();
7023}
7024
7025static PyObject*
7026DBEnv_get_intermediate_dir_mode(DBEnvObject* self)
7027{
7028 int err;
7029 const char *mode;
7030
7031 CHECK_ENV_NOT_CLOSED(self);
7032
7033 MYDB_BEGIN_ALLOW_THREADS;
7034 err = self->db_env->get_intermediate_dir_mode(self->db_env, &mode);
7035 MYDB_END_ALLOW_THREADS;
7036 RETURN_IF_ERR();
7037 return Py_BuildValue("s", mode);
7038}
7039#endif
7040
7041#if (DBVER < 47)
7042static PyObject*
7043DBEnv_set_intermediate_dir(DBEnvObject* self, PyObject* args)
7044{
7045 int err;
7046 int mode;
7047 u_int32_t flags;
7048
7049 if (!PyArg_ParseTuple(args, "iI:set_intermediate_dir", &mode, &flags))
7050 return NULL;
7051
7052 CHECK_ENV_NOT_CLOSED(self);
7053
7054 MYDB_BEGIN_ALLOW_THREADS;
7055 err = self->db_env->set_intermediate_dir(self->db_env, mode, flags);
7056 MYDB_END_ALLOW_THREADS;
7057 RETURN_IF_ERR();
7058 RETURN_NONE();
7059}
7060#endif
7061
7062static PyObject*
7063DBEnv_get_open_flags(DBEnvObject* self)
7064{
7065 int err;
7066 unsigned int flags;
7067
7068 CHECK_ENV_NOT_CLOSED(self);
7069
7070 MYDB_BEGIN_ALLOW_THREADS;
7071 err = self->db_env->get_open_flags(self->db_env, &flags);
7072 MYDB_END_ALLOW_THREADS;
7073 RETURN_IF_ERR();
7074 return NUMBER_FromLong(flags);
7075}
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007076
Matthias Klose54cc5392010-03-15 12:46:18 +00007077#if (DBVER < 48)
Jesus Ceaef9764f2008-05-13 18:45:46 +00007078static PyObject*
Jesus Ceaca3939c2008-05-22 15:27:38 +00007079DBEnv_set_rpc_server(DBEnvObject* self, PyObject* args, PyObject* kwargs)
7080{
7081 int err;
7082 char *host;
7083 long cl_timeout=0, sv_timeout=0;
7084
7085 static char* kwnames[] = { "host", "cl_timeout", "sv_timeout", NULL};
7086
7087 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|ll:set_rpc_server", kwnames,
7088 &host, &cl_timeout, &sv_timeout))
7089 return NULL;
7090 CHECK_ENV_NOT_CLOSED(self);
7091
7092 MYDB_BEGIN_ALLOW_THREADS;
7093 err = self->db_env->set_rpc_server(self->db_env, NULL, host, cl_timeout,
7094 sv_timeout, 0);
7095 MYDB_END_ALLOW_THREADS;
7096 RETURN_IF_ERR();
7097 RETURN_NONE();
7098}
Matthias Klose54cc5392010-03-15 12:46:18 +00007099#endif
Jesus Ceaca3939c2008-05-22 15:27:38 +00007100
Jesus Cea6557aac2010-03-22 14:22:26 +00007101static PyObject*
7102DBEnv_set_mp_max_openfd(DBEnvObject* self, PyObject* args)
7103{
7104 int err;
7105 int maxopenfd;
7106
7107 if (!PyArg_ParseTuple(args, "i:set_mp_max_openfd", &maxopenfd)) {
7108 return NULL;
7109 }
7110 CHECK_ENV_NOT_CLOSED(self);
7111 MYDB_BEGIN_ALLOW_THREADS;
7112 err = self->db_env->set_mp_max_openfd(self->db_env, maxopenfd);
7113 MYDB_END_ALLOW_THREADS;
7114 RETURN_IF_ERR();
7115 RETURN_NONE();
7116}
7117
7118static PyObject*
7119DBEnv_get_mp_max_openfd(DBEnvObject* self)
7120{
7121 int err;
7122 int maxopenfd;
7123
7124 CHECK_ENV_NOT_CLOSED(self);
7125
7126 MYDB_BEGIN_ALLOW_THREADS;
7127 err = self->db_env->get_mp_max_openfd(self->db_env, &maxopenfd);
7128 MYDB_END_ALLOW_THREADS;
7129 RETURN_IF_ERR();
7130 return NUMBER_FromLong(maxopenfd);
7131}
7132
7133
7134static PyObject*
7135DBEnv_set_mp_max_write(DBEnvObject* self, PyObject* args)
7136{
7137 int err;
7138 int maxwrite, maxwrite_sleep;
7139
7140 if (!PyArg_ParseTuple(args, "ii:set_mp_max_write", &maxwrite,
7141 &maxwrite_sleep)) {
7142 return NULL;
7143 }
7144 CHECK_ENV_NOT_CLOSED(self);
7145 MYDB_BEGIN_ALLOW_THREADS;
7146 err = self->db_env->set_mp_max_write(self->db_env, maxwrite,
7147 maxwrite_sleep);
7148 MYDB_END_ALLOW_THREADS;
7149 RETURN_IF_ERR();
7150 RETURN_NONE();
7151}
7152
7153static PyObject*
7154DBEnv_get_mp_max_write(DBEnvObject* self)
7155{
7156 int err;
7157 int maxwrite;
7158#if (DBVER >= 46)
7159 db_timeout_t maxwrite_sleep;
7160#else
7161 int maxwrite_sleep;
7162#endif
7163
7164 CHECK_ENV_NOT_CLOSED(self);
7165
7166 MYDB_BEGIN_ALLOW_THREADS;
7167 err = self->db_env->get_mp_max_write(self->db_env, &maxwrite,
7168 &maxwrite_sleep);
7169 MYDB_END_ALLOW_THREADS;
7170 RETURN_IF_ERR();
7171
7172 return Py_BuildValue("(ii)", maxwrite, (int)maxwrite_sleep);
7173}
Jesus Cea6557aac2010-03-22 14:22:26 +00007174
7175
Jesus Ceaca3939c2008-05-22 15:27:38 +00007176static PyObject*
Jesus Ceaef9764f2008-05-13 18:45:46 +00007177DBEnv_set_verbose(DBEnvObject* self, PyObject* args)
7178{
7179 int err;
7180 int which, onoff;
7181
7182 if (!PyArg_ParseTuple(args, "ii:set_verbose", &which, &onoff)) {
7183 return NULL;
7184 }
7185 CHECK_ENV_NOT_CLOSED(self);
7186 MYDB_BEGIN_ALLOW_THREADS;
7187 err = self->db_env->set_verbose(self->db_env, which, onoff);
7188 MYDB_END_ALLOW_THREADS;
7189 RETURN_IF_ERR();
7190 RETURN_NONE();
7191}
7192
Jesus Ceaef9764f2008-05-13 18:45:46 +00007193static PyObject*
7194DBEnv_get_verbose(DBEnvObject* self, PyObject* args)
7195{
7196 int err;
7197 int which;
7198 int verbose;
7199
7200 if (!PyArg_ParseTuple(args, "i:get_verbose", &which)) {
7201 return NULL;
7202 }
7203 CHECK_ENV_NOT_CLOSED(self);
7204 MYDB_BEGIN_ALLOW_THREADS;
7205 err = self->db_env->get_verbose(self->db_env, which, &verbose);
7206 MYDB_END_ALLOW_THREADS;
7207 RETURN_IF_ERR();
7208 return PyBool_FromLong(verbose);
7209}
Jesus Ceaef9764f2008-05-13 18:45:46 +00007210
7211#if (DBVER >= 45)
7212static void
7213_dbenv_event_notifyCallback(DB_ENV* db_env, u_int32_t event, void *event_info)
7214{
7215 DBEnvObject *dbenv;
7216 PyObject* callback;
7217 PyObject* args;
7218 PyObject* result = NULL;
7219
7220 MYDB_BEGIN_BLOCK_THREADS;
7221 dbenv = (DBEnvObject *)db_env->app_private;
7222 callback = dbenv->event_notifyCallback;
7223 if (callback) {
7224 if (event == DB_EVENT_REP_NEWMASTER) {
7225 args = Py_BuildValue("(Oii)", dbenv, event, *((int *)event_info));
7226 } else {
7227 args = Py_BuildValue("(OiO)", dbenv, event, Py_None);
7228 }
7229 if (args) {
7230 result = PyEval_CallObject(callback, args);
7231 }
7232 if ((!args) || (!result)) {
7233 PyErr_Print();
7234 }
7235 Py_XDECREF(args);
7236 Py_XDECREF(result);
7237 }
7238 MYDB_END_BLOCK_THREADS;
7239}
7240#endif
7241
7242#if (DBVER >= 45)
7243static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007244DBEnv_set_event_notify(DBEnvObject* self, PyObject* notifyFunc)
Jesus Ceaef9764f2008-05-13 18:45:46 +00007245{
7246 int err;
Jesus Ceaef9764f2008-05-13 18:45:46 +00007247
7248 CHECK_ENV_NOT_CLOSED(self);
7249
7250 if (!PyCallable_Check(notifyFunc)) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00007251 makeTypeError("Callable", notifyFunc);
7252 return NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00007253 }
7254
Jesus Ceaef9764f2008-05-13 18:45:46 +00007255 Py_INCREF(notifyFunc);
Serhiy Storchakabc62af12016-04-06 09:51:18 +03007256 Py_XSETREF(self->event_notifyCallback, notifyFunc);
Jesus Ceaef9764f2008-05-13 18:45:46 +00007257
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007258 /* This is to workaround a problem with un-initialized threads (see
7259 comment in DB_associate) */
7260#ifdef WITH_THREAD
7261 PyEval_InitThreads();
7262#endif
7263
Jesus Ceaef9764f2008-05-13 18:45:46 +00007264 MYDB_BEGIN_ALLOW_THREADS;
7265 err = self->db_env->set_event_notify(self->db_env, _dbenv_event_notifyCallback);
7266 MYDB_END_ALLOW_THREADS;
7267
7268 if (err) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00007269 Py_DECREF(notifyFunc);
7270 self->event_notifyCallback = NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00007271 }
7272
7273 RETURN_IF_ERR();
7274 RETURN_NONE();
7275}
7276#endif
7277
7278
7279/* --------------------------------------------------------------------- */
7280/* REPLICATION METHODS: Base Replication */
7281
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007282
7283static PyObject*
7284DBEnv_rep_process_message(DBEnvObject* self, PyObject* args)
7285{
7286 int err;
7287 PyObject *control_py, *rec_py;
7288 DBT control, rec;
7289 int envid;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007290 DB_LSN lsn;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007291
7292 if (!PyArg_ParseTuple(args, "OOi:rep_process_message", &control_py,
7293 &rec_py, &envid))
7294 return NULL;
7295 CHECK_ENV_NOT_CLOSED(self);
7296
7297 if (!make_dbt(control_py, &control))
7298 return NULL;
7299 if (!make_dbt(rec_py, &rec))
7300 return NULL;
7301
7302 MYDB_BEGIN_ALLOW_THREADS;
7303#if (DBVER >= 46)
7304 err = self->db_env->rep_process_message(self->db_env, &control, &rec,
7305 envid, &lsn);
7306#else
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007307 err = self->db_env->rep_process_message(self->db_env, &control, &rec,
7308 &envid, &lsn);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007309#endif
7310 MYDB_END_ALLOW_THREADS;
7311 switch (err) {
7312 case DB_REP_NEWMASTER :
7313 return Py_BuildValue("(iO)", envid, Py_None);
7314 break;
7315
7316 case DB_REP_DUPMASTER :
7317 case DB_REP_HOLDELECTION :
7318#if (DBVER >= 44)
7319 case DB_REP_IGNORE :
7320 case DB_REP_JOIN_FAILURE :
7321#endif
7322 return Py_BuildValue("(iO)", err, Py_None);
7323 break;
7324 case DB_REP_NEWSITE :
Jesus Cea4907d272008-08-31 14:00:51 +00007325 {
7326 PyObject *tmp, *r;
7327
7328 if (!(tmp = PyBytes_FromStringAndSize(rec.data, rec.size))) {
7329 return NULL;
7330 }
7331
7332 r = Py_BuildValue("(iO)", err, tmp);
7333 Py_DECREF(tmp);
7334 return r;
7335 break;
7336 }
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007337 case DB_REP_NOTPERM :
7338 case DB_REP_ISPERM :
7339 return Py_BuildValue("(i(ll))", err, lsn.file, lsn.offset);
7340 break;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007341 }
7342 RETURN_IF_ERR();
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07007343 return PyTuple_Pack(2, Py_None, Py_None);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007344}
7345
7346static int
7347_DBEnv_rep_transportCallback(DB_ENV* db_env, const DBT* control, const DBT* rec,
7348 const DB_LSN *lsn, int envid, u_int32_t flags)
7349{
7350 DBEnvObject *dbenv;
7351 PyObject* rep_transport;
7352 PyObject* args;
Jesus Cea4907d272008-08-31 14:00:51 +00007353 PyObject *a, *b;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007354 PyObject* result = NULL;
7355 int ret=0;
7356
7357 MYDB_BEGIN_BLOCK_THREADS;
7358 dbenv = (DBEnvObject *)db_env->app_private;
7359 rep_transport = dbenv->rep_transport;
7360
Jesus Cea4907d272008-08-31 14:00:51 +00007361 /*
7362 ** The errors in 'a' or 'b' are detected in "Py_BuildValue".
7363 */
7364 a = PyBytes_FromStringAndSize(control->data, control->size);
7365 b = PyBytes_FromStringAndSize(rec->data, rec->size);
7366
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007367 args = Py_BuildValue(
Jesus Cea4907d272008-08-31 14:00:51 +00007368 "(OOO(ll)iI)",
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007369 dbenv,
Jesus Cea4907d272008-08-31 14:00:51 +00007370 a, b,
7371 lsn->file, lsn->offset, envid, flags);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007372 if (args) {
7373 result = PyEval_CallObject(rep_transport, args);
7374 }
7375
7376 if ((!args) || (!result)) {
7377 PyErr_Print();
7378 ret = -1;
7379 }
Jesus Cea4907d272008-08-31 14:00:51 +00007380 Py_XDECREF(a);
7381 Py_XDECREF(b);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007382 Py_XDECREF(args);
7383 Py_XDECREF(result);
7384 MYDB_END_BLOCK_THREADS;
7385 return ret;
7386}
7387
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007388static PyObject*
7389DBEnv_rep_set_transport(DBEnvObject* self, PyObject* args)
7390{
7391 int err;
7392 int envid;
7393 PyObject *rep_transport;
7394
7395 if (!PyArg_ParseTuple(args, "iO:rep_set_transport", &envid, &rep_transport))
7396 return NULL;
7397 CHECK_ENV_NOT_CLOSED(self);
7398 if (!PyCallable_Check(rep_transport)) {
7399 makeTypeError("Callable", rep_transport);
7400 return NULL;
7401 }
7402
7403 MYDB_BEGIN_ALLOW_THREADS;
7404#if (DBVER >=45)
7405 err = self->db_env->rep_set_transport(self->db_env, envid,
7406 &_DBEnv_rep_transportCallback);
7407#else
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007408 err = self->db_env->set_rep_transport(self->db_env, envid,
7409 &_DBEnv_rep_transportCallback);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007410#endif
7411 MYDB_END_ALLOW_THREADS;
7412 RETURN_IF_ERR();
7413
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007414 Py_INCREF(rep_transport);
Serhiy Storchaka763a61c2016-04-10 18:05:12 +03007415 Py_SETREF(self->rep_transport, rep_transport);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007416 RETURN_NONE();
7417}
7418
7419#if (DBVER >= 47)
7420static PyObject*
7421DBEnv_rep_set_request(DBEnvObject* self, PyObject* args)
7422{
7423 int err;
7424 unsigned int minimum, maximum;
7425
7426 if (!PyArg_ParseTuple(args,"II:rep_set_request", &minimum, &maximum))
7427 return NULL;
7428 CHECK_ENV_NOT_CLOSED(self);
7429
7430 MYDB_BEGIN_ALLOW_THREADS;
7431 err = self->db_env->rep_set_request(self->db_env, minimum, maximum);
7432 MYDB_END_ALLOW_THREADS;
7433 RETURN_IF_ERR();
7434 RETURN_NONE();
7435}
7436
7437static PyObject*
7438DBEnv_rep_get_request(DBEnvObject* self)
7439{
7440 int err;
7441 u_int32_t minimum, maximum;
7442
7443 CHECK_ENV_NOT_CLOSED(self);
7444 MYDB_BEGIN_ALLOW_THREADS;
7445 err = self->db_env->rep_get_request(self->db_env, &minimum, &maximum);
7446 MYDB_END_ALLOW_THREADS;
7447 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007448 return Py_BuildValue("II", minimum, maximum);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007449}
7450#endif
7451
7452#if (DBVER >= 45)
7453static PyObject*
7454DBEnv_rep_set_limit(DBEnvObject* self, PyObject* args)
7455{
7456 int err;
7457 int limit;
7458
7459 if (!PyArg_ParseTuple(args,"i:rep_set_limit", &limit))
7460 return NULL;
7461 CHECK_ENV_NOT_CLOSED(self);
7462
7463 MYDB_BEGIN_ALLOW_THREADS;
7464 err = self->db_env->rep_set_limit(self->db_env, 0, limit);
7465 MYDB_END_ALLOW_THREADS;
7466 RETURN_IF_ERR();
7467 RETURN_NONE();
7468}
7469
7470static PyObject*
7471DBEnv_rep_get_limit(DBEnvObject* self)
7472{
7473 int err;
7474 u_int32_t gbytes, bytes;
7475
7476 CHECK_ENV_NOT_CLOSED(self);
7477 MYDB_BEGIN_ALLOW_THREADS;
7478 err = self->db_env->rep_get_limit(self->db_env, &gbytes, &bytes);
7479 MYDB_END_ALLOW_THREADS;
7480 RETURN_IF_ERR();
7481 return NUMBER_FromLong(bytes);
7482}
7483#endif
7484
7485#if (DBVER >= 44)
7486static PyObject*
7487DBEnv_rep_set_config(DBEnvObject* self, PyObject* args)
7488{
7489 int err;
7490 int which;
7491 int onoff;
7492
7493 if (!PyArg_ParseTuple(args,"ii:rep_set_config", &which, &onoff))
7494 return NULL;
7495 CHECK_ENV_NOT_CLOSED(self);
7496
7497 MYDB_BEGIN_ALLOW_THREADS;
7498 err = self->db_env->rep_set_config(self->db_env, which, onoff);
7499 MYDB_END_ALLOW_THREADS;
7500 RETURN_IF_ERR();
7501 RETURN_NONE();
7502}
7503
7504static PyObject*
7505DBEnv_rep_get_config(DBEnvObject* self, PyObject* args)
7506{
7507 int err;
7508 int which;
7509 int onoff;
7510
7511 if (!PyArg_ParseTuple(args, "i:rep_get_config", &which)) {
7512 return NULL;
7513 }
7514 CHECK_ENV_NOT_CLOSED(self);
7515 MYDB_BEGIN_ALLOW_THREADS;
7516 err = self->db_env->rep_get_config(self->db_env, which, &onoff);
7517 MYDB_END_ALLOW_THREADS;
7518 RETURN_IF_ERR();
7519 return PyBool_FromLong(onoff);
7520}
7521#endif
7522
7523#if (DBVER >= 46)
7524static PyObject*
7525DBEnv_rep_elect(DBEnvObject* self, PyObject* args)
7526{
7527 int err;
7528 u_int32_t nsites, nvotes;
7529
7530 if (!PyArg_ParseTuple(args, "II:rep_elect", &nsites, &nvotes)) {
7531 return NULL;
7532 }
7533 CHECK_ENV_NOT_CLOSED(self);
7534 MYDB_BEGIN_ALLOW_THREADS;
Jesus Cea2ab4a912012-01-16 23:57:34 +01007535 err = self->db_env->rep_elect(self->db_env, nsites, nvotes, 0);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007536 MYDB_END_ALLOW_THREADS;
7537 RETURN_IF_ERR();
7538 RETURN_NONE();
7539}
7540#endif
7541
7542static PyObject*
7543DBEnv_rep_start(DBEnvObject* self, PyObject* args, PyObject* kwargs)
7544{
7545 int err;
7546 PyObject *cdata_py = Py_None;
7547 DBT cdata;
7548 int flags;
7549 static char* kwnames[] = {"flags","cdata", NULL};
7550
7551 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
7552 "i|O:rep_start", kwnames, &flags, &cdata_py))
7553 {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00007554 return NULL;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007555 }
7556 CHECK_ENV_NOT_CLOSED(self);
7557
7558 if (!make_dbt(cdata_py, &cdata))
7559 return NULL;
7560
7561 MYDB_BEGIN_ALLOW_THREADS;
7562 err = self->db_env->rep_start(self->db_env, cdata.size ? &cdata : NULL,
7563 flags);
7564 MYDB_END_ALLOW_THREADS;
7565 RETURN_IF_ERR();
7566 RETURN_NONE();
7567}
7568
7569#if (DBVER >= 44)
7570static PyObject*
7571DBEnv_rep_sync(DBEnvObject* self)
7572{
7573 int err;
7574
7575 CHECK_ENV_NOT_CLOSED(self);
7576 MYDB_BEGIN_ALLOW_THREADS;
7577 err = self->db_env->rep_sync(self->db_env, 0);
7578 MYDB_END_ALLOW_THREADS;
7579 RETURN_IF_ERR();
7580 RETURN_NONE();
7581}
7582#endif
7583
7584
Jesus Ceaef9764f2008-05-13 18:45:46 +00007585#if (DBVER >= 45)
7586static PyObject*
7587DBEnv_rep_set_nsites(DBEnvObject* self, PyObject* args)
7588{
7589 int err;
7590 int nsites;
7591
7592 if (!PyArg_ParseTuple(args, "i:rep_set_nsites", &nsites)) {
7593 return NULL;
7594 }
7595 CHECK_ENV_NOT_CLOSED(self);
7596 MYDB_BEGIN_ALLOW_THREADS;
7597 err = self->db_env->rep_set_nsites(self->db_env, nsites);
7598 MYDB_END_ALLOW_THREADS;
7599 RETURN_IF_ERR();
7600 RETURN_NONE();
7601}
7602
7603static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007604DBEnv_rep_get_nsites(DBEnvObject* self)
Jesus Ceaef9764f2008-05-13 18:45:46 +00007605{
7606 int err;
Jesus Ceaca3939c2008-05-22 15:27:38 +00007607#if (DBVER >= 47)
7608 u_int32_t nsites;
7609#else
Jesus Ceaef9764f2008-05-13 18:45:46 +00007610 int nsites;
Jesus Ceaca3939c2008-05-22 15:27:38 +00007611#endif
Jesus Ceaef9764f2008-05-13 18:45:46 +00007612
Jesus Ceaef9764f2008-05-13 18:45:46 +00007613 CHECK_ENV_NOT_CLOSED(self);
7614 MYDB_BEGIN_ALLOW_THREADS;
7615 err = self->db_env->rep_get_nsites(self->db_env, &nsites);
7616 MYDB_END_ALLOW_THREADS;
7617 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007618 return NUMBER_FromLong(nsites);
Jesus Ceaef9764f2008-05-13 18:45:46 +00007619}
7620
7621static PyObject*
7622DBEnv_rep_set_priority(DBEnvObject* self, PyObject* args)
7623{
7624 int err;
7625 int priority;
7626
7627 if (!PyArg_ParseTuple(args, "i:rep_set_priority", &priority)) {
7628 return NULL;
7629 }
7630 CHECK_ENV_NOT_CLOSED(self);
7631 MYDB_BEGIN_ALLOW_THREADS;
7632 err = self->db_env->rep_set_priority(self->db_env, priority);
7633 MYDB_END_ALLOW_THREADS;
7634 RETURN_IF_ERR();
7635 RETURN_NONE();
7636}
7637
7638static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007639DBEnv_rep_get_priority(DBEnvObject* self)
Jesus Ceaef9764f2008-05-13 18:45:46 +00007640{
7641 int err;
Jesus Ceaca3939c2008-05-22 15:27:38 +00007642#if (DBVER >= 47)
7643 u_int32_t priority;
7644#else
Jesus Ceaef9764f2008-05-13 18:45:46 +00007645 int priority;
Jesus Ceaca3939c2008-05-22 15:27:38 +00007646#endif
Jesus Ceaef9764f2008-05-13 18:45:46 +00007647
Jesus Ceaef9764f2008-05-13 18:45:46 +00007648 CHECK_ENV_NOT_CLOSED(self);
7649 MYDB_BEGIN_ALLOW_THREADS;
7650 err = self->db_env->rep_get_priority(self->db_env, &priority);
7651 MYDB_END_ALLOW_THREADS;
7652 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007653 return NUMBER_FromLong(priority);
Jesus Ceaef9764f2008-05-13 18:45:46 +00007654}
7655
7656static PyObject*
7657DBEnv_rep_set_timeout(DBEnvObject* self, PyObject* args)
7658{
7659 int err;
7660 int which, timeout;
7661
7662 if (!PyArg_ParseTuple(args, "ii:rep_set_timeout", &which, &timeout)) {
7663 return NULL;
7664 }
7665 CHECK_ENV_NOT_CLOSED(self);
7666 MYDB_BEGIN_ALLOW_THREADS;
7667 err = self->db_env->rep_set_timeout(self->db_env, which, timeout);
7668 MYDB_END_ALLOW_THREADS;
7669 RETURN_IF_ERR();
7670 RETURN_NONE();
7671}
7672
7673static PyObject*
7674DBEnv_rep_get_timeout(DBEnvObject* self, PyObject* args)
7675{
7676 int err;
7677 int which;
7678 u_int32_t timeout;
7679
7680 if (!PyArg_ParseTuple(args, "i:rep_get_timeout", &which)) {
7681 return NULL;
7682 }
7683 CHECK_ENV_NOT_CLOSED(self);
7684 MYDB_BEGIN_ALLOW_THREADS;
7685 err = self->db_env->rep_get_timeout(self->db_env, which, &timeout);
7686 MYDB_END_ALLOW_THREADS;
7687 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007688 return NUMBER_FromLong(timeout);
Jesus Ceaef9764f2008-05-13 18:45:46 +00007689}
7690#endif
7691
Jesus Cea6557aac2010-03-22 14:22:26 +00007692
7693#if (DBVER >= 47)
7694static PyObject*
7695DBEnv_rep_set_clockskew(DBEnvObject* self, PyObject* args)
7696{
7697 int err;
7698 unsigned int fast, slow;
7699
Jesus Cea6557aac2010-03-22 14:22:26 +00007700 if (!PyArg_ParseTuple(args,"II:rep_set_clockskew", &fast, &slow))
7701 return NULL;
Jesus Cea6557aac2010-03-22 14:22:26 +00007702
7703 CHECK_ENV_NOT_CLOSED(self);
7704
7705 MYDB_BEGIN_ALLOW_THREADS;
7706 err = self->db_env->rep_set_clockskew(self->db_env, fast, slow);
7707 MYDB_END_ALLOW_THREADS;
7708 RETURN_IF_ERR();
7709 RETURN_NONE();
7710}
7711
7712static PyObject*
7713DBEnv_rep_get_clockskew(DBEnvObject* self)
7714{
7715 int err;
7716 unsigned int fast, slow;
7717
7718 CHECK_ENV_NOT_CLOSED(self);
7719 MYDB_BEGIN_ALLOW_THREADS;
7720 err = self->db_env->rep_get_clockskew(self->db_env, &fast, &slow);
7721 MYDB_END_ALLOW_THREADS;
7722 RETURN_IF_ERR();
Jesus Cea6557aac2010-03-22 14:22:26 +00007723 return Py_BuildValue("(II)", fast, slow);
Jesus Cea6557aac2010-03-22 14:22:26 +00007724}
7725#endif
7726
Jesus Cea6557aac2010-03-22 14:22:26 +00007727static PyObject*
7728DBEnv_rep_stat_print(DBEnvObject* self, PyObject* args, PyObject *kwargs)
7729{
7730 int err;
7731 int flags=0;
7732 static char* kwnames[] = { "flags", NULL };
7733
7734 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:rep_stat_print",
7735 kwnames, &flags))
7736 {
7737 return NULL;
7738 }
7739 CHECK_ENV_NOT_CLOSED(self);
7740 MYDB_BEGIN_ALLOW_THREADS;
7741 err = self->db_env->rep_stat_print(self->db_env, flags);
7742 MYDB_END_ALLOW_THREADS;
7743 RETURN_IF_ERR();
7744 RETURN_NONE();
7745}
Jesus Cea6557aac2010-03-22 14:22:26 +00007746
7747static PyObject*
7748DBEnv_rep_stat(DBEnvObject* self, PyObject* args, PyObject *kwargs)
7749{
7750 int err;
7751 int flags=0;
7752 DB_REP_STAT *statp;
7753 PyObject *stats;
7754 static char* kwnames[] = { "flags", NULL };
7755
7756 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:rep_stat",
7757 kwnames, &flags))
7758 {
7759 return NULL;
7760 }
7761 CHECK_ENV_NOT_CLOSED(self);
7762 MYDB_BEGIN_ALLOW_THREADS;
7763 err = self->db_env->rep_stat(self->db_env, &statp, flags);
7764 MYDB_END_ALLOW_THREADS;
7765 RETURN_IF_ERR();
7766
7767 stats=PyDict_New();
7768 if (stats == NULL) {
7769 free(statp);
7770 return NULL;
7771 }
7772
7773#define MAKE_ENTRY(name) _addIntToDict(stats, #name, statp->st_##name)
7774#define MAKE_DB_LSN_ENTRY(name) _addDB_lsnToDict(stats , #name, statp->st_##name)
7775
7776#if (DBVER >= 44)
7777 MAKE_ENTRY(bulk_fills);
7778 MAKE_ENTRY(bulk_overflows);
7779 MAKE_ENTRY(bulk_records);
7780 MAKE_ENTRY(bulk_transfers);
7781 MAKE_ENTRY(client_rerequests);
7782 MAKE_ENTRY(client_svc_miss);
7783 MAKE_ENTRY(client_svc_req);
7784#endif
7785 MAKE_ENTRY(dupmasters);
Jesus Cea6557aac2010-03-22 14:22:26 +00007786 MAKE_ENTRY(egen);
7787 MAKE_ENTRY(election_nvotes);
7788 MAKE_ENTRY(startup_complete);
7789 MAKE_ENTRY(pg_duplicated);
7790 MAKE_ENTRY(pg_records);
7791 MAKE_ENTRY(pg_requested);
7792 MAKE_ENTRY(next_pg);
7793 MAKE_ENTRY(waiting_pg);
Jesus Cea6557aac2010-03-22 14:22:26 +00007794 MAKE_ENTRY(election_cur_winner);
7795 MAKE_ENTRY(election_gen);
7796 MAKE_DB_LSN_ENTRY(election_lsn);
7797 MAKE_ENTRY(election_nsites);
7798 MAKE_ENTRY(election_priority);
7799#if (DBVER >= 44)
7800 MAKE_ENTRY(election_sec);
7801 MAKE_ENTRY(election_usec);
7802#endif
7803 MAKE_ENTRY(election_status);
7804 MAKE_ENTRY(election_tiebreaker);
7805 MAKE_ENTRY(election_votes);
7806 MAKE_ENTRY(elections);
7807 MAKE_ENTRY(elections_won);
7808 MAKE_ENTRY(env_id);
7809 MAKE_ENTRY(env_priority);
7810 MAKE_ENTRY(gen);
7811 MAKE_ENTRY(log_duplicated);
7812 MAKE_ENTRY(log_queued);
7813 MAKE_ENTRY(log_queued_max);
7814 MAKE_ENTRY(log_queued_total);
7815 MAKE_ENTRY(log_records);
7816 MAKE_ENTRY(log_requested);
7817 MAKE_ENTRY(master);
7818 MAKE_ENTRY(master_changes);
7819#if (DBVER >= 47)
7820 MAKE_ENTRY(max_lease_sec);
7821 MAKE_ENTRY(max_lease_usec);
7822 MAKE_DB_LSN_ENTRY(max_perm_lsn);
7823#endif
7824 MAKE_ENTRY(msgs_badgen);
7825 MAKE_ENTRY(msgs_processed);
7826 MAKE_ENTRY(msgs_recover);
7827 MAKE_ENTRY(msgs_send_failures);
7828 MAKE_ENTRY(msgs_sent);
7829 MAKE_ENTRY(newsites);
7830 MAKE_DB_LSN_ENTRY(next_lsn);
7831 MAKE_ENTRY(nsites);
7832 MAKE_ENTRY(nthrottles);
7833 MAKE_ENTRY(outdated);
7834#if (DBVER >= 46)
7835 MAKE_ENTRY(startsync_delayed);
7836#endif
7837 MAKE_ENTRY(status);
7838 MAKE_ENTRY(txns_applied);
7839 MAKE_DB_LSN_ENTRY(waiting_lsn);
7840
7841#undef MAKE_DB_LSN_ENTRY
7842#undef MAKE_ENTRY
7843
7844 free(statp);
7845 return stats;
7846}
7847
Jesus Ceaef9764f2008-05-13 18:45:46 +00007848/* --------------------------------------------------------------------- */
7849/* REPLICATION METHODS: Replication Manager */
7850
7851#if (DBVER >= 45)
7852static PyObject*
7853DBEnv_repmgr_start(DBEnvObject* self, PyObject* args, PyObject*
7854 kwargs)
7855{
7856 int err;
7857 int nthreads, flags;
7858 static char* kwnames[] = {"nthreads","flags", NULL};
7859
7860 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
7861 "ii:repmgr_start", kwnames, &nthreads, &flags))
7862 {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00007863 return NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00007864 }
7865 CHECK_ENV_NOT_CLOSED(self);
7866 MYDB_BEGIN_ALLOW_THREADS;
7867 err = self->db_env->repmgr_start(self->db_env, nthreads, flags);
7868 MYDB_END_ALLOW_THREADS;
7869 RETURN_IF_ERR();
7870 RETURN_NONE();
7871}
7872
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07007873#if (DBVER < 52)
Jesus Ceaef9764f2008-05-13 18:45:46 +00007874static PyObject*
7875DBEnv_repmgr_set_local_site(DBEnvObject* self, PyObject* args, PyObject*
7876 kwargs)
7877{
7878 int err;
7879 char *host;
7880 int port;
7881 int flags = 0;
7882 static char* kwnames[] = {"host", "port", "flags", NULL};
7883
7884 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
7885 "si|i:repmgr_set_local_site", kwnames, &host, &port, &flags))
7886 {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00007887 return NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00007888 }
7889 CHECK_ENV_NOT_CLOSED(self);
7890 MYDB_BEGIN_ALLOW_THREADS;
7891 err = self->db_env->repmgr_set_local_site(self->db_env, host, port, flags);
7892 MYDB_END_ALLOW_THREADS;
7893 RETURN_IF_ERR();
7894 RETURN_NONE();
7895}
7896
7897static PyObject*
7898DBEnv_repmgr_add_remote_site(DBEnvObject* self, PyObject* args, PyObject*
7899 kwargs)
7900{
7901 int err;
7902 char *host;
7903 int port;
7904 int flags = 0;
7905 int eidp;
7906 static char* kwnames[] = {"host", "port", "flags", NULL};
7907
7908 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
7909 "si|i:repmgr_add_remote_site", kwnames, &host, &port, &flags))
7910 {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00007911 return NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00007912 }
7913 CHECK_ENV_NOT_CLOSED(self);
7914 MYDB_BEGIN_ALLOW_THREADS;
7915 err = self->db_env->repmgr_add_remote_site(self->db_env, host, port, &eidp, flags);
7916 MYDB_END_ALLOW_THREADS;
7917 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007918 return NUMBER_FromLong(eidp);
Jesus Ceaef9764f2008-05-13 18:45:46 +00007919}
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07007920#endif
Jesus Ceaef9764f2008-05-13 18:45:46 +00007921
7922static PyObject*
7923DBEnv_repmgr_set_ack_policy(DBEnvObject* self, PyObject* args)
7924{
7925 int err;
7926 int ack_policy;
7927
7928 if (!PyArg_ParseTuple(args, "i:repmgr_set_ack_policy", &ack_policy))
7929 {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00007930 return NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00007931 }
7932 CHECK_ENV_NOT_CLOSED(self);
7933 MYDB_BEGIN_ALLOW_THREADS;
7934 err = self->db_env->repmgr_set_ack_policy(self->db_env, ack_policy);
7935 MYDB_END_ALLOW_THREADS;
7936 RETURN_IF_ERR();
7937 RETURN_NONE();
7938}
7939
7940static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007941DBEnv_repmgr_get_ack_policy(DBEnvObject* self)
Jesus Ceaef9764f2008-05-13 18:45:46 +00007942{
7943 int err;
7944 int ack_policy;
7945
Jesus Ceaef9764f2008-05-13 18:45:46 +00007946 CHECK_ENV_NOT_CLOSED(self);
7947 MYDB_BEGIN_ALLOW_THREADS;
7948 err = self->db_env->repmgr_get_ack_policy(self->db_env, &ack_policy);
7949 MYDB_END_ALLOW_THREADS;
7950 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007951 return NUMBER_FromLong(ack_policy);
Jesus Ceaef9764f2008-05-13 18:45:46 +00007952}
7953
7954static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007955DBEnv_repmgr_site_list(DBEnvObject* self)
Jesus Ceaef9764f2008-05-13 18:45:46 +00007956{
7957 int err;
7958 unsigned int countp;
7959 DB_REPMGR_SITE *listp;
7960 PyObject *stats, *key, *tuple;
7961
Jesus Ceaef9764f2008-05-13 18:45:46 +00007962 CHECK_ENV_NOT_CLOSED(self);
7963 MYDB_BEGIN_ALLOW_THREADS;
7964 err = self->db_env->repmgr_site_list(self->db_env, &countp, &listp);
7965 MYDB_END_ALLOW_THREADS;
7966 RETURN_IF_ERR();
7967
7968 stats=PyDict_New();
7969 if (stats == NULL) {
7970 free(listp);
7971 return NULL;
7972 }
7973
7974 for(;countp--;) {
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007975 key=NUMBER_FromLong(listp[countp].eid);
Jesus Ceaef9764f2008-05-13 18:45:46 +00007976 if(!key) {
7977 Py_DECREF(stats);
7978 free(listp);
7979 return NULL;
7980 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00007981 tuple=Py_BuildValue("(sII)", listp[countp].host,
7982 listp[countp].port, listp[countp].status);
Jesus Ceaef9764f2008-05-13 18:45:46 +00007983 if(!tuple) {
7984 Py_DECREF(key);
7985 Py_DECREF(stats);
7986 free(listp);
7987 return NULL;
7988 }
7989 if(PyDict_SetItem(stats, key, tuple)) {
7990 Py_DECREF(key);
7991 Py_DECREF(tuple);
7992 Py_DECREF(stats);
7993 free(listp);
7994 return NULL;
7995 }
Florent Xiclunae7901c52010-03-01 20:45:01 +00007996 Py_DECREF(key);
7997 Py_DECREF(tuple);
Jesus Ceaef9764f2008-05-13 18:45:46 +00007998 }
7999 free(listp);
8000 return stats;
8001}
8002#endif
8003
8004#if (DBVER >= 46)
8005static PyObject*
8006DBEnv_repmgr_stat_print(DBEnvObject* self, PyObject* args, PyObject *kwargs)
8007{
8008 int err;
8009 int flags=0;
8010 static char* kwnames[] = { "flags", NULL };
8011
8012 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:repmgr_stat_print",
8013 kwnames, &flags))
8014 {
8015 return NULL;
8016 }
8017 CHECK_ENV_NOT_CLOSED(self);
8018 MYDB_BEGIN_ALLOW_THREADS;
8019 err = self->db_env->repmgr_stat_print(self->db_env, flags);
8020 MYDB_END_ALLOW_THREADS;
8021 RETURN_IF_ERR();
8022 RETURN_NONE();
8023}
8024
8025static PyObject*
8026DBEnv_repmgr_stat(DBEnvObject* self, PyObject* args, PyObject *kwargs)
8027{
8028 int err;
8029 int flags=0;
8030 DB_REPMGR_STAT *statp;
8031 PyObject *stats;
8032 static char* kwnames[] = { "flags", NULL };
8033
8034 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:repmgr_stat",
8035 kwnames, &flags))
8036 {
8037 return NULL;
8038 }
8039 CHECK_ENV_NOT_CLOSED(self);
8040 MYDB_BEGIN_ALLOW_THREADS;
8041 err = self->db_env->repmgr_stat(self->db_env, &statp, flags);
8042 MYDB_END_ALLOW_THREADS;
8043 RETURN_IF_ERR();
8044
8045 stats=PyDict_New();
8046 if (stats == NULL) {
8047 free(statp);
8048 return NULL;
8049 }
8050
8051#define MAKE_ENTRY(name) _addIntToDict(stats, #name, statp->st_##name)
8052
8053 MAKE_ENTRY(perm_failed);
8054 MAKE_ENTRY(msgs_queued);
8055 MAKE_ENTRY(msgs_dropped);
8056 MAKE_ENTRY(connection_drop);
8057 MAKE_ENTRY(connect_fail);
8058
8059#undef MAKE_ENTRY
8060
8061 free(statp);
8062 return stats;
8063}
8064#endif
8065
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008066
8067/* --------------------------------------------------------------------- */
8068/* DBTxn methods */
8069
8070
Jesus Ceaef9764f2008-05-13 18:45:46 +00008071static void _close_transaction_cursors(DBTxnObject* txn)
8072{
8073 PyObject *dummy;
8074
8075 while(txn->children_cursors) {
8076 PyErr_Warn(PyExc_RuntimeWarning,
8077 "Must close cursors before resolving a transaction.");
8078 dummy=DBC_close_internal(txn->children_cursors);
8079 Py_XDECREF(dummy);
8080 }
8081}
8082
8083static void _promote_transaction_dbs_and_sequences(DBTxnObject *txn)
8084{
8085 DBObject *db;
Jesus Ceaef9764f2008-05-13 18:45:46 +00008086 DBSequenceObject *dbs;
Jesus Ceaef9764f2008-05-13 18:45:46 +00008087
8088 while (txn->children_dbs) {
8089 db=txn->children_dbs;
8090 EXTRACT_FROM_DOUBLE_LINKED_LIST_TXN(db);
8091 if (txn->parent_txn) {
8092 INSERT_IN_DOUBLE_LINKED_LIST_TXN(txn->parent_txn->children_dbs,db);
8093 db->txn=txn->parent_txn;
8094 } else {
8095 /* The db is already linked to its environment,
8096 ** so nothing to do.
8097 */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00008098 db->txn=NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00008099 }
8100 }
8101
Jesus Ceaef9764f2008-05-13 18:45:46 +00008102 while (txn->children_sequences) {
8103 dbs=txn->children_sequences;
8104 EXTRACT_FROM_DOUBLE_LINKED_LIST_TXN(dbs);
8105 if (txn->parent_txn) {
8106 INSERT_IN_DOUBLE_LINKED_LIST_TXN(txn->parent_txn->children_sequences,dbs);
8107 dbs->txn=txn->parent_txn;
8108 } else {
8109 /* The sequence is already linked to its
8110 ** parent db. Nothing to do.
8111 */
8112 dbs->txn=NULL;
8113 }
8114 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00008115}
8116
8117
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008118static PyObject*
8119DBTxn_commit(DBTxnObject* self, PyObject* args)
8120{
8121 int flags=0, err;
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008122 DB_TXN *txn;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008123
8124 if (!PyArg_ParseTuple(args, "|i:commit", &flags))
8125 return NULL;
8126
Jesus Ceaef9764f2008-05-13 18:45:46 +00008127 _close_transaction_cursors(self);
8128
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008129 if (!self->txn) {
Thomas Woutersb3153832006-03-08 01:47:19 +00008130 PyObject *t = Py_BuildValue("(is)", 0, "DBTxn must not be used "
Jesus Ceaef9764f2008-05-13 18:45:46 +00008131 "after txn_commit, txn_abort "
8132 "or txn_discard");
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008133 if (t) {
8134 PyErr_SetObject(DBError, t);
8135 Py_DECREF(t);
8136 }
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008137 return NULL;
8138 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00008139 self->flag_prepare=0;
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008140 txn = self->txn;
8141 self->txn = NULL; /* this DB_TXN is no longer valid after this call */
Jesus Ceaef9764f2008-05-13 18:45:46 +00008142
8143 EXTRACT_FROM_DOUBLE_LINKED_LIST(self);
8144
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008145 MYDB_BEGIN_ALLOW_THREADS;
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008146 err = txn->commit(txn, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008147 MYDB_END_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00008148
8149 _promote_transaction_dbs_and_sequences(self);
8150
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008151 RETURN_IF_ERR();
8152 RETURN_NONE();
8153}
8154
8155static PyObject*
8156DBTxn_prepare(DBTxnObject* self, PyObject* args)
8157{
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008158 int err;
8159 char* gid=NULL;
8160 int gid_size=0;
8161
8162 if (!PyArg_ParseTuple(args, "s#:prepare", &gid, &gid_size))
8163 return NULL;
8164
Matthias Klose54cc5392010-03-15 12:46:18 +00008165 if (gid_size != DB_GID_SIZE) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008166 PyErr_SetString(PyExc_TypeError,
Matthias Klose54cc5392010-03-15 12:46:18 +00008167 "gid must be DB_GID_SIZE bytes long");
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008168 return NULL;
8169 }
8170
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008171 if (!self->txn) {
Thomas Woutersb3153832006-03-08 01:47:19 +00008172 PyObject *t = Py_BuildValue("(is)", 0,"DBTxn must not be used "
Jesus Ceaef9764f2008-05-13 18:45:46 +00008173 "after txn_commit, txn_abort "
8174 "or txn_discard");
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008175 if (t) {
8176 PyErr_SetObject(DBError, t);
8177 Py_DECREF(t);
8178 }
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008179 return NULL;
8180 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00008181 self->flag_prepare=1; /* Prepare state */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008182 MYDB_BEGIN_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008183 err = self->txn->prepare(self->txn, (u_int8_t*)gid);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008184 MYDB_END_ALLOW_THREADS;
8185 RETURN_IF_ERR();
8186 RETURN_NONE();
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008187}
8188
8189
8190static PyObject*
Jesus Ceaef9764f2008-05-13 18:45:46 +00008191DBTxn_abort_discard_internal(DBTxnObject* self, int discard)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008192{
Jesus Ceaef9764f2008-05-13 18:45:46 +00008193 PyObject *dummy;
8194 int err=0;
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008195 DB_TXN *txn;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008196
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008197 if (!self->txn) {
Thomas Woutersb3153832006-03-08 01:47:19 +00008198 PyObject *t = Py_BuildValue("(is)", 0, "DBTxn must not be used "
Jesus Ceaef9764f2008-05-13 18:45:46 +00008199 "after txn_commit, txn_abort "
8200 "or txn_discard");
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008201 if (t) {
8202 PyErr_SetObject(DBError, t);
8203 Py_DECREF(t);
8204 }
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008205 return NULL;
8206 }
8207 txn = self->txn;
8208 self->txn = NULL; /* this DB_TXN is no longer valid after this call */
Jesus Ceaef9764f2008-05-13 18:45:46 +00008209
8210 _close_transaction_cursors(self);
Jesus Ceaef9764f2008-05-13 18:45:46 +00008211 while (self->children_sequences) {
8212 dummy=DBSequence_close_internal(self->children_sequences,0,0);
8213 Py_XDECREF(dummy);
8214 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00008215 while (self->children_dbs) {
Jesus Cea5cd5f122008-09-23 18:54:08 +00008216 dummy=DB_close_internal(self->children_dbs, 0, 0);
Jesus Ceaef9764f2008-05-13 18:45:46 +00008217 Py_XDECREF(dummy);
8218 }
8219
8220 EXTRACT_FROM_DOUBLE_LINKED_LIST(self);
8221
8222 MYDB_BEGIN_ALLOW_THREADS;
8223 if (discard) {
8224 assert(!self->flag_prepare);
Jesus Ceaef9764f2008-05-13 18:45:46 +00008225 err = txn->discard(txn,0);
Jesus Ceaef9764f2008-05-13 18:45:46 +00008226 } else {
8227 /*
8228 ** If the transaction is in the "prepare" or "recover" state,
8229 ** we better do not implicitly abort it.
8230 */
8231 if (!self->flag_prepare) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00008232 err = txn->abort(txn);
Jesus Ceaef9764f2008-05-13 18:45:46 +00008233 }
8234 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008235 MYDB_END_ALLOW_THREADS;
8236 RETURN_IF_ERR();
8237 RETURN_NONE();
8238}
8239
Jesus Ceaef9764f2008-05-13 18:45:46 +00008240static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008241DBTxn_abort(DBTxnObject* self)
Jesus Ceaef9764f2008-05-13 18:45:46 +00008242{
Jesus Ceaef9764f2008-05-13 18:45:46 +00008243 self->flag_prepare=0;
8244 _close_transaction_cursors(self);
8245
8246 return DBTxn_abort_discard_internal(self,0);
8247}
8248
8249static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008250DBTxn_discard(DBTxnObject* self)
Jesus Ceaef9764f2008-05-13 18:45:46 +00008251{
Jesus Ceaef9764f2008-05-13 18:45:46 +00008252 self->flag_prepare=0;
8253 _close_transaction_cursors(self);
8254
8255 return DBTxn_abort_discard_internal(self,1);
8256}
8257
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008258
8259static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008260DBTxn_id(DBTxnObject* self)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008261{
8262 int id;
8263
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008264 if (!self->txn) {
Thomas Woutersb3153832006-03-08 01:47:19 +00008265 PyObject *t = Py_BuildValue("(is)", 0, "DBTxn must not be used "
Jesus Ceaef9764f2008-05-13 18:45:46 +00008266 "after txn_commit, txn_abort "
8267 "or txn_discard");
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008268 if (t) {
8269 PyErr_SetObject(DBError, t);
8270 Py_DECREF(t);
8271 }
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008272 return NULL;
8273 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008274 MYDB_BEGIN_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008275 id = self->txn->id(self->txn);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008276 MYDB_END_ALLOW_THREADS;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008277 return NUMBER_FromLong(id);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008278}
8279
Jesus Cea6557aac2010-03-22 14:22:26 +00008280
8281static PyObject*
8282DBTxn_set_timeout(DBTxnObject* self, PyObject* args, PyObject* kwargs)
8283{
8284 int err;
8285 u_int32_t flags=0;
8286 u_int32_t timeout = 0;
8287 static char* kwnames[] = { "timeout", "flags", NULL };
8288
8289 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ii:set_timeout", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00008290 &timeout, &flags)) {
8291 return NULL;
Jesus Cea6557aac2010-03-22 14:22:26 +00008292 }
8293
8294 MYDB_BEGIN_ALLOW_THREADS;
8295 err = self->txn->set_timeout(self->txn, (db_timeout_t)timeout, flags);
8296 MYDB_END_ALLOW_THREADS;
8297
8298 RETURN_IF_ERR();
8299 RETURN_NONE();
8300}
8301
8302
8303#if (DBVER >= 44)
8304static PyObject*
8305DBTxn_set_name(DBTxnObject* self, PyObject* args)
8306{
8307 int err;
8308 const char *name;
8309
8310 if (!PyArg_ParseTuple(args, "s:set_name", &name))
8311 return NULL;
8312
8313 MYDB_BEGIN_ALLOW_THREADS;
8314 err = self->txn->set_name(self->txn, name);
8315 MYDB_END_ALLOW_THREADS;
8316
8317 RETURN_IF_ERR();
8318 RETURN_NONE();
8319}
8320#endif
8321
8322
8323#if (DBVER >= 44)
8324static PyObject*
8325DBTxn_get_name(DBTxnObject* self)
8326{
8327 int err;
8328 const char *name;
8329
8330 MYDB_BEGIN_ALLOW_THREADS;
8331 err = self->txn->get_name(self->txn, &name);
8332 MYDB_END_ALLOW_THREADS;
8333
8334 RETURN_IF_ERR();
8335#if (PY_VERSION_HEX < 0x03000000)
8336 if (!name) {
8337 return PyString_FromString("");
8338 }
8339 return PyString_FromString(name);
8340#else
8341 if (!name) {
8342 return PyUnicode_FromString("");
8343 }
8344 return PyUnicode_FromString(name);
8345#endif
8346}
8347#endif
8348
8349
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008350/* --------------------------------------------------------------------- */
8351/* DBSequence methods */
8352
8353
8354static PyObject*
Jesus Ceaef9764f2008-05-13 18:45:46 +00008355DBSequence_close_internal(DBSequenceObject* self, int flags, int do_not_close)
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008356{
Jesus Ceaef9764f2008-05-13 18:45:46 +00008357 int err=0;
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008358
Jesus Ceaef9764f2008-05-13 18:45:46 +00008359 if (self->sequence!=NULL) {
8360 EXTRACT_FROM_DOUBLE_LINKED_LIST(self);
8361 if (self->txn) {
8362 EXTRACT_FROM_DOUBLE_LINKED_LIST_TXN(self);
8363 self->txn=NULL;
8364 }
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008365
Jesus Cea5cd5f122008-09-23 18:54:08 +00008366 /*
8367 ** "do_not_close" is used to dispose all related objects in the
8368 ** tree, without actually releasing the "root" object.
8369 ** This is done, for example, because function calls like
8370 ** "DBSequence.remove()" implicitly close the underlying handle. So
8371 ** the handle doesn't need to be closed, but related objects
8372 ** must be cleaned up.
8373 */
Jesus Ceaef9764f2008-05-13 18:45:46 +00008374 if (!do_not_close) {
8375 MYDB_BEGIN_ALLOW_THREADS
8376 err = self->sequence->close(self->sequence, flags);
8377 MYDB_END_ALLOW_THREADS
8378 }
8379 self->sequence = NULL;
8380
8381 RETURN_IF_ERR();
8382 }
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008383
8384 RETURN_NONE();
8385}
8386
8387static PyObject*
Jesus Ceaef9764f2008-05-13 18:45:46 +00008388DBSequence_close(DBSequenceObject* self, PyObject* args)
8389{
8390 int flags=0;
8391 if (!PyArg_ParseTuple(args,"|i:close", &flags))
8392 return NULL;
8393
8394 return DBSequence_close_internal(self,flags,0);
8395}
8396
8397static PyObject*
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008398DBSequence_get(DBSequenceObject* self, PyObject* args, PyObject* kwargs)
8399{
8400 int err, flags = 0;
8401 int delta = 1;
8402 db_seq_t value;
8403 PyObject *txnobj = NULL;
8404 DB_TXN *txn = NULL;
8405 static char* kwnames[] = {"delta", "txn", "flags", NULL };
8406 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|iOi:get", kwnames, &delta, &txnobj, &flags))
8407 return NULL;
8408 CHECK_SEQUENCE_NOT_CLOSED(self)
8409
8410 if (!checkTxnObj(txnobj, &txn))
8411 return NULL;
8412
8413 MYDB_BEGIN_ALLOW_THREADS
8414 err = self->sequence->get(self->sequence, txn, delta, &value, flags);
8415 MYDB_END_ALLOW_THREADS
8416
8417 RETURN_IF_ERR();
8418 return PyLong_FromLongLong(value);
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008419}
8420
8421static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008422DBSequence_get_dbp(DBSequenceObject* self)
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008423{
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008424 CHECK_SEQUENCE_NOT_CLOSED(self)
8425 Py_INCREF(self->mydb);
8426 return (PyObject* )self->mydb;
8427}
8428
8429static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008430DBSequence_get_key(DBSequenceObject* self)
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008431{
8432 int err;
8433 DBT key;
Neal Norwitz088beae2007-10-12 03:01:54 +00008434 PyObject *retval = NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00008435
Gregory P. Smithe70be5c2007-10-06 07:48:10 +00008436 key.flags = DB_DBT_MALLOC;
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008437 CHECK_SEQUENCE_NOT_CLOSED(self)
8438 MYDB_BEGIN_ALLOW_THREADS
8439 err = self->sequence->get_key(self->sequence, &key);
8440 MYDB_END_ALLOW_THREADS
8441
Gregory P. Smithe70be5c2007-10-06 07:48:10 +00008442 if (!err)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008443 retval = Build_PyString(key.data, key.size);
Gregory P. Smithe70be5c2007-10-06 07:48:10 +00008444
8445 FREE_DBT(key);
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008446 RETURN_IF_ERR();
8447
Gregory P. Smithe70be5c2007-10-06 07:48:10 +00008448 return retval;
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008449}
8450
8451static PyObject*
Jesus Cea6557aac2010-03-22 14:22:26 +00008452DBSequence_initial_value(DBSequenceObject* self, PyObject* args)
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008453{
8454 int err;
Jesus Ceaef9764f2008-05-13 18:45:46 +00008455 PY_LONG_LONG value;
8456 db_seq_t value2;
Jesus Cea6557aac2010-03-22 14:22:26 +00008457 if (!PyArg_ParseTuple(args,"L:initial_value", &value))
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008458 return NULL;
8459 CHECK_SEQUENCE_NOT_CLOSED(self)
8460
Jesus Ceaef9764f2008-05-13 18:45:46 +00008461 value2=value; /* If truncation, compiler should show a warning */
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008462 MYDB_BEGIN_ALLOW_THREADS
Jesus Ceaef9764f2008-05-13 18:45:46 +00008463 err = self->sequence->initial_value(self->sequence, value2);
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008464 MYDB_END_ALLOW_THREADS
8465
8466 RETURN_IF_ERR();
8467
8468 RETURN_NONE();
8469}
8470
8471static PyObject*
8472DBSequence_open(DBSequenceObject* self, PyObject* args, PyObject* kwargs)
8473{
8474 int err, flags = 0;
8475 PyObject* keyobj;
8476 PyObject *txnobj = NULL;
8477 DB_TXN *txn = NULL;
8478 DBT key;
8479
8480 static char* kwnames[] = {"key", "txn", "flags", NULL };
Neal Norwitzdd2a6bf2006-06-06 07:23:01 +00008481 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|Oi:open", kwnames, &keyobj, &txnobj, &flags))
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008482 return NULL;
8483
8484 if (!checkTxnObj(txnobj, &txn))
8485 return NULL;
8486
8487 if (!make_key_dbt(self->mydb, keyobj, &key, NULL))
8488 return NULL;
8489
8490 MYDB_BEGIN_ALLOW_THREADS
8491 err = self->sequence->open(self->sequence, txn, &key, flags);
8492 MYDB_END_ALLOW_THREADS
8493
Jesus Ceaac25fab2008-09-03 17:50:32 +00008494 FREE_DBT(key);
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008495 RETURN_IF_ERR();
8496
Jesus Ceaef9764f2008-05-13 18:45:46 +00008497 if (txn) {
8498 INSERT_IN_DOUBLE_LINKED_LIST_TXN(((DBTxnObject *)txnobj)->children_sequences,self);
8499 self->txn=(DBTxnObject *)txnobj;
8500 }
8501
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008502 RETURN_NONE();
8503}
8504
8505static PyObject*
8506DBSequence_remove(DBSequenceObject* self, PyObject* args, PyObject* kwargs)
8507{
Jesus Ceaef9764f2008-05-13 18:45:46 +00008508 PyObject *dummy;
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008509 int err, flags = 0;
8510 PyObject *txnobj = NULL;
8511 DB_TXN *txn = NULL;
8512
8513 static char* kwnames[] = {"txn", "flags", NULL };
Neal Norwitzdd2a6bf2006-06-06 07:23:01 +00008514 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Oi:remove", kwnames, &txnobj, &flags))
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008515 return NULL;
8516
8517 if (!checkTxnObj(txnobj, &txn))
8518 return NULL;
8519
8520 CHECK_SEQUENCE_NOT_CLOSED(self)
8521
8522 MYDB_BEGIN_ALLOW_THREADS
8523 err = self->sequence->remove(self->sequence, txn, flags);
8524 MYDB_END_ALLOW_THREADS
8525
Jesus Ceaef9764f2008-05-13 18:45:46 +00008526 dummy=DBSequence_close_internal(self,flags,1);
8527 Py_XDECREF(dummy);
8528
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008529 RETURN_IF_ERR();
8530 RETURN_NONE();
8531}
8532
8533static PyObject*
8534DBSequence_set_cachesize(DBSequenceObject* self, PyObject* args)
8535{
8536 int err, size;
Neal Norwitzdd2a6bf2006-06-06 07:23:01 +00008537 if (!PyArg_ParseTuple(args,"i:set_cachesize", &size))
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008538 return NULL;
8539 CHECK_SEQUENCE_NOT_CLOSED(self)
8540
8541 MYDB_BEGIN_ALLOW_THREADS
8542 err = self->sequence->set_cachesize(self->sequence, size);
8543 MYDB_END_ALLOW_THREADS
8544
8545 RETURN_IF_ERR();
8546 RETURN_NONE();
8547}
8548
8549static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008550DBSequence_get_cachesize(DBSequenceObject* self)
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008551{
8552 int err, size;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008553
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008554 CHECK_SEQUENCE_NOT_CLOSED(self)
8555
8556 MYDB_BEGIN_ALLOW_THREADS
8557 err = self->sequence->get_cachesize(self->sequence, &size);
8558 MYDB_END_ALLOW_THREADS
8559
8560 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008561 return NUMBER_FromLong(size);
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008562}
8563
8564static PyObject*
8565DBSequence_set_flags(DBSequenceObject* self, PyObject* args)
8566{
8567 int err, flags = 0;
Neal Norwitzdd2a6bf2006-06-06 07:23:01 +00008568 if (!PyArg_ParseTuple(args,"i:set_flags", &flags))
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008569 return NULL;
8570 CHECK_SEQUENCE_NOT_CLOSED(self)
8571
8572 MYDB_BEGIN_ALLOW_THREADS
8573 err = self->sequence->set_flags(self->sequence, flags);
8574 MYDB_END_ALLOW_THREADS
8575
8576 RETURN_IF_ERR();
8577 RETURN_NONE();
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008578}
8579
8580static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008581DBSequence_get_flags(DBSequenceObject* self)
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008582{
8583 unsigned int flags;
8584 int err;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008585
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008586 CHECK_SEQUENCE_NOT_CLOSED(self)
8587
8588 MYDB_BEGIN_ALLOW_THREADS
8589 err = self->sequence->get_flags(self->sequence, &flags);
8590 MYDB_END_ALLOW_THREADS
8591
8592 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008593 return NUMBER_FromLong((int)flags);
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008594}
8595
8596static PyObject*
8597DBSequence_set_range(DBSequenceObject* self, PyObject* args)
8598{
8599 int err;
Jesus Ceaef9764f2008-05-13 18:45:46 +00008600 PY_LONG_LONG min, max;
8601 db_seq_t min2, max2;
Tim Petersbb21b2c2006-06-06 15:50:17 +00008602 if (!PyArg_ParseTuple(args,"(LL):set_range", &min, &max))
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008603 return NULL;
8604 CHECK_SEQUENCE_NOT_CLOSED(self)
8605
Jesus Ceaef9764f2008-05-13 18:45:46 +00008606 min2=min; /* If truncation, compiler should show a warning */
8607 max2=max;
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008608 MYDB_BEGIN_ALLOW_THREADS
Jesus Ceaef9764f2008-05-13 18:45:46 +00008609 err = self->sequence->set_range(self->sequence, min2, max2);
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008610 MYDB_END_ALLOW_THREADS
8611
8612 RETURN_IF_ERR();
8613 RETURN_NONE();
8614}
8615
8616static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008617DBSequence_get_range(DBSequenceObject* self)
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008618{
8619 int err;
Jesus Ceaef9764f2008-05-13 18:45:46 +00008620 PY_LONG_LONG min, max;
8621 db_seq_t min2, max2;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008622
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008623 CHECK_SEQUENCE_NOT_CLOSED(self)
8624
8625 MYDB_BEGIN_ALLOW_THREADS
Jesus Ceaef9764f2008-05-13 18:45:46 +00008626 err = self->sequence->get_range(self->sequence, &min2, &max2);
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008627 MYDB_END_ALLOW_THREADS
8628
8629 RETURN_IF_ERR();
Jesus Ceaef9764f2008-05-13 18:45:46 +00008630 min=min2; /* If truncation, compiler should show a warning */
8631 max=max2;
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008632 return Py_BuildValue("(LL)", min, max);
8633}
8634
Jesus Cea6557aac2010-03-22 14:22:26 +00008635
8636static PyObject*
8637DBSequence_stat_print(DBSequenceObject* self, PyObject* args, PyObject *kwargs)
8638{
8639 int err;
8640 int flags=0;
8641 static char* kwnames[] = { "flags", NULL };
8642
8643 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:stat_print",
8644 kwnames, &flags))
8645 {
8646 return NULL;
8647 }
8648
8649 CHECK_SEQUENCE_NOT_CLOSED(self);
8650
8651 MYDB_BEGIN_ALLOW_THREADS;
8652 err = self->sequence->stat_print(self->sequence, flags);
8653 MYDB_END_ALLOW_THREADS;
8654 RETURN_IF_ERR();
8655 RETURN_NONE();
8656}
8657
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008658static PyObject*
8659DBSequence_stat(DBSequenceObject* self, PyObject* args, PyObject* kwargs)
8660{
8661 int err, flags = 0;
8662 DB_SEQUENCE_STAT* sp = NULL;
8663 PyObject* dict_stat;
8664 static char* kwnames[] = {"flags", NULL };
8665 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:stat", kwnames, &flags))
8666 return NULL;
8667 CHECK_SEQUENCE_NOT_CLOSED(self);
8668
8669 MYDB_BEGIN_ALLOW_THREADS;
8670 err = self->sequence->stat(self->sequence, &sp, flags);
8671 MYDB_END_ALLOW_THREADS;
8672 RETURN_IF_ERR();
8673
8674 if ((dict_stat = PyDict_New()) == NULL) {
8675 free(sp);
8676 return NULL;
8677 }
8678
8679
8680#define MAKE_INT_ENTRY(name) _addIntToDict(dict_stat, #name, sp->st_##name)
8681#define MAKE_LONG_LONG_ENTRY(name) _addDb_seq_tToDict(dict_stat, #name, sp->st_##name)
8682
8683 MAKE_INT_ENTRY(wait);
8684 MAKE_INT_ENTRY(nowait);
8685 MAKE_LONG_LONG_ENTRY(current);
8686 MAKE_LONG_LONG_ENTRY(value);
8687 MAKE_LONG_LONG_ENTRY(last_value);
8688 MAKE_LONG_LONG_ENTRY(min);
8689 MAKE_LONG_LONG_ENTRY(max);
8690 MAKE_INT_ENTRY(cache_size);
8691 MAKE_INT_ENTRY(flags);
8692
8693#undef MAKE_INT_ENTRY
8694#undef MAKE_LONG_LONG_ENTRY
8695
8696 free(sp);
8697 return dict_stat;
8698}
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008699
8700
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008701/* --------------------------------------------------------------------- */
8702/* Method definition tables and type objects */
8703
8704static PyMethodDef DB_methods[] = {
Jesus Cea4907d272008-08-31 14:00:51 +00008705 {"append", (PyCFunction)DB_append, METH_VARARGS|METH_KEYWORDS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008706 {"associate", (PyCFunction)DB_associate, METH_VARARGS|METH_KEYWORDS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008707 {"close", (PyCFunction)DB_close, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008708#if (DBVER >= 47)
8709 {"compact", (PyCFunction)DB_compact, METH_VARARGS|METH_KEYWORDS},
8710#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008711 {"consume", (PyCFunction)DB_consume, METH_VARARGS|METH_KEYWORDS},
8712 {"consume_wait", (PyCFunction)DB_consume_wait, METH_VARARGS|METH_KEYWORDS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008713 {"cursor", (PyCFunction)DB_cursor, METH_VARARGS|METH_KEYWORDS},
8714 {"delete", (PyCFunction)DB_delete, METH_VARARGS|METH_KEYWORDS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008715 {"fd", (PyCFunction)DB_fd, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008716#if (DBVER >= 46)
8717 {"exists", (PyCFunction)DB_exists,
8718 METH_VARARGS|METH_KEYWORDS},
8719#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008720 {"get", (PyCFunction)DB_get, METH_VARARGS|METH_KEYWORDS},
Gregory P. Smith19699a92004-06-28 04:06:49 +00008721 {"pget", (PyCFunction)DB_pget, METH_VARARGS|METH_KEYWORDS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008722 {"get_both", (PyCFunction)DB_get_both, METH_VARARGS|METH_KEYWORDS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008723 {"get_byteswapped", (PyCFunction)DB_get_byteswapped,METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008724 {"get_size", (PyCFunction)DB_get_size, METH_VARARGS|METH_KEYWORDS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008725 {"get_type", (PyCFunction)DB_get_type, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008726 {"join", (PyCFunction)DB_join, METH_VARARGS},
8727 {"key_range", (PyCFunction)DB_key_range, METH_VARARGS|METH_KEYWORDS},
Jesus Cea4907d272008-08-31 14:00:51 +00008728 {"has_key", (PyCFunction)DB_has_key, METH_VARARGS|METH_KEYWORDS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008729 {"items", (PyCFunction)DB_items, METH_VARARGS},
8730 {"keys", (PyCFunction)DB_keys, METH_VARARGS},
8731 {"open", (PyCFunction)DB_open, METH_VARARGS|METH_KEYWORDS},
8732 {"put", (PyCFunction)DB_put, METH_VARARGS|METH_KEYWORDS},
8733 {"remove", (PyCFunction)DB_remove, METH_VARARGS|METH_KEYWORDS},
8734 {"rename", (PyCFunction)DB_rename, METH_VARARGS},
8735 {"set_bt_minkey", (PyCFunction)DB_set_bt_minkey, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008736 {"get_bt_minkey", (PyCFunction)DB_get_bt_minkey, METH_NOARGS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008737 {"set_bt_compare", (PyCFunction)DB_set_bt_compare, METH_O},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008738 {"set_cachesize", (PyCFunction)DB_set_cachesize, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008739 {"get_cachesize", (PyCFunction)DB_get_cachesize, METH_NOARGS},
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07008740 {"set_dup_compare", (PyCFunction)DB_set_dup_compare, METH_O},
Jesus Cea6557aac2010-03-22 14:22:26 +00008741 {"set_encrypt", (PyCFunction)DB_set_encrypt, METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008742 {"get_encrypt_flags", (PyCFunction)DB_get_encrypt_flags, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008743 {"set_flags", (PyCFunction)DB_set_flags, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008744 {"get_flags", (PyCFunction)DB_get_flags, METH_NOARGS},
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07008745 {"get_transactional", (PyCFunction)DB_get_transactional, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008746 {"set_h_ffactor", (PyCFunction)DB_set_h_ffactor, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008747 {"get_h_ffactor", (PyCFunction)DB_get_h_ffactor, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008748 {"set_h_nelem", (PyCFunction)DB_set_h_nelem, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008749 {"get_h_nelem", (PyCFunction)DB_get_h_nelem, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008750 {"set_lorder", (PyCFunction)DB_set_lorder, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008751 {"get_lorder", (PyCFunction)DB_get_lorder, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008752 {"set_pagesize", (PyCFunction)DB_set_pagesize, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008753 {"get_pagesize", (PyCFunction)DB_get_pagesize, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008754 {"set_re_delim", (PyCFunction)DB_set_re_delim, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008755 {"get_re_delim", (PyCFunction)DB_get_re_delim, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008756 {"set_re_len", (PyCFunction)DB_set_re_len, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008757 {"get_re_len", (PyCFunction)DB_get_re_len, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008758 {"set_re_pad", (PyCFunction)DB_set_re_pad, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008759 {"get_re_pad", (PyCFunction)DB_get_re_pad, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008760 {"set_re_source", (PyCFunction)DB_set_re_source, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008761 {"get_re_source", (PyCFunction)DB_get_re_source, METH_NOARGS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008762 {"set_q_extentsize",(PyCFunction)DB_set_q_extentsize, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008763 {"get_q_extentsize",(PyCFunction)DB_get_q_extentsize, METH_NOARGS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008764 {"set_private", (PyCFunction)DB_set_private, METH_O},
8765 {"get_private", (PyCFunction)DB_get_private, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008766#if (DBVER >= 46)
8767 {"set_priority", (PyCFunction)DB_set_priority, METH_VARARGS},
8768 {"get_priority", (PyCFunction)DB_get_priority, METH_NOARGS},
8769#endif
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07008770 {"get_dbname", (PyCFunction)DB_get_dbname, METH_NOARGS},
8771 {"get_open_flags", (PyCFunction)DB_get_open_flags, METH_NOARGS},
Gregory P. Smith8b7e9172004-12-13 09:51:23 +00008772 {"stat", (PyCFunction)DB_stat, METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008773 {"stat_print", (PyCFunction)DB_stat_print,
8774 METH_VARARGS|METH_KEYWORDS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008775 {"sync", (PyCFunction)DB_sync, METH_VARARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008776 {"truncate", (PyCFunction)DB_truncate, METH_VARARGS|METH_KEYWORDS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008777 {"type", (PyCFunction)DB_get_type, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008778 {"upgrade", (PyCFunction)DB_upgrade, METH_VARARGS},
8779 {"values", (PyCFunction)DB_values, METH_VARARGS},
8780 {"verify", (PyCFunction)DB_verify, METH_VARARGS|METH_KEYWORDS},
8781 {"set_get_returns_none",(PyCFunction)DB_set_get_returns_none, METH_VARARGS},
8782 {NULL, NULL} /* sentinel */
8783};
8784
8785
Jesus Cea6557aac2010-03-22 14:22:26 +00008786/* We need this to support __contains__() */
8787static PySequenceMethods DB_sequence = {
8788 0, /* sq_length, mapping wins here */
8789 0, /* sq_concat */
8790 0, /* sq_repeat */
8791 0, /* sq_item */
8792 0, /* sq_slice */
8793 0, /* sq_ass_item */
8794 0, /* sq_ass_slice */
8795 (objobjproc)DB_contains, /* sq_contains */
8796 0, /* sq_inplace_concat */
8797 0, /* sq_inplace_repeat */
8798};
8799
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008800static PyMappingMethods DB_mapping = {
Martin v. Löwis70ee3cc2006-06-12 04:26:31 +00008801 DB_length, /*mp_length*/
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008802 (binaryfunc)DB_subscript, /*mp_subscript*/
8803 (objobjargproc)DB_ass_sub, /*mp_ass_subscript*/
8804};
8805
8806
8807static PyMethodDef DBCursor_methods[] = {
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008808 {"close", (PyCFunction)DBC_close, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008809 {"count", (PyCFunction)DBC_count, METH_VARARGS},
8810 {"current", (PyCFunction)DBC_current, METH_VARARGS|METH_KEYWORDS},
8811 {"delete", (PyCFunction)DBC_delete, METH_VARARGS},
8812 {"dup", (PyCFunction)DBC_dup, METH_VARARGS},
8813 {"first", (PyCFunction)DBC_first, METH_VARARGS|METH_KEYWORDS},
8814 {"get", (PyCFunction)DBC_get, METH_VARARGS|METH_KEYWORDS},
Gregory P. Smith19699a92004-06-28 04:06:49 +00008815 {"pget", (PyCFunction)DBC_pget, METH_VARARGS|METH_KEYWORDS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008816 {"get_recno", (PyCFunction)DBC_get_recno, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008817 {"last", (PyCFunction)DBC_last, METH_VARARGS|METH_KEYWORDS},
8818 {"next", (PyCFunction)DBC_next, METH_VARARGS|METH_KEYWORDS},
8819 {"prev", (PyCFunction)DBC_prev, METH_VARARGS|METH_KEYWORDS},
8820 {"put", (PyCFunction)DBC_put, METH_VARARGS|METH_KEYWORDS},
8821 {"set", (PyCFunction)DBC_set, METH_VARARGS|METH_KEYWORDS},
8822 {"set_range", (PyCFunction)DBC_set_range, METH_VARARGS|METH_KEYWORDS},
8823 {"get_both", (PyCFunction)DBC_get_both, METH_VARARGS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008824 {"get_current_size",(PyCFunction)DBC_get_current_size, METH_NOARGS},
Gregory P. Smith455d46f2003-07-09 04:45:59 +00008825 {"set_both", (PyCFunction)DBC_set_both, METH_VARARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008826 {"set_recno", (PyCFunction)DBC_set_recno, METH_VARARGS|METH_KEYWORDS},
8827 {"consume", (PyCFunction)DBC_consume, METH_VARARGS|METH_KEYWORDS},
8828 {"next_dup", (PyCFunction)DBC_next_dup, METH_VARARGS|METH_KEYWORDS},
8829 {"next_nodup", (PyCFunction)DBC_next_nodup, METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008830#if (DBVER >= 46)
8831 {"prev_dup", (PyCFunction)DBC_prev_dup,
8832 METH_VARARGS|METH_KEYWORDS},
8833#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008834 {"prev_nodup", (PyCFunction)DBC_prev_nodup, METH_VARARGS|METH_KEYWORDS},
8835 {"join_item", (PyCFunction)DBC_join_item, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008836#if (DBVER >= 46)
8837 {"set_priority", (PyCFunction)DBC_set_priority,
8838 METH_VARARGS|METH_KEYWORDS},
8839 {"get_priority", (PyCFunction)DBC_get_priority, METH_NOARGS},
8840#endif
8841 {NULL, NULL} /* sentinel */
8842};
8843
8844
8845static PyMethodDef DBLogCursor_methods[] = {
8846 {"close", (PyCFunction)DBLogCursor_close, METH_NOARGS},
8847 {"current", (PyCFunction)DBLogCursor_current, METH_NOARGS},
8848 {"first", (PyCFunction)DBLogCursor_first, METH_NOARGS},
8849 {"last", (PyCFunction)DBLogCursor_last, METH_NOARGS},
8850 {"next", (PyCFunction)DBLogCursor_next, METH_NOARGS},
8851 {"prev", (PyCFunction)DBLogCursor_prev, METH_NOARGS},
8852 {"set", (PyCFunction)DBLogCursor_set, METH_VARARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008853 {NULL, NULL} /* sentinel */
8854};
8855
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07008856#if (DBVER >= 52)
8857static PyMethodDef DBSite_methods[] = {
8858 {"get_config", (PyCFunction)DBSite_get_config,
8859 METH_VARARGS | METH_KEYWORDS},
8860 {"set_config", (PyCFunction)DBSite_set_config,
8861 METH_VARARGS | METH_KEYWORDS},
8862 {"remove", (PyCFunction)DBSite_remove, METH_NOARGS},
8863 {"get_eid", (PyCFunction)DBSite_get_eid, METH_NOARGS},
8864 {"get_address", (PyCFunction)DBSite_get_address, METH_NOARGS},
8865 {"close", (PyCFunction)DBSite_close, METH_NOARGS},
8866 {NULL, NULL} /* sentinel */
8867};
8868#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008869
8870static PyMethodDef DBEnv_methods[] = {
8871 {"close", (PyCFunction)DBEnv_close, METH_VARARGS},
8872 {"open", (PyCFunction)DBEnv_open, METH_VARARGS},
8873 {"remove", (PyCFunction)DBEnv_remove, METH_VARARGS},
Barry Warsaw9a0d7792002-12-30 20:53:52 +00008874 {"dbremove", (PyCFunction)DBEnv_dbremove, METH_VARARGS|METH_KEYWORDS},
8875 {"dbrename", (PyCFunction)DBEnv_dbrename, METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008876#if (DBVER >= 46)
8877 {"set_thread_count", (PyCFunction)DBEnv_set_thread_count, METH_VARARGS},
8878 {"get_thread_count", (PyCFunction)DBEnv_get_thread_count, METH_NOARGS},
8879#endif
Barry Warsaw9a0d7792002-12-30 20:53:52 +00008880 {"set_encrypt", (PyCFunction)DBEnv_set_encrypt, METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008881 {"get_encrypt_flags", (PyCFunction)DBEnv_get_encrypt_flags, METH_NOARGS},
8882 {"get_timeout", (PyCFunction)DBEnv_get_timeout,
8883 METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008884 {"set_timeout", (PyCFunction)DBEnv_set_timeout, METH_VARARGS|METH_KEYWORDS},
8885 {"set_shm_key", (PyCFunction)DBEnv_set_shm_key, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008886 {"get_shm_key", (PyCFunction)DBEnv_get_shm_key, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008887#if (DBVER >= 46)
8888 {"set_cache_max", (PyCFunction)DBEnv_set_cache_max, METH_VARARGS},
8889 {"get_cache_max", (PyCFunction)DBEnv_get_cache_max, METH_NOARGS},
8890#endif
8891 {"set_cachesize", (PyCFunction)DBEnv_set_cachesize, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008892 {"get_cachesize", (PyCFunction)DBEnv_get_cachesize, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008893 {"memp_trickle", (PyCFunction)DBEnv_memp_trickle, METH_VARARGS},
8894 {"memp_sync", (PyCFunction)DBEnv_memp_sync, METH_VARARGS},
8895 {"memp_stat", (PyCFunction)DBEnv_memp_stat,
8896 METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008897 {"memp_stat_print", (PyCFunction)DBEnv_memp_stat_print,
8898 METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008899#if (DBVER >= 44)
8900 {"mutex_set_max", (PyCFunction)DBEnv_mutex_set_max, METH_VARARGS},
8901 {"mutex_get_max", (PyCFunction)DBEnv_mutex_get_max, METH_NOARGS},
8902 {"mutex_set_align", (PyCFunction)DBEnv_mutex_set_align, METH_VARARGS},
8903 {"mutex_get_align", (PyCFunction)DBEnv_mutex_get_align, METH_NOARGS},
8904 {"mutex_set_increment", (PyCFunction)DBEnv_mutex_set_increment,
8905 METH_VARARGS},
8906 {"mutex_get_increment", (PyCFunction)DBEnv_mutex_get_increment,
8907 METH_NOARGS},
8908 {"mutex_set_tas_spins", (PyCFunction)DBEnv_mutex_set_tas_spins,
8909 METH_VARARGS},
8910 {"mutex_get_tas_spins", (PyCFunction)DBEnv_mutex_get_tas_spins,
8911 METH_NOARGS},
8912 {"mutex_stat", (PyCFunction)DBEnv_mutex_stat, METH_VARARGS},
8913#if (DBVER >= 44)
8914 {"mutex_stat_print", (PyCFunction)DBEnv_mutex_stat_print,
8915 METH_VARARGS|METH_KEYWORDS},
8916#endif
8917#endif
8918 {"set_data_dir", (PyCFunction)DBEnv_set_data_dir, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008919 {"get_data_dirs", (PyCFunction)DBEnv_get_data_dirs, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008920 {"get_flags", (PyCFunction)DBEnv_get_flags, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008921 {"set_flags", (PyCFunction)DBEnv_set_flags, METH_VARARGS},
8922#if (DBVER >= 47)
8923 {"log_set_config", (PyCFunction)DBEnv_log_set_config, METH_VARARGS},
8924 {"log_get_config", (PyCFunction)DBEnv_log_get_config, METH_VARARGS},
8925#endif
8926 {"set_lg_bsize", (PyCFunction)DBEnv_set_lg_bsize, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008927 {"get_lg_bsize", (PyCFunction)DBEnv_get_lg_bsize, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008928 {"set_lg_dir", (PyCFunction)DBEnv_set_lg_dir, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008929 {"get_lg_dir", (PyCFunction)DBEnv_get_lg_dir, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008930 {"set_lg_max", (PyCFunction)DBEnv_set_lg_max, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008931 {"get_lg_max", (PyCFunction)DBEnv_get_lg_max, METH_NOARGS},
Gregory P. Smithe9477062005-06-04 06:46:59 +00008932 {"set_lg_regionmax",(PyCFunction)DBEnv_set_lg_regionmax, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008933 {"get_lg_regionmax",(PyCFunction)DBEnv_get_lg_regionmax, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008934#if (DBVER >= 44)
8935 {"set_lg_filemode", (PyCFunction)DBEnv_set_lg_filemode, METH_VARARGS},
8936 {"get_lg_filemode", (PyCFunction)DBEnv_get_lg_filemode, METH_NOARGS},
8937#endif
8938#if (DBVER >= 47)
8939 {"set_lk_partitions", (PyCFunction)DBEnv_set_lk_partitions, METH_VARARGS},
8940 {"get_lk_partitions", (PyCFunction)DBEnv_get_lk_partitions, METH_NOARGS},
8941#endif
8942 {"set_lk_detect", (PyCFunction)DBEnv_set_lk_detect, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008943 {"get_lk_detect", (PyCFunction)DBEnv_get_lk_detect, METH_NOARGS},
Gregory P. Smith8b96a352007-01-05 01:59:42 +00008944#if (DBVER < 45)
Jesus Cea6557aac2010-03-22 14:22:26 +00008945 {"set_lk_max", (PyCFunction)DBEnv_set_lk_max, METH_VARARGS},
Gregory P. Smith8b96a352007-01-05 01:59:42 +00008946#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008947 {"set_lk_max_locks", (PyCFunction)DBEnv_set_lk_max_locks, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008948 {"get_lk_max_locks", (PyCFunction)DBEnv_get_lk_max_locks, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008949 {"set_lk_max_lockers", (PyCFunction)DBEnv_set_lk_max_lockers, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008950 {"get_lk_max_lockers", (PyCFunction)DBEnv_get_lk_max_lockers, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008951 {"set_lk_max_objects", (PyCFunction)DBEnv_set_lk_max_objects, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008952 {"get_lk_max_objects", (PyCFunction)DBEnv_get_lk_max_objects, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008953 {"stat_print", (PyCFunction)DBEnv_stat_print,
8954 METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008955 {"set_mp_mmapsize", (PyCFunction)DBEnv_set_mp_mmapsize, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008956 {"get_mp_mmapsize", (PyCFunction)DBEnv_get_mp_mmapsize, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008957 {"set_tmp_dir", (PyCFunction)DBEnv_set_tmp_dir, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008958 {"get_tmp_dir", (PyCFunction)DBEnv_get_tmp_dir, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008959 {"txn_begin", (PyCFunction)DBEnv_txn_begin, METH_VARARGS|METH_KEYWORDS},
8960 {"txn_checkpoint", (PyCFunction)DBEnv_txn_checkpoint, METH_VARARGS},
8961 {"txn_stat", (PyCFunction)DBEnv_txn_stat, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008962 {"txn_stat_print", (PyCFunction)DBEnv_txn_stat_print,
8963 METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008964 {"get_tx_max", (PyCFunction)DBEnv_get_tx_max, METH_NOARGS},
8965 {"get_tx_timestamp", (PyCFunction)DBEnv_get_tx_timestamp, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008966 {"set_tx_max", (PyCFunction)DBEnv_set_tx_max, METH_VARARGS},
Gregory P. Smith8a474042006-01-27 07:05:40 +00008967 {"set_tx_timestamp", (PyCFunction)DBEnv_set_tx_timestamp, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008968 {"lock_detect", (PyCFunction)DBEnv_lock_detect, METH_VARARGS},
8969 {"lock_get", (PyCFunction)DBEnv_lock_get, METH_VARARGS},
8970 {"lock_id", (PyCFunction)DBEnv_lock_id, METH_NOARGS},
8971 {"lock_id_free", (PyCFunction)DBEnv_lock_id_free, METH_VARARGS},
8972 {"lock_put", (PyCFunction)DBEnv_lock_put, METH_VARARGS},
8973 {"lock_stat", (PyCFunction)DBEnv_lock_stat, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008974 {"lock_stat_print", (PyCFunction)DBEnv_lock_stat_print,
8975 METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008976 {"log_cursor", (PyCFunction)DBEnv_log_cursor, METH_NOARGS},
8977 {"log_file", (PyCFunction)DBEnv_log_file, METH_VARARGS},
Gregory P. Smithdb8a8072006-06-05 01:56:15 +00008978#if (DBVER >= 44)
Jesus Cea6557aac2010-03-22 14:22:26 +00008979 {"log_printf", (PyCFunction)DBEnv_log_printf,
8980 METH_VARARGS|METH_KEYWORDS},
8981#endif
8982 {"log_archive", (PyCFunction)DBEnv_log_archive, METH_VARARGS},
8983 {"log_flush", (PyCFunction)DBEnv_log_flush, METH_NOARGS},
8984 {"log_stat", (PyCFunction)DBEnv_log_stat, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008985 {"log_stat_print", (PyCFunction)DBEnv_log_stat_print,
8986 METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008987#if (DBVER >= 44)
8988 {"fileid_reset", (PyCFunction)DBEnv_fileid_reset, METH_VARARGS|METH_KEYWORDS},
8989 {"lsn_reset", (PyCFunction)DBEnv_lsn_reset, METH_VARARGS|METH_KEYWORDS},
Gregory P. Smithdb8a8072006-06-05 01:56:15 +00008990#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008991 {"set_get_returns_none",(PyCFunction)DBEnv_set_get_returns_none, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008992 {"txn_recover", (PyCFunction)DBEnv_txn_recover, METH_NOARGS},
Matthias Klose54cc5392010-03-15 12:46:18 +00008993#if (DBVER < 48)
Jesus Ceaca3939c2008-05-22 15:27:38 +00008994 {"set_rpc_server", (PyCFunction)DBEnv_set_rpc_server,
Stefan Krah77112732011-09-15 22:56:00 +02008995 METH_VARARGS|METH_KEYWORDS},
Matthias Klose54cc5392010-03-15 12:46:18 +00008996#endif
Jesus Cea6557aac2010-03-22 14:22:26 +00008997 {"set_mp_max_openfd", (PyCFunction)DBEnv_set_mp_max_openfd, METH_VARARGS},
8998 {"get_mp_max_openfd", (PyCFunction)DBEnv_get_mp_max_openfd, METH_NOARGS},
8999 {"set_mp_max_write", (PyCFunction)DBEnv_set_mp_max_write, METH_VARARGS},
9000 {"get_mp_max_write", (PyCFunction)DBEnv_get_mp_max_write, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00009001 {"set_verbose", (PyCFunction)DBEnv_set_verbose, METH_VARARGS},
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009002 {"get_verbose", (PyCFunction)DBEnv_get_verbose, METH_VARARGS},
9003 {"set_private", (PyCFunction)DBEnv_set_private, METH_O},
9004 {"get_private", (PyCFunction)DBEnv_get_private, METH_NOARGS},
9005 {"get_open_flags", (PyCFunction)DBEnv_get_open_flags, METH_NOARGS},
9006#if (DBVER >= 47)
9007 {"set_intermediate_dir_mode", (PyCFunction)DBEnv_set_intermediate_dir_mode,
9008 METH_VARARGS},
9009 {"get_intermediate_dir_mode", (PyCFunction)DBEnv_get_intermediate_dir_mode,
9010 METH_NOARGS},
Jesus Ceaef9764f2008-05-13 18:45:46 +00009011#endif
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009012#if (DBVER < 47)
9013 {"set_intermediate_dir", (PyCFunction)DBEnv_set_intermediate_dir,
9014 METH_VARARGS},
9015#endif
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009016 {"rep_start", (PyCFunction)DBEnv_rep_start,
9017 METH_VARARGS|METH_KEYWORDS},
9018 {"rep_set_transport", (PyCFunction)DBEnv_rep_set_transport, METH_VARARGS},
9019 {"rep_process_message", (PyCFunction)DBEnv_rep_process_message,
9020 METH_VARARGS},
9021#if (DBVER >= 46)
9022 {"rep_elect", (PyCFunction)DBEnv_rep_elect, METH_VARARGS},
9023#endif
9024#if (DBVER >= 44)
9025 {"rep_set_config", (PyCFunction)DBEnv_rep_set_config, METH_VARARGS},
9026 {"rep_get_config", (PyCFunction)DBEnv_rep_get_config, METH_VARARGS},
9027 {"rep_sync", (PyCFunction)DBEnv_rep_sync, METH_NOARGS},
Jesus Ceaef9764f2008-05-13 18:45:46 +00009028#endif
9029#if (DBVER >= 45)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009030 {"rep_set_limit", (PyCFunction)DBEnv_rep_set_limit, METH_VARARGS},
9031 {"rep_get_limit", (PyCFunction)DBEnv_rep_get_limit, METH_NOARGS},
9032#endif
9033#if (DBVER >= 47)
9034 {"rep_set_request", (PyCFunction)DBEnv_rep_set_request, METH_VARARGS},
9035 {"rep_get_request", (PyCFunction)DBEnv_rep_get_request, METH_NOARGS},
9036#endif
9037#if (DBVER >= 45)
9038 {"set_event_notify", (PyCFunction)DBEnv_set_event_notify, METH_O},
Jesus Ceaef9764f2008-05-13 18:45:46 +00009039#endif
9040#if (DBVER >= 45)
9041 {"rep_set_nsites", (PyCFunction)DBEnv_rep_set_nsites, METH_VARARGS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009042 {"rep_get_nsites", (PyCFunction)DBEnv_rep_get_nsites, METH_NOARGS},
Jesus Ceaef9764f2008-05-13 18:45:46 +00009043 {"rep_set_priority", (PyCFunction)DBEnv_rep_set_priority, METH_VARARGS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009044 {"rep_get_priority", (PyCFunction)DBEnv_rep_get_priority, METH_NOARGS},
Jesus Ceaef9764f2008-05-13 18:45:46 +00009045 {"rep_set_timeout", (PyCFunction)DBEnv_rep_set_timeout, METH_VARARGS},
9046 {"rep_get_timeout", (PyCFunction)DBEnv_rep_get_timeout, METH_VARARGS},
9047#endif
Jesus Cea6557aac2010-03-22 14:22:26 +00009048#if (DBVER >= 47)
9049 {"rep_set_clockskew", (PyCFunction)DBEnv_rep_set_clockskew, METH_VARARGS},
9050 {"rep_get_clockskew", (PyCFunction)DBEnv_rep_get_clockskew, METH_VARARGS},
9051#endif
9052 {"rep_stat", (PyCFunction)DBEnv_rep_stat,
9053 METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00009054 {"rep_stat_print", (PyCFunction)DBEnv_rep_stat_print,
9055 METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00009056
Jesus Ceaef9764f2008-05-13 18:45:46 +00009057#if (DBVER >= 45)
9058 {"repmgr_start", (PyCFunction)DBEnv_repmgr_start,
9059 METH_VARARGS|METH_KEYWORDS},
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009060#if (DBVER < 52)
Jesus Ceaef9764f2008-05-13 18:45:46 +00009061 {"repmgr_set_local_site", (PyCFunction)DBEnv_repmgr_set_local_site,
9062 METH_VARARGS|METH_KEYWORDS},
9063 {"repmgr_add_remote_site", (PyCFunction)DBEnv_repmgr_add_remote_site,
9064 METH_VARARGS|METH_KEYWORDS},
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009065#endif
Jesus Ceaef9764f2008-05-13 18:45:46 +00009066 {"repmgr_set_ack_policy", (PyCFunction)DBEnv_repmgr_set_ack_policy,
9067 METH_VARARGS},
9068 {"repmgr_get_ack_policy", (PyCFunction)DBEnv_repmgr_get_ack_policy,
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009069 METH_NOARGS},
Jesus Ceaef9764f2008-05-13 18:45:46 +00009070 {"repmgr_site_list", (PyCFunction)DBEnv_repmgr_site_list,
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009071 METH_NOARGS},
Jesus Ceaef9764f2008-05-13 18:45:46 +00009072#endif
9073#if (DBVER >= 46)
9074 {"repmgr_stat", (PyCFunction)DBEnv_repmgr_stat,
9075 METH_VARARGS|METH_KEYWORDS},
9076 {"repmgr_stat_print", (PyCFunction)DBEnv_repmgr_stat_print,
9077 METH_VARARGS|METH_KEYWORDS},
9078#endif
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009079#if (DBVER >= 52)
9080 {"repmgr_site", (PyCFunction)DBEnv_repmgr_site,
9081 METH_VARARGS | METH_KEYWORDS},
9082 {"repmgr_site_by_eid", (PyCFunction)DBEnv_repmgr_site_by_eid,
9083 METH_VARARGS | METH_KEYWORDS},
9084#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009085 {NULL, NULL} /* sentinel */
9086};
9087
9088
9089static PyMethodDef DBTxn_methods[] = {
9090 {"commit", (PyCFunction)DBTxn_commit, METH_VARARGS},
9091 {"prepare", (PyCFunction)DBTxn_prepare, METH_VARARGS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009092 {"discard", (PyCFunction)DBTxn_discard, METH_NOARGS},
9093 {"abort", (PyCFunction)DBTxn_abort, METH_NOARGS},
9094 {"id", (PyCFunction)DBTxn_id, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00009095 {"set_timeout", (PyCFunction)DBTxn_set_timeout,
9096 METH_VARARGS|METH_KEYWORDS},
9097#if (DBVER >= 44)
9098 {"set_name", (PyCFunction)DBTxn_set_name, METH_VARARGS},
9099 {"get_name", (PyCFunction)DBTxn_get_name, METH_NOARGS},
9100#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009101 {NULL, NULL} /* sentinel */
9102};
9103
9104
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009105static PyMethodDef DBSequence_methods[] = {
9106 {"close", (PyCFunction)DBSequence_close, METH_VARARGS},
9107 {"get", (PyCFunction)DBSequence_get, METH_VARARGS|METH_KEYWORDS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009108 {"get_dbp", (PyCFunction)DBSequence_get_dbp, METH_NOARGS},
9109 {"get_key", (PyCFunction)DBSequence_get_key, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00009110 {"initial_value", (PyCFunction)DBSequence_initial_value, METH_VARARGS},
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009111 {"open", (PyCFunction)DBSequence_open, METH_VARARGS|METH_KEYWORDS},
9112 {"remove", (PyCFunction)DBSequence_remove, METH_VARARGS|METH_KEYWORDS},
9113 {"set_cachesize", (PyCFunction)DBSequence_set_cachesize, METH_VARARGS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009114 {"get_cachesize", (PyCFunction)DBSequence_get_cachesize, METH_NOARGS},
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009115 {"set_flags", (PyCFunction)DBSequence_set_flags, METH_VARARGS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009116 {"get_flags", (PyCFunction)DBSequence_get_flags, METH_NOARGS},
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009117 {"set_range", (PyCFunction)DBSequence_set_range, METH_VARARGS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009118 {"get_range", (PyCFunction)DBSequence_get_range, METH_NOARGS},
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009119 {"stat", (PyCFunction)DBSequence_stat, METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00009120 {"stat_print", (PyCFunction)DBSequence_stat_print,
9121 METH_VARARGS|METH_KEYWORDS},
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009122 {NULL, NULL} /* sentinel */
9123};
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009124
9125
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009126static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009127DBEnv_db_home_get(DBEnvObject* self)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009128{
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009129 const char *home = NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009130
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009131 CHECK_ENV_NOT_CLOSED(self);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009132
Jesus Cea6557aac2010-03-22 14:22:26 +00009133 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009134 self->db_env->get_home(self->db_env, &home);
Jesus Cea6557aac2010-03-22 14:22:26 +00009135 MYDB_END_ALLOW_THREADS;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009136
9137 if (home == NULL) {
9138 RETURN_NONE();
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009139 }
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009140 return PyBytes_FromString(home);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009141}
9142
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009143static PyGetSetDef DBEnv_getsets[] = {
9144 {"db_home", (getter)DBEnv_db_home_get, NULL,},
9145 {NULL}
9146};
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009147
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009148
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009149statichere PyTypeObject DB_Type = {
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009150#if (PY_VERSION_HEX < 0x03000000)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009151 PyObject_HEAD_INIT(NULL)
9152 0, /*ob_size*/
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009153#else
9154 PyVarObject_HEAD_INIT(NULL, 0)
9155#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009156 "DB", /*tp_name*/
9157 sizeof(DBObject), /*tp_basicsize*/
9158 0, /*tp_itemsize*/
9159 /* methods */
9160 (destructor)DB_dealloc, /*tp_dealloc*/
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009161 0, /*tp_print*/
9162 0, /*tp_getattr*/
9163 0, /*tp_setattr*/
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009164 0, /*tp_compare*/
9165 0, /*tp_repr*/
9166 0, /*tp_as_number*/
Jesus Cea6557aac2010-03-22 14:22:26 +00009167 &DB_sequence,/*tp_as_sequence*/
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009168 &DB_mapping,/*tp_as_mapping*/
9169 0, /*tp_hash*/
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009170 0, /* tp_call */
9171 0, /* tp_str */
9172 0, /* tp_getattro */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009173 0, /* tp_setattro */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009174 0, /* tp_as_buffer */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009175#if (PY_VERSION_HEX < 0x03000000)
Gregory P. Smith31c50652004-06-28 01:20:40 +00009176 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009177#else
9178 Py_TPFLAGS_DEFAULT, /* tp_flags */
9179#endif
9180 0, /* tp_doc */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009181 0, /* tp_traverse */
9182 0, /* tp_clear */
9183 0, /* tp_richcompare */
Gregory P. Smith31c50652004-06-28 01:20:40 +00009184 offsetof(DBObject, in_weakreflist), /* tp_weaklistoffset */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009185 0, /*tp_iter*/
9186 0, /*tp_iternext*/
9187 DB_methods, /*tp_methods*/
9188 0, /*tp_members*/
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009189};
9190
9191
9192statichere PyTypeObject DBCursor_Type = {
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009193#if (PY_VERSION_HEX < 0x03000000)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009194 PyObject_HEAD_INIT(NULL)
9195 0, /*ob_size*/
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009196#else
9197 PyVarObject_HEAD_INIT(NULL, 0)
9198#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009199 "DBCursor", /*tp_name*/
9200 sizeof(DBCursorObject), /*tp_basicsize*/
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009201 0, /*tp_itemsize*/
9202 /* methods */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009203 (destructor)DBCursor_dealloc,/*tp_dealloc*/
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009204 0, /*tp_print*/
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009205 0, /*tp_getattr*/
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009206 0, /*tp_setattr*/
9207 0, /*tp_compare*/
9208 0, /*tp_repr*/
9209 0, /*tp_as_number*/
9210 0, /*tp_as_sequence*/
9211 0, /*tp_as_mapping*/
9212 0, /*tp_hash*/
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009213 0, /*tp_call*/
9214 0, /*tp_str*/
9215 0, /*tp_getattro*/
9216 0, /*tp_setattro*/
9217 0, /*tp_as_buffer*/
9218#if (PY_VERSION_HEX < 0x03000000)
Gregory P. Smith31c50652004-06-28 01:20:40 +00009219 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009220#else
9221 Py_TPFLAGS_DEFAULT, /* tp_flags */
9222#endif
9223 0, /* tp_doc */
9224 0, /* tp_traverse */
9225 0, /* tp_clear */
9226 0, /* tp_richcompare */
9227 offsetof(DBCursorObject, in_weakreflist), /* tp_weaklistoffset */
9228 0, /*tp_iter*/
9229 0, /*tp_iternext*/
9230 DBCursor_methods, /*tp_methods*/
9231 0, /*tp_members*/
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009232};
9233
9234
Jesus Cea6557aac2010-03-22 14:22:26 +00009235statichere PyTypeObject DBLogCursor_Type = {
9236#if (PY_VERSION_HEX < 0x03000000)
9237 PyObject_HEAD_INIT(NULL)
9238 0, /*ob_size*/
9239#else
9240 PyVarObject_HEAD_INIT(NULL, 0)
9241#endif
9242 "DBLogCursor", /*tp_name*/
9243 sizeof(DBLogCursorObject), /*tp_basicsize*/
9244 0, /*tp_itemsize*/
9245 /* methods */
9246 (destructor)DBLogCursor_dealloc,/*tp_dealloc*/
9247 0, /*tp_print*/
9248 0, /*tp_getattr*/
9249 0, /*tp_setattr*/
9250 0, /*tp_compare*/
9251 0, /*tp_repr*/
9252 0, /*tp_as_number*/
9253 0, /*tp_as_sequence*/
9254 0, /*tp_as_mapping*/
9255 0, /*tp_hash*/
9256 0, /*tp_call*/
9257 0, /*tp_str*/
9258 0, /*tp_getattro*/
9259 0, /*tp_setattro*/
9260 0, /*tp_as_buffer*/
9261#if (PY_VERSION_HEX < 0x03000000)
9262 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
9263#else
9264 Py_TPFLAGS_DEFAULT, /* tp_flags */
9265#endif
9266 0, /* tp_doc */
9267 0, /* tp_traverse */
9268 0, /* tp_clear */
9269 0, /* tp_richcompare */
9270 offsetof(DBLogCursorObject, in_weakreflist), /* tp_weaklistoffset */
9271 0, /*tp_iter*/
9272 0, /*tp_iternext*/
9273 DBLogCursor_methods, /*tp_methods*/
9274 0, /*tp_members*/
9275};
9276
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009277#if (DBVER >= 52)
9278statichere PyTypeObject DBSite_Type = {
9279#if (PY_VERSION_HEX < 0x03000000)
9280 PyObject_HEAD_INIT(NULL)
9281 0, /*ob_size*/
9282#else
9283 PyVarObject_HEAD_INIT(NULL, 0)
9284#endif
9285 "DBSite", /*tp_name*/
9286 sizeof(DBSiteObject), /*tp_basicsize*/
9287 0, /*tp_itemsize*/
9288 /* methods */
9289 (destructor)DBSite_dealloc,/*tp_dealloc*/
9290 0, /*tp_print*/
9291 0, /*tp_getattr*/
9292 0, /*tp_setattr*/
9293 0, /*tp_compare*/
9294 0, /*tp_repr*/
9295 0, /*tp_as_number*/
9296 0, /*tp_as_sequence*/
9297 0, /*tp_as_mapping*/
9298 0, /*tp_hash*/
9299 0, /*tp_call*/
9300 0, /*tp_str*/
9301 0, /*tp_getattro*/
9302 0, /*tp_setattro*/
9303 0, /*tp_as_buffer*/
9304#if (PY_VERSION_HEX < 0x03000000)
9305 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
9306#else
9307 Py_TPFLAGS_DEFAULT, /* tp_flags */
9308#endif
9309 0, /* tp_doc */
9310 0, /* tp_traverse */
9311 0, /* tp_clear */
9312 0, /* tp_richcompare */
9313 offsetof(DBSiteObject, in_weakreflist), /* tp_weaklistoffset */
9314 0, /*tp_iter*/
9315 0, /*tp_iternext*/
9316 DBSite_methods, /*tp_methods*/
9317 0, /*tp_members*/
9318};
9319#endif
Jesus Cea6557aac2010-03-22 14:22:26 +00009320
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009321statichere PyTypeObject DBEnv_Type = {
9322#if (PY_VERSION_HEX < 0x03000000)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009323 PyObject_HEAD_INIT(NULL)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009324 0, /*ob_size*/
9325#else
9326 PyVarObject_HEAD_INIT(NULL, 0)
9327#endif
9328 "DBEnv", /*tp_name*/
9329 sizeof(DBEnvObject), /*tp_basicsize*/
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009330 0, /*tp_itemsize*/
9331 /* methods */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009332 (destructor)DBEnv_dealloc, /*tp_dealloc*/
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009333 0, /*tp_print*/
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009334 0, /*tp_getattr*/
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009335 0, /*tp_setattr*/
9336 0, /*tp_compare*/
9337 0, /*tp_repr*/
9338 0, /*tp_as_number*/
9339 0, /*tp_as_sequence*/
9340 0, /*tp_as_mapping*/
9341 0, /*tp_hash*/
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009342 0, /* tp_call */
9343 0, /* tp_str */
9344 0, /* tp_getattro */
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009345 0, /* tp_setattro */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009346 0, /* tp_as_buffer */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009347#if (PY_VERSION_HEX < 0x03000000)
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009348 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009349#else
9350 Py_TPFLAGS_DEFAULT, /* tp_flags */
9351#endif
9352 0, /* tp_doc */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009353 0, /* tp_traverse */
9354 0, /* tp_clear */
9355 0, /* tp_richcompare */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009356 offsetof(DBEnvObject, in_weakreflist), /* tp_weaklistoffset */
9357 0, /* tp_iter */
9358 0, /* tp_iternext */
9359 DBEnv_methods, /* tp_methods */
9360 0, /* tp_members */
9361 DBEnv_getsets, /* tp_getsets */
9362};
9363
9364statichere PyTypeObject DBTxn_Type = {
9365#if (PY_VERSION_HEX < 0x03000000)
9366 PyObject_HEAD_INIT(NULL)
9367 0, /*ob_size*/
9368#else
9369 PyVarObject_HEAD_INIT(NULL, 0)
9370#endif
9371 "DBTxn", /*tp_name*/
9372 sizeof(DBTxnObject), /*tp_basicsize*/
9373 0, /*tp_itemsize*/
9374 /* methods */
9375 (destructor)DBTxn_dealloc, /*tp_dealloc*/
9376 0, /*tp_print*/
9377 0, /*tp_getattr*/
9378 0, /*tp_setattr*/
9379 0, /*tp_compare*/
9380 0, /*tp_repr*/
9381 0, /*tp_as_number*/
9382 0, /*tp_as_sequence*/
9383 0, /*tp_as_mapping*/
9384 0, /*tp_hash*/
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009385 0, /* tp_call */
9386 0, /* tp_str */
9387 0, /* tp_getattro */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009388 0, /* tp_setattro */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009389 0, /* tp_as_buffer */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009390#if (PY_VERSION_HEX < 0x03000000)
9391 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
9392#else
9393 Py_TPFLAGS_DEFAULT, /* tp_flags */
9394#endif
9395 0, /* tp_doc */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009396 0, /* tp_traverse */
9397 0, /* tp_clear */
9398 0, /* tp_richcompare */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009399 offsetof(DBTxnObject, in_weakreflist), /* tp_weaklistoffset */
9400 0, /*tp_iter*/
9401 0, /*tp_iternext*/
9402 DBTxn_methods, /*tp_methods*/
9403 0, /*tp_members*/
9404};
9405
9406
9407statichere PyTypeObject DBLock_Type = {
9408#if (PY_VERSION_HEX < 0x03000000)
9409 PyObject_HEAD_INIT(NULL)
9410 0, /*ob_size*/
9411#else
9412 PyVarObject_HEAD_INIT(NULL, 0)
9413#endif
9414 "DBLock", /*tp_name*/
9415 sizeof(DBLockObject), /*tp_basicsize*/
9416 0, /*tp_itemsize*/
9417 /* methods */
9418 (destructor)DBLock_dealloc, /*tp_dealloc*/
9419 0, /*tp_print*/
9420 0, /*tp_getattr*/
9421 0, /*tp_setattr*/
9422 0, /*tp_compare*/
9423 0, /*tp_repr*/
9424 0, /*tp_as_number*/
9425 0, /*tp_as_sequence*/
9426 0, /*tp_as_mapping*/
9427 0, /*tp_hash*/
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009428 0, /* tp_call */
9429 0, /* tp_str */
9430 0, /* tp_getattro */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009431 0, /* tp_setattro */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009432 0, /* tp_as_buffer */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009433#if (PY_VERSION_HEX < 0x03000000)
9434 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
9435#else
9436 Py_TPFLAGS_DEFAULT, /* tp_flags */
9437#endif
9438 0, /* tp_doc */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009439 0, /* tp_traverse */
9440 0, /* tp_clear */
9441 0, /* tp_richcompare */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009442 offsetof(DBLockObject, in_weakreflist), /* tp_weaklistoffset */
9443};
9444
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009445statichere PyTypeObject DBSequence_Type = {
9446#if (PY_VERSION_HEX < 0x03000000)
9447 PyObject_HEAD_INIT(NULL)
9448 0, /*ob_size*/
9449#else
9450 PyVarObject_HEAD_INIT(NULL, 0)
9451#endif
9452 "DBSequence", /*tp_name*/
9453 sizeof(DBSequenceObject), /*tp_basicsize*/
9454 0, /*tp_itemsize*/
9455 /* methods */
9456 (destructor)DBSequence_dealloc, /*tp_dealloc*/
9457 0, /*tp_print*/
9458 0, /*tp_getattr*/
9459 0, /*tp_setattr*/
9460 0, /*tp_compare*/
9461 0, /*tp_repr*/
9462 0, /*tp_as_number*/
9463 0, /*tp_as_sequence*/
9464 0, /*tp_as_mapping*/
9465 0, /*tp_hash*/
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009466 0, /* tp_call */
9467 0, /* tp_str */
9468 0, /* tp_getattro */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009469 0, /* tp_setattro */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009470 0, /* tp_as_buffer */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009471#if (PY_VERSION_HEX < 0x03000000)
9472 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
9473#else
9474 Py_TPFLAGS_DEFAULT, /* tp_flags */
9475#endif
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009476 0, /* tp_doc */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009477 0, /* tp_traverse */
9478 0, /* tp_clear */
9479 0, /* tp_richcompare */
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009480 offsetof(DBSequenceObject, in_weakreflist), /* tp_weaklistoffset */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009481 0, /*tp_iter*/
9482 0, /*tp_iternext*/
9483 DBSequence_methods, /*tp_methods*/
9484 0, /*tp_members*/
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009485};
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009486
9487/* --------------------------------------------------------------------- */
9488/* Module-level functions */
9489
9490static PyObject*
9491DB_construct(PyObject* self, PyObject* args, PyObject* kwargs)
9492{
9493 PyObject* dbenvobj = NULL;
9494 int flags = 0;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00009495 static char* kwnames[] = { "dbEnv", "flags", NULL};
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009496
Barry Warsaw9a0d7792002-12-30 20:53:52 +00009497 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Oi:DB", kwnames,
9498 &dbenvobj, &flags))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009499 return NULL;
9500 if (dbenvobj == Py_None)
9501 dbenvobj = NULL;
9502 else if (dbenvobj && !DBEnvObject_Check(dbenvobj)) {
9503 makeTypeError("DBEnv", dbenvobj);
9504 return NULL;
9505 }
9506
9507 return (PyObject* )newDBObject((DBEnvObject*)dbenvobj, flags);
9508}
9509
9510
9511static PyObject*
9512DBEnv_construct(PyObject* self, PyObject* args)
9513{
9514 int flags = 0;
9515 if (!PyArg_ParseTuple(args, "|i:DbEnv", &flags)) return NULL;
9516 return (PyObject* )newDBEnvObject(flags);
9517}
9518
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009519static PyObject*
9520DBSequence_construct(PyObject* self, PyObject* args, PyObject* kwargs)
9521{
Neal Norwitzb4fcf8d2006-06-11 05:44:18 +00009522 PyObject* dbobj;
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009523 int flags = 0;
9524 static char* kwnames[] = { "db", "flags", NULL};
9525
9526 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|i:DBSequence", kwnames, &dbobj, &flags))
9527 return NULL;
Neal Norwitzb4fcf8d2006-06-11 05:44:18 +00009528 if (!DBObject_Check(dbobj)) {
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009529 makeTypeError("DB", dbobj);
9530 return NULL;
9531 }
9532 return (PyObject* )newDBSequenceObject((DBObject*)dbobj, flags);
9533}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009534
9535static char bsddb_version_doc[] =
9536"Returns a tuple of major, minor, and patch release numbers of the\n\
9537underlying DB library.";
9538
9539static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009540bsddb_version(PyObject* self)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009541{
9542 int major, minor, patch;
9543
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009544 /* This should be instantaneous, no need to release the GIL */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009545 db_version(&major, &minor, &patch);
9546 return Py_BuildValue("(iii)", major, minor, patch);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009547}
9548
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009549#if (DBVER >= 50)
9550static PyObject*
9551bsddb_version_full(PyObject* self)
9552{
9553 char *version_string;
9554 int family, release, major, minor, patch;
9555
9556 /* This should be instantaneous, no need to release the GIL */
9557 version_string = db_full_version(&family, &release, &major, &minor, &patch);
9558 return Py_BuildValue("(siiiii)",
9559 version_string, family, release, major, minor, patch);
9560}
9561#endif
9562
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009563
9564/* List of functions defined in the module */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009565static PyMethodDef bsddb_methods[] = {
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009566 {"DB", (PyCFunction)DB_construct, METH_VARARGS | METH_KEYWORDS },
9567 {"DBEnv", (PyCFunction)DBEnv_construct, METH_VARARGS},
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009568 {"DBSequence", (PyCFunction)DBSequence_construct, METH_VARARGS | METH_KEYWORDS },
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009569 {"version", (PyCFunction)bsddb_version, METH_NOARGS, bsddb_version_doc},
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009570#if (DBVER >= 50)
9571 {"full_version", (PyCFunction)bsddb_version_full, METH_NOARGS},
9572#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009573 {NULL, NULL} /* sentinel */
9574};
9575
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009576
Gregory P. Smith39250532007-10-09 06:02:21 +00009577/* API structure */
9578static BSDDB_api bsddb_api;
9579
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009580
9581/* --------------------------------------------------------------------- */
9582/* Module initialization */
9583
9584
9585/* Convenience routine to export an integer value.
9586 * Errors are silently ignored, for better or for worse...
9587 */
9588#define ADD_INT(dict, NAME) _addIntToDict(dict, #NAME, NAME)
9589
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009590/*
9591** We can rename the module at import time, so the string allocated
9592** must be big enough, and any use of the name must use this particular
9593** string.
9594*/
Gregory P. Smith41631e82003-09-21 00:08:14 +00009595#define MODULE_NAME_MAX_LEN 11
9596static char _bsddbModuleName[MODULE_NAME_MAX_LEN+1] = "_bsddb";
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009597
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009598#if (PY_VERSION_HEX >= 0x03000000)
9599static struct PyModuleDef bsddbmodule = {
9600 PyModuleDef_HEAD_INIT,
9601 _bsddbModuleName, /* Name of module */
9602 NULL, /* module documentation, may be NULL */
9603 -1, /* size of per-interpreter state of the module,
9604 or -1 if the module keeps state in global variables. */
9605 bsddb_methods,
9606 NULL, /* Reload */
9607 NULL, /* Traverse */
9608 NULL, /* Clear */
9609 NULL /* Free */
9610};
9611#endif
9612
9613
9614#if (PY_VERSION_HEX < 0x03000000)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009615DL_EXPORT(void) init_bsddb(void)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009616#else
9617PyMODINIT_FUNC PyInit__bsddb(void) /* Note the two underscores */
9618#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009619{
9620 PyObject* m;
9621 PyObject* d;
Gregory P. Smith39250532007-10-09 06:02:21 +00009622 PyObject* py_api;
Jesus Cea6557aac2010-03-22 14:22:26 +00009623 PyObject* pybsddb_version_s;
9624 PyObject* db_version_s;
9625 PyObject* cvsid_s;
9626
9627#if (PY_VERSION_HEX < 0x03000000)
9628 pybsddb_version_s = PyString_FromString(PY_BSDDB_VERSION);
9629 db_version_s = PyString_FromString(DB_VERSION_STRING);
9630 cvsid_s = PyString_FromString(rcs_id);
9631#else
9632 /* This data should be ascii, so UTF-8 conversion is fine */
9633 pybsddb_version_s = PyUnicode_FromString(PY_BSDDB_VERSION);
9634 db_version_s = PyUnicode_FromString(DB_VERSION_STRING);
9635 cvsid_s = PyUnicode_FromString(rcs_id);
9636#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009637
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009638 /* Initialize object types */
9639 if ((PyType_Ready(&DB_Type) < 0)
9640 || (PyType_Ready(&DBCursor_Type) < 0)
Jesus Cea6557aac2010-03-22 14:22:26 +00009641 || (PyType_Ready(&DBLogCursor_Type) < 0)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009642 || (PyType_Ready(&DBEnv_Type) < 0)
9643 || (PyType_Ready(&DBTxn_Type) < 0)
9644 || (PyType_Ready(&DBLock_Type) < 0)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009645 || (PyType_Ready(&DBSequence_Type) < 0)
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009646#if (DBVER >= 52)
9647 || (PyType_Ready(&DBSite_Type) < 0)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009648#endif
9649 ) {
9650#if (PY_VERSION_HEX < 0x03000000)
9651 return;
9652#else
9653 return NULL;
9654#endif
9655 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009656
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009657 /* Create the module and add the functions */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009658#if (PY_VERSION_HEX < 0x03000000)
Gregory P. Smith41631e82003-09-21 00:08:14 +00009659 m = Py_InitModule(_bsddbModuleName, bsddb_methods);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009660#else
9661 m=PyModule_Create(&bsddbmodule);
9662#endif
9663 if (m == NULL) {
9664#if (PY_VERSION_HEX < 0x03000000)
9665 return;
9666#else
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009667 return NULL;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009668#endif
9669 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009670
9671 /* Add some symbolic constants to the module */
9672 d = PyModule_GetDict(m);
9673 PyDict_SetItemString(d, "__version__", pybsddb_version_s);
9674 PyDict_SetItemString(d, "cvsid", cvsid_s);
9675 PyDict_SetItemString(d, "DB_VERSION_STRING", db_version_s);
9676 Py_DECREF(pybsddb_version_s);
9677 pybsddb_version_s = NULL;
9678 Py_DECREF(cvsid_s);
9679 cvsid_s = NULL;
9680 Py_DECREF(db_version_s);
9681 db_version_s = NULL;
9682
9683 ADD_INT(d, DB_VERSION_MAJOR);
9684 ADD_INT(d, DB_VERSION_MINOR);
9685 ADD_INT(d, DB_VERSION_PATCH);
9686
9687 ADD_INT(d, DB_MAX_PAGES);
9688 ADD_INT(d, DB_MAX_RECORDS);
9689
Matthias Klose54cc5392010-03-15 12:46:18 +00009690#if (DBVER < 48)
Gregory P. Smith41631e82003-09-21 00:08:14 +00009691 ADD_INT(d, DB_RPCCLIENT);
Matthias Klose54cc5392010-03-15 12:46:18 +00009692#endif
9693
9694#if (DBVER < 48)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009695 ADD_INT(d, DB_XA_CREATE);
Matthias Klose54cc5392010-03-15 12:46:18 +00009696#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009697
9698 ADD_INT(d, DB_CREATE);
9699 ADD_INT(d, DB_NOMMAP);
9700 ADD_INT(d, DB_THREAD);
Jesus Ceaef9764f2008-05-13 18:45:46 +00009701#if (DBVER >= 45)
9702 ADD_INT(d, DB_MULTIVERSION);
9703#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009704
9705 ADD_INT(d, DB_FORCE);
9706 ADD_INT(d, DB_INIT_CDB);
9707 ADD_INT(d, DB_INIT_LOCK);
9708 ADD_INT(d, DB_INIT_LOG);
9709 ADD_INT(d, DB_INIT_MPOOL);
9710 ADD_INT(d, DB_INIT_TXN);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009711 ADD_INT(d, DB_JOINENV);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009712
Matthias Klose54cc5392010-03-15 12:46:18 +00009713#if (DBVER >= 48)
9714 ADD_INT(d, DB_GID_SIZE);
9715#else
Jesus Ceaef9764f2008-05-13 18:45:46 +00009716 ADD_INT(d, DB_XIDDATASIZE);
Matthias Klose54cc5392010-03-15 12:46:18 +00009717 /* Allow new code to work in old BDB releases */
9718 _addIntToDict(d, "DB_GID_SIZE", DB_XIDDATASIZE);
9719#endif
Jesus Ceaef9764f2008-05-13 18:45:46 +00009720
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009721 ADD_INT(d, DB_RECOVER);
9722 ADD_INT(d, DB_RECOVER_FATAL);
9723 ADD_INT(d, DB_TXN_NOSYNC);
9724 ADD_INT(d, DB_USE_ENVIRON);
9725 ADD_INT(d, DB_USE_ENVIRON_ROOT);
9726
9727 ADD_INT(d, DB_LOCKDOWN);
9728 ADD_INT(d, DB_PRIVATE);
9729 ADD_INT(d, DB_SYSTEM_MEM);
9730
9731 ADD_INT(d, DB_TXN_SYNC);
9732 ADD_INT(d, DB_TXN_NOWAIT);
9733
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009734#if (DBVER >= 51)
9735 ADD_INT(d, DB_TXN_BULK);
9736#endif
9737
9738#if (DBVER >= 48)
9739 ADD_INT(d, DB_CURSOR_BULK);
9740#endif
9741
Jesus Cea6557aac2010-03-22 14:22:26 +00009742#if (DBVER >= 46)
9743 ADD_INT(d, DB_TXN_WAIT);
9744#endif
9745
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009746 ADD_INT(d, DB_EXCL);
9747 ADD_INT(d, DB_FCNTL_LOCKING);
9748 ADD_INT(d, DB_ODDFILESIZE);
9749 ADD_INT(d, DB_RDWRMASTER);
9750 ADD_INT(d, DB_RDONLY);
9751 ADD_INT(d, DB_TRUNCATE);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009752 ADD_INT(d, DB_EXTENT);
9753 ADD_INT(d, DB_CDB_ALLDB);
9754 ADD_INT(d, DB_VERIFY);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009755 ADD_INT(d, DB_UPGRADE);
9756
Jesus Cea6557aac2010-03-22 14:22:26 +00009757 ADD_INT(d, DB_PRINTABLE);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009758 ADD_INT(d, DB_AGGRESSIVE);
9759 ADD_INT(d, DB_NOORDERCHK);
9760 ADD_INT(d, DB_ORDERCHKONLY);
9761 ADD_INT(d, DB_PR_PAGE);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009762
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009763 ADD_INT(d, DB_PR_RECOVERYTEST);
9764 ADD_INT(d, DB_SALVAGE);
9765
9766 ADD_INT(d, DB_LOCK_NORUN);
9767 ADD_INT(d, DB_LOCK_DEFAULT);
9768 ADD_INT(d, DB_LOCK_OLDEST);
9769 ADD_INT(d, DB_LOCK_RANDOM);
9770 ADD_INT(d, DB_LOCK_YOUNGEST);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009771 ADD_INT(d, DB_LOCK_MAXLOCKS);
9772 ADD_INT(d, DB_LOCK_MINLOCKS);
9773 ADD_INT(d, DB_LOCK_MINWRITE);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009774
Jesus Ceaef9764f2008-05-13 18:45:46 +00009775 ADD_INT(d, DB_LOCK_EXPIRE);
Jesus Ceaef9764f2008-05-13 18:45:46 +00009776 ADD_INT(d, DB_LOCK_MAXWRITE);
Jesus Ceaef9764f2008-05-13 18:45:46 +00009777
Barry Warsaw9a0d7792002-12-30 20:53:52 +00009778 _addIntToDict(d, "DB_LOCK_CONFLICT", 0);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009779
9780 ADD_INT(d, DB_LOCK_DUMP);
9781 ADD_INT(d, DB_LOCK_GET);
9782 ADD_INT(d, DB_LOCK_INHERIT);
9783 ADD_INT(d, DB_LOCK_PUT);
9784 ADD_INT(d, DB_LOCK_PUT_ALL);
9785 ADD_INT(d, DB_LOCK_PUT_OBJ);
9786
9787 ADD_INT(d, DB_LOCK_NG);
9788 ADD_INT(d, DB_LOCK_READ);
9789 ADD_INT(d, DB_LOCK_WRITE);
9790 ADD_INT(d, DB_LOCK_NOWAIT);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009791 ADD_INT(d, DB_LOCK_WAIT);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009792 ADD_INT(d, DB_LOCK_IWRITE);
9793 ADD_INT(d, DB_LOCK_IREAD);
9794 ADD_INT(d, DB_LOCK_IWR);
Gregory P. Smith29602d22006-01-24 09:46:48 +00009795#if (DBVER < 44)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009796 ADD_INT(d, DB_LOCK_DIRTY);
Gregory P. Smith29602d22006-01-24 09:46:48 +00009797#else
9798 ADD_INT(d, DB_LOCK_READ_UNCOMMITTED); /* renamed in 4.4 */
9799#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009800 ADD_INT(d, DB_LOCK_WWRITE);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009801
9802 ADD_INT(d, DB_LOCK_RECORD);
9803 ADD_INT(d, DB_LOCK_UPGRADE);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009804 ADD_INT(d, DB_LOCK_SWITCH);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009805 ADD_INT(d, DB_LOCK_UPGRADE_WRITE);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009806
9807 ADD_INT(d, DB_LOCK_NOWAIT);
9808 ADD_INT(d, DB_LOCK_RECORD);
9809 ADD_INT(d, DB_LOCK_UPGRADE);
9810
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009811 ADD_INT(d, DB_LSTAT_ABORTED);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009812 ADD_INT(d, DB_LSTAT_FREE);
9813 ADD_INT(d, DB_LSTAT_HELD);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009814
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009815 ADD_INT(d, DB_LSTAT_PENDING);
9816 ADD_INT(d, DB_LSTAT_WAITING);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009817
9818 ADD_INT(d, DB_ARCH_ABS);
9819 ADD_INT(d, DB_ARCH_DATA);
9820 ADD_INT(d, DB_ARCH_LOG);
Gregory P. Smith3dd20022006-06-05 00:31:01 +00009821 ADD_INT(d, DB_ARCH_REMOVE);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009822
9823 ADD_INT(d, DB_BTREE);
9824 ADD_INT(d, DB_HASH);
9825 ADD_INT(d, DB_RECNO);
9826 ADD_INT(d, DB_QUEUE);
9827 ADD_INT(d, DB_UNKNOWN);
9828
9829 ADD_INT(d, DB_DUP);
9830 ADD_INT(d, DB_DUPSORT);
9831 ADD_INT(d, DB_RECNUM);
9832 ADD_INT(d, DB_RENUMBER);
9833 ADD_INT(d, DB_REVSPLITOFF);
9834 ADD_INT(d, DB_SNAPSHOT);
9835
Jesus Cea6557aac2010-03-22 14:22:26 +00009836 ADD_INT(d, DB_INORDER);
Jesus Cea6557aac2010-03-22 14:22:26 +00009837
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009838 ADD_INT(d, DB_JOIN_NOSORT);
9839
9840 ADD_INT(d, DB_AFTER);
9841 ADD_INT(d, DB_APPEND);
9842 ADD_INT(d, DB_BEFORE);
Gregory P. Smith8b96a352007-01-05 01:59:42 +00009843#if (DBVER < 45)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009844 ADD_INT(d, DB_CACHED_COUNTS);
Gregory P. Smith8b96a352007-01-05 01:59:42 +00009845#endif
Jesus Ceaca3939c2008-05-22 15:27:38 +00009846
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009847 ADD_INT(d, DB_CONSUME);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009848 ADD_INT(d, DB_CONSUME_WAIT);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009849 ADD_INT(d, DB_CURRENT);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009850 ADD_INT(d, DB_FAST_STAT);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009851 ADD_INT(d, DB_FIRST);
9852 ADD_INT(d, DB_FLUSH);
9853 ADD_INT(d, DB_GET_BOTH);
Jesus Cea6557aac2010-03-22 14:22:26 +00009854 ADD_INT(d, DB_GET_BOTH_RANGE);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009855 ADD_INT(d, DB_GET_RECNO);
9856 ADD_INT(d, DB_JOIN_ITEM);
9857 ADD_INT(d, DB_KEYFIRST);
9858 ADD_INT(d, DB_KEYLAST);
9859 ADD_INT(d, DB_LAST);
9860 ADD_INT(d, DB_NEXT);
9861 ADD_INT(d, DB_NEXT_DUP);
9862 ADD_INT(d, DB_NEXT_NODUP);
9863 ADD_INT(d, DB_NODUPDATA);
9864 ADD_INT(d, DB_NOOVERWRITE);
9865 ADD_INT(d, DB_NOSYNC);
9866 ADD_INT(d, DB_POSITION);
9867 ADD_INT(d, DB_PREV);
9868 ADD_INT(d, DB_PREV_NODUP);
Jesus Cea6557aac2010-03-22 14:22:26 +00009869#if (DBVER >= 46)
9870 ADD_INT(d, DB_PREV_DUP);
9871#endif
Gregory P. Smith8b96a352007-01-05 01:59:42 +00009872#if (DBVER < 45)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009873 ADD_INT(d, DB_RECORDCOUNT);
Gregory P. Smith8b96a352007-01-05 01:59:42 +00009874#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009875 ADD_INT(d, DB_SET);
9876 ADD_INT(d, DB_SET_RANGE);
9877 ADD_INT(d, DB_SET_RECNO);
9878 ADD_INT(d, DB_WRITECURSOR);
9879
9880 ADD_INT(d, DB_OPFLAGS_MASK);
9881 ADD_INT(d, DB_RMW);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009882 ADD_INT(d, DB_DIRTY_READ);
9883 ADD_INT(d, DB_MULTIPLE);
9884 ADD_INT(d, DB_MULTIPLE_KEY);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009885
Gregory P. Smith29602d22006-01-24 09:46:48 +00009886#if (DBVER >= 44)
Jesus Cea6557aac2010-03-22 14:22:26 +00009887 ADD_INT(d, DB_IMMUTABLE_KEY);
Gregory P. Smith29602d22006-01-24 09:46:48 +00009888 ADD_INT(d, DB_READ_UNCOMMITTED); /* replaces DB_DIRTY_READ in 4.4 */
9889 ADD_INT(d, DB_READ_COMMITTED);
9890#endif
9891
Jesus Cea6557aac2010-03-22 14:22:26 +00009892#if (DBVER >= 44)
9893 ADD_INT(d, DB_FREELIST_ONLY);
9894 ADD_INT(d, DB_FREE_SPACE);
9895#endif
9896
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009897 ADD_INT(d, DB_DONOTINDEX);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009898
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009899 ADD_INT(d, DB_KEYEMPTY);
9900 ADD_INT(d, DB_KEYEXIST);
9901 ADD_INT(d, DB_LOCK_DEADLOCK);
9902 ADD_INT(d, DB_LOCK_NOTGRANTED);
9903 ADD_INT(d, DB_NOSERVER);
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009904#if (DBVER < 52)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009905 ADD_INT(d, DB_NOSERVER_HOME);
9906 ADD_INT(d, DB_NOSERVER_ID);
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009907#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009908 ADD_INT(d, DB_NOTFOUND);
9909 ADD_INT(d, DB_OLD_VERSION);
9910 ADD_INT(d, DB_RUNRECOVERY);
9911 ADD_INT(d, DB_VERIFY_BAD);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009912 ADD_INT(d, DB_PAGE_NOTFOUND);
9913 ADD_INT(d, DB_SECONDARY_BAD);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009914 ADD_INT(d, DB_STAT_CLEAR);
9915 ADD_INT(d, DB_REGION_INIT);
9916 ADD_INT(d, DB_NOLOCKING);
9917 ADD_INT(d, DB_YIELDCPU);
9918 ADD_INT(d, DB_PANIC_ENVIRONMENT);
9919 ADD_INT(d, DB_NOPANIC);
Jesus Ceaef9764f2008-05-13 18:45:46 +00009920 ADD_INT(d, DB_OVERWRITE);
Jesus Cea6557aac2010-03-22 14:22:26 +00009921
Jesus Cea6557aac2010-03-22 14:22:26 +00009922 ADD_INT(d, DB_STAT_SUBSYSTEM);
9923 ADD_INT(d, DB_STAT_MEMP_HASH);
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009924 ADD_INT(d, DB_STAT_LOCK_CONF);
9925 ADD_INT(d, DB_STAT_LOCK_LOCKERS);
9926 ADD_INT(d, DB_STAT_LOCK_OBJECTS);
9927 ADD_INT(d, DB_STAT_LOCK_PARAMS);
Jesus Ceaef9764f2008-05-13 18:45:46 +00009928
Jesus Cea6557aac2010-03-22 14:22:26 +00009929#if (DBVER >= 48)
9930 ADD_INT(d, DB_OVERWRITE_DUP);
9931#endif
9932
9933#if (DBVER >= 47)
9934 ADD_INT(d, DB_FOREIGN_ABORT);
9935 ADD_INT(d, DB_FOREIGN_CASCADE);
9936 ADD_INT(d, DB_FOREIGN_NULLIFY);
9937#endif
9938
9939#if (DBVER >= 44)
Gregory P. Smithaae141a2007-11-01 21:08:14 +00009940 ADD_INT(d, DB_REGISTER);
9941#endif
9942
Jesus Cea6557aac2010-03-22 14:22:26 +00009943 ADD_INT(d, DB_EID_INVALID);
9944 ADD_INT(d, DB_EID_BROADCAST);
9945
Gregory P. Smith41631e82003-09-21 00:08:14 +00009946 ADD_INT(d, DB_TIME_NOTGRANTED);
9947 ADD_INT(d, DB_TXN_NOT_DURABLE);
9948 ADD_INT(d, DB_TXN_WRITE_NOSYNC);
Gregory P. Smith41631e82003-09-21 00:08:14 +00009949 ADD_INT(d, DB_DIRECT_DB);
9950 ADD_INT(d, DB_INIT_REP);
9951 ADD_INT(d, DB_ENCRYPT);
9952 ADD_INT(d, DB_CHKSUM);
Gregory P. Smith41631e82003-09-21 00:08:14 +00009953
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009954#if (DBVER < 47)
Jesus Ceaca3939c2008-05-22 15:27:38 +00009955 ADD_INT(d, DB_LOG_AUTOREMOVE);
9956 ADD_INT(d, DB_DIRECT_LOG);
9957#endif
9958
9959#if (DBVER >= 47)
9960 ADD_INT(d, DB_LOG_DIRECT);
9961 ADD_INT(d, DB_LOG_DSYNC);
9962 ADD_INT(d, DB_LOG_IN_MEMORY);
9963 ADD_INT(d, DB_LOG_AUTO_REMOVE);
9964 ADD_INT(d, DB_LOG_ZERO);
9965#endif
9966
Jesus Ceaef9764f2008-05-13 18:45:46 +00009967#if (DBVER >= 44)
9968 ADD_INT(d, DB_DSYNC_DB);
9969#endif
9970
9971#if (DBVER >= 45)
9972 ADD_INT(d, DB_TXN_SNAPSHOT);
9973#endif
9974
Jesus Ceaef9764f2008-05-13 18:45:46 +00009975 ADD_INT(d, DB_VERB_DEADLOCK);
9976#if (DBVER >= 46)
9977 ADD_INT(d, DB_VERB_FILEOPS);
9978 ADD_INT(d, DB_VERB_FILEOPS_ALL);
9979#endif
9980 ADD_INT(d, DB_VERB_RECOVERY);
9981#if (DBVER >= 44)
9982 ADD_INT(d, DB_VERB_REGISTER);
9983#endif
9984 ADD_INT(d, DB_VERB_REPLICATION);
9985 ADD_INT(d, DB_VERB_WAITSFOR);
Jesus Ceaef9764f2008-05-13 18:45:46 +00009986
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009987#if (DBVER >= 50)
9988 ADD_INT(d, DB_VERB_REP_SYSTEM);
9989#endif
9990
9991#if (DBVER >= 47)
9992 ADD_INT(d, DB_VERB_REP_ELECT);
9993 ADD_INT(d, DB_VERB_REP_LEASE);
9994 ADD_INT(d, DB_VERB_REP_MISC);
9995 ADD_INT(d, DB_VERB_REP_MSGS);
9996 ADD_INT(d, DB_VERB_REP_SYNC);
9997 ADD_INT(d, DB_VERB_REPMGR_CONNFAIL);
9998 ADD_INT(d, DB_VERB_REPMGR_MISC);
9999#endif
10000
Jesus Ceaef9764f2008-05-13 18:45:46 +000010001#if (DBVER >= 45)
10002 ADD_INT(d, DB_EVENT_PANIC);
10003 ADD_INT(d, DB_EVENT_REP_CLIENT);
10004#if (DBVER >= 46)
10005 ADD_INT(d, DB_EVENT_REP_ELECTED);
10006#endif
10007 ADD_INT(d, DB_EVENT_REP_MASTER);
10008 ADD_INT(d, DB_EVENT_REP_NEWMASTER);
10009#if (DBVER >= 46)
10010 ADD_INT(d, DB_EVENT_REP_PERM_FAILED);
10011#endif
10012 ADD_INT(d, DB_EVENT_REP_STARTUPDONE);
10013 ADD_INT(d, DB_EVENT_WRITE_FAILED);
10014#endif
10015
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010016#if (DBVER >= 50)
10017 ADD_INT(d, DB_REPMGR_CONF_ELECTIONS);
10018 ADD_INT(d, DB_EVENT_REP_MASTER_FAILURE);
10019 ADD_INT(d, DB_EVENT_REP_DUPMASTER);
10020 ADD_INT(d, DB_EVENT_REP_ELECTION_FAILED);
10021#endif
10022#if (DBVER >= 48)
10023 ADD_INT(d, DB_EVENT_REG_ALIVE);
10024 ADD_INT(d, DB_EVENT_REG_PANIC);
10025#endif
10026
10027#if (DBVER >=52)
10028 ADD_INT(d, DB_EVENT_REP_SITE_ADDED);
10029 ADD_INT(d, DB_EVENT_REP_SITE_REMOVED);
10030 ADD_INT(d, DB_EVENT_REP_LOCAL_SITE_REMOVED);
10031 ADD_INT(d, DB_EVENT_REP_CONNECT_BROKEN);
10032 ADD_INT(d, DB_EVENT_REP_CONNECT_ESTD);
10033 ADD_INT(d, DB_EVENT_REP_CONNECT_TRY_FAILED);
10034 ADD_INT(d, DB_EVENT_REP_INIT_DONE);
10035
10036 ADD_INT(d, DB_MEM_LOCK);
10037 ADD_INT(d, DB_MEM_LOCKOBJECT);
10038 ADD_INT(d, DB_MEM_LOCKER);
10039 ADD_INT(d, DB_MEM_LOGID);
10040 ADD_INT(d, DB_MEM_TRANSACTION);
10041 ADD_INT(d, DB_MEM_THREAD);
10042
10043 ADD_INT(d, DB_BOOTSTRAP_HELPER);
10044 ADD_INT(d, DB_GROUP_CREATOR);
10045 ADD_INT(d, DB_LEGACY);
10046 ADD_INT(d, DB_LOCAL_SITE);
10047 ADD_INT(d, DB_REPMGR_PEER);
10048#endif
10049
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010050 ADD_INT(d, DB_REP_DUPMASTER);
10051 ADD_INT(d, DB_REP_HOLDELECTION);
10052#if (DBVER >= 44)
10053 ADD_INT(d, DB_REP_IGNORE);
10054 ADD_INT(d, DB_REP_JOIN_FAILURE);
10055#endif
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010056 ADD_INT(d, DB_REP_ISPERM);
10057 ADD_INT(d, DB_REP_NOTPERM);
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010058 ADD_INT(d, DB_REP_NEWSITE);
10059
Jesus Ceaef9764f2008-05-13 18:45:46 +000010060 ADD_INT(d, DB_REP_MASTER);
10061 ADD_INT(d, DB_REP_CLIENT);
Jesus Cea6557aac2010-03-22 14:22:26 +000010062
10063 ADD_INT(d, DB_REP_PERMANENT);
10064
10065#if (DBVER >= 44)
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010066#if (DBVER >= 50)
10067 ADD_INT(d, DB_REP_CONF_AUTOINIT);
10068#else
Jesus Cea6557aac2010-03-22 14:22:26 +000010069 ADD_INT(d, DB_REP_CONF_NOAUTOINIT);
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010070#endif /* 5.0 */
10071#endif /* 4.4 */
10072#if (DBVER >= 44)
Jesus Cea6557aac2010-03-22 14:22:26 +000010073 ADD_INT(d, DB_REP_CONF_DELAYCLIENT);
10074 ADD_INT(d, DB_REP_CONF_BULK);
10075 ADD_INT(d, DB_REP_CONF_NOWAIT);
10076 ADD_INT(d, DB_REP_ANYWHERE);
10077 ADD_INT(d, DB_REP_REREQUEST);
10078#endif
10079
Jesus Cea6557aac2010-03-22 14:22:26 +000010080 ADD_INT(d, DB_REP_NOBUFFER);
Jesus Cea6557aac2010-03-22 14:22:26 +000010081
10082#if (DBVER >= 46)
10083 ADD_INT(d, DB_REP_LEASE_EXPIRED);
10084 ADD_INT(d, DB_IGNORE_LEASE);
10085#endif
10086
10087#if (DBVER >= 47)
10088 ADD_INT(d, DB_REP_CONF_LEASE);
10089 ADD_INT(d, DB_REPMGR_CONF_2SITE_STRICT);
10090#endif
10091
Jesus Ceaef9764f2008-05-13 18:45:46 +000010092#if (DBVER >= 45)
10093 ADD_INT(d, DB_REP_ELECTION);
10094
10095 ADD_INT(d, DB_REP_ACK_TIMEOUT);
10096 ADD_INT(d, DB_REP_CONNECTION_RETRY);
10097 ADD_INT(d, DB_REP_ELECTION_TIMEOUT);
10098 ADD_INT(d, DB_REP_ELECTION_RETRY);
10099#endif
10100#if (DBVER >= 46)
10101 ADD_INT(d, DB_REP_CHECKPOINT_DELAY);
10102 ADD_INT(d, DB_REP_FULL_ELECTION_TIMEOUT);
Jesus Cea6557aac2010-03-22 14:22:26 +000010103 ADD_INT(d, DB_REP_LEASE_TIMEOUT);
10104#endif
10105#if (DBVER >= 47)
10106 ADD_INT(d, DB_REP_HEARTBEAT_MONITOR);
10107 ADD_INT(d, DB_REP_HEARTBEAT_SEND);
Jesus Ceaef9764f2008-05-13 18:45:46 +000010108#endif
Jesus Ceaef9764f2008-05-13 18:45:46 +000010109
10110#if (DBVER >= 45)
10111 ADD_INT(d, DB_REPMGR_PEER);
10112 ADD_INT(d, DB_REPMGR_ACKS_ALL);
10113 ADD_INT(d, DB_REPMGR_ACKS_ALL_PEERS);
10114 ADD_INT(d, DB_REPMGR_ACKS_NONE);
10115 ADD_INT(d, DB_REPMGR_ACKS_ONE);
10116 ADD_INT(d, DB_REPMGR_ACKS_ONE_PEER);
10117 ADD_INT(d, DB_REPMGR_ACKS_QUORUM);
10118 ADD_INT(d, DB_REPMGR_CONNECTED);
10119 ADD_INT(d, DB_REPMGR_DISCONNECTED);
Jesus Ceaef9764f2008-05-13 18:45:46 +000010120 ADD_INT(d, DB_STAT_ALL);
10121#endif
10122
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010123#if (DBVER >= 51)
10124 ADD_INT(d, DB_REPMGR_ACKS_ALL_AVAILABLE);
10125#endif
10126
10127#if (DBVER >= 48)
10128 ADD_INT(d, DB_REP_CONF_INMEM);
10129#endif
10130
10131 ADD_INT(d, DB_TIMEOUT);
10132
10133#if (DBVER >= 50)
10134 ADD_INT(d, DB_FORCESYNC);
10135#endif
10136
10137#if (DBVER >= 48)
10138 ADD_INT(d, DB_FAILCHK);
10139#endif
10140
10141#if (DBVER >= 51)
10142 ADD_INT(d, DB_HOTBACKUP_IN_PROGRESS);
10143#endif
10144
Gregory P. Smith8b7e9172004-12-13 09:51:23 +000010145 ADD_INT(d, DB_BUFFER_SMALL);
Gregory P. Smithf0547d02006-06-05 17:38:04 +000010146 ADD_INT(d, DB_SEQ_DEC);
10147 ADD_INT(d, DB_SEQ_INC);
10148 ADD_INT(d, DB_SEQ_WRAP);
Gregory P. Smith8b7e9172004-12-13 09:51:23 +000010149
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010150#if (DBVER < 47)
Jesus Ceaca3939c2008-05-22 15:27:38 +000010151 ADD_INT(d, DB_LOG_INMEMORY);
10152 ADD_INT(d, DB_DSYNC_LOG);
10153#endif
10154
Barry Warsaw9a0d7792002-12-30 20:53:52 +000010155 ADD_INT(d, DB_ENCRYPT_AES);
10156 ADD_INT(d, DB_AUTO_COMMIT);
Jesus Cea6557aac2010-03-22 14:22:26 +000010157 ADD_INT(d, DB_PRIORITY_VERY_LOW);
10158 ADD_INT(d, DB_PRIORITY_LOW);
10159 ADD_INT(d, DB_PRIORITY_DEFAULT);
10160 ADD_INT(d, DB_PRIORITY_HIGH);
10161 ADD_INT(d, DB_PRIORITY_VERY_HIGH);
10162
10163#if (DBVER >= 46)
10164 ADD_INT(d, DB_PRIORITY_UNCHANGED);
Barry Warsaw9a0d7792002-12-30 20:53:52 +000010165#endif
10166
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010167 ADD_INT(d, EINVAL);
10168 ADD_INT(d, EACCES);
10169 ADD_INT(d, ENOSPC);
10170 ADD_INT(d, ENOMEM);
10171 ADD_INT(d, EAGAIN);
10172 ADD_INT(d, EBUSY);
10173 ADD_INT(d, EEXIST);
10174 ADD_INT(d, ENOENT);
10175 ADD_INT(d, EPERM);
10176
Barry Warsaw1baa9822003-03-31 19:51:29 +000010177 ADD_INT(d, DB_SET_LOCK_TIMEOUT);
10178 ADD_INT(d, DB_SET_TXN_TIMEOUT);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010179
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010180#if (DBVER >= 48)
10181 ADD_INT(d, DB_SET_REG_TIMEOUT);
10182#endif
10183
Gregory P. Smith7f5b6f42006-04-08 07:10:51 +000010184 /* The exception name must be correct for pickled exception *
10185 * objects to unpickle properly. */
10186#ifdef PYBSDDB_STANDALONE /* different value needed for standalone pybsddb */
10187#define PYBSDDB_EXCEPTION_BASE "bsddb3.db."
10188#else
10189#define PYBSDDB_EXCEPTION_BASE "bsddb.db."
10190#endif
10191
10192 /* All the rest of the exceptions derive only from DBError */
10193#define MAKE_EX(name) name = PyErr_NewException(PYBSDDB_EXCEPTION_BASE #name, DBError, NULL); \
10194 PyDict_SetItemString(d, #name, name)
10195
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010196 /* The base exception class is DBError */
Gregory P. Smith7f5b6f42006-04-08 07:10:51 +000010197 DBError = NULL; /* used in MAKE_EX so that it derives from nothing */
10198 MAKE_EX(DBError);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010199
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010200#if (PY_VERSION_HEX < 0x03000000)
Gregory P. Smithe9477062005-06-04 06:46:59 +000010201 /* Some magic to make DBNotFoundError and DBKeyEmptyError derive
10202 * from both DBError and KeyError, since the API only supports
10203 * using one base class. */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010204 PyDict_SetItemString(d, "KeyError", PyExc_KeyError);
Gregory P. Smithe9477062005-06-04 06:46:59 +000010205 PyRun_String("class DBNotFoundError(DBError, KeyError): pass\n"
Antoine Pitrouc83ea132010-05-09 14:46:46 +000010206 "class DBKeyEmptyError(DBError, KeyError): pass",
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010207 Py_file_input, d, d);
10208 DBNotFoundError = PyDict_GetItemString(d, "DBNotFoundError");
Gregory P. Smithe9477062005-06-04 06:46:59 +000010209 DBKeyEmptyError = PyDict_GetItemString(d, "DBKeyEmptyError");
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010210 PyDict_DelItemString(d, "KeyError");
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010211#else
10212 /* Since Python 2.5, PyErr_NewException() accepts a tuple, to be able to
10213 ** derive from several classes. We use this new API only for Python 3.0,
10214 ** though.
10215 */
10216 {
10217 PyObject* bases;
10218
10219 bases = PyTuple_Pack(2, DBError, PyExc_KeyError);
10220
10221#define MAKE_EX2(name) name = PyErr_NewException(PYBSDDB_EXCEPTION_BASE #name, bases, NULL); \
10222 PyDict_SetItemString(d, #name, name)
10223 MAKE_EX2(DBNotFoundError);
10224 MAKE_EX2(DBKeyEmptyError);
10225
10226#undef MAKE_EX2
10227
10228 Py_XDECREF(bases);
10229 }
10230#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010231
Gregory P. Smithe2767172003-11-02 08:06:29 +000010232 MAKE_EX(DBCursorClosedError);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010233 MAKE_EX(DBKeyExistError);
10234 MAKE_EX(DBLockDeadlockError);
10235 MAKE_EX(DBLockNotGrantedError);
10236 MAKE_EX(DBOldVersionError);
10237 MAKE_EX(DBRunRecoveryError);
10238 MAKE_EX(DBVerifyBadError);
10239 MAKE_EX(DBNoServerError);
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010240#if (DBVER < 52)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010241 MAKE_EX(DBNoServerHomeError);
10242 MAKE_EX(DBNoServerIDError);
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010243#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010244 MAKE_EX(DBPageNotFoundError);
10245 MAKE_EX(DBSecondaryBadError);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010246
10247 MAKE_EX(DBInvalidArgError);
10248 MAKE_EX(DBAccessError);
10249 MAKE_EX(DBNoSpaceError);
10250 MAKE_EX(DBNoMemoryError);
10251 MAKE_EX(DBAgainError);
10252 MAKE_EX(DBBusyError);
10253 MAKE_EX(DBFileExistsError);
10254 MAKE_EX(DBNoSuchFileError);
10255 MAKE_EX(DBPermissionsError);
10256
Jesus Ceaef9764f2008-05-13 18:45:46 +000010257 MAKE_EX(DBRepHandleDeadError);
Jesus Cea6557aac2010-03-22 14:22:26 +000010258#if (DBVER >= 44)
10259 MAKE_EX(DBRepLockoutError);
10260#endif
Jesus Ceaef9764f2008-05-13 18:45:46 +000010261
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010262 MAKE_EX(DBRepUnavailError);
10263
Jesus Cea6557aac2010-03-22 14:22:26 +000010264#if (DBVER >= 46)
10265 MAKE_EX(DBRepLeaseExpiredError);
10266#endif
10267
10268#if (DBVER >= 47)
10269 MAKE_EX(DBForeignConflictError);
10270#endif
10271
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010272#undef MAKE_EX
10273
Jesus Cea6557aac2010-03-22 14:22:26 +000010274 /* Initialise the C API structure and add it to the module */
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010275 bsddb_api.api_version = PYBSDDB_API_VERSION;
Jesus Cea6557aac2010-03-22 14:22:26 +000010276 bsddb_api.db_type = &DB_Type;
10277 bsddb_api.dbcursor_type = &DBCursor_Type;
10278 bsddb_api.dblogcursor_type = &DBLogCursor_Type;
10279 bsddb_api.dbenv_type = &DBEnv_Type;
10280 bsddb_api.dbtxn_type = &DBTxn_Type;
10281 bsddb_api.dblock_type = &DBLock_Type;
Jesus Cea6557aac2010-03-22 14:22:26 +000010282 bsddb_api.dbsequence_type = &DBSequence_Type;
Jesus Cea6557aac2010-03-22 14:22:26 +000010283 bsddb_api.makeDBError = makeDBError;
Gregory P. Smith39250532007-10-09 06:02:21 +000010284
Jesus Cea6557aac2010-03-22 14:22:26 +000010285 /*
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010286 ** Capsules exist from Python 2.7 and 3.1.
10287 ** We don't support Python 3.0 anymore, so...
10288 ** #if (PY_VERSION_HEX < ((PY_MAJOR_VERSION < 3) ? 0x02070000 : 0x03020000))
Jesus Cea6557aac2010-03-22 14:22:26 +000010289 */
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010290#if (PY_VERSION_HEX < 0x02070000)
Gregory P. Smith39250532007-10-09 06:02:21 +000010291 py_api = PyCObject_FromVoidPtr((void*)&bsddb_api, NULL);
Jesus Cea6557aac2010-03-22 14:22:26 +000010292#else
10293 {
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010294 /*
10295 ** The data must outlive the call!!. So, the static definition.
10296 ** The buffer must be big enough...
10297 */
10298 static char py_api_name[MODULE_NAME_MAX_LEN+10];
Jesus Cea6557aac2010-03-22 14:22:26 +000010299
10300 strcpy(py_api_name, _bsddbModuleName);
10301 strcat(py_api_name, ".api");
10302
10303 py_api = PyCapsule_New((void*)&bsddb_api, py_api_name, NULL);
10304 }
10305#endif
10306
Jesus Cea84f2c322010-11-05 00:13:50 +000010307 /* Check error control */
10308 /*
10309 ** PyErr_NoMemory();
10310 ** py_api = NULL;
10311 */
10312
10313 if (py_api) {
10314 PyDict_SetItemString(d, "api", py_api);
10315 Py_DECREF(py_api);
10316 } else { /* Something bad happened */
10317 PyErr_WriteUnraisable(m);
Jesus Ceabf088f82010-11-08 12:57:59 +000010318 if(PyErr_Warn(PyExc_RuntimeWarning,
10319 "_bsddb/_pybsddb C API will be not available")) {
10320 PyErr_WriteUnraisable(m);
10321 }
Jesus Cea84f2c322010-11-05 00:13:50 +000010322 PyErr_Clear();
10323 }
Gregory P. Smith39250532007-10-09 06:02:21 +000010324
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010325 /* Check for errors */
10326 if (PyErr_Occurred()) {
10327 PyErr_Print();
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010328 Py_FatalError("can't initialize module _bsddb/_pybsddb");
10329 Py_DECREF(m);
10330 m = NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010331 }
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010332#if (PY_VERSION_HEX < 0x03000000)
10333 return;
10334#else
10335 return m;
10336#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010337}
Gregory P. Smith41631e82003-09-21 00:08:14 +000010338
10339/* allow this module to be named _pybsddb so that it can be installed
10340 * and imported on top of python >= 2.3 that includes its own older
10341 * copy of the library named _bsddb without importing the old version. */
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010342#if (PY_VERSION_HEX < 0x03000000)
Gregory P. Smith41631e82003-09-21 00:08:14 +000010343DL_EXPORT(void) init_pybsddb(void)
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010344#else
10345PyMODINIT_FUNC PyInit__pybsddb(void) /* Note the two underscores */
10346#endif
Gregory P. Smith41631e82003-09-21 00:08:14 +000010347{
10348 strncpy(_bsddbModuleName, "_pybsddb", MODULE_NAME_MAX_LEN);
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010349#if (PY_VERSION_HEX < 0x03000000)
Gregory P. Smith41631e82003-09-21 00:08:14 +000010350 init_bsddb();
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010351#else
10352 return PyInit__bsddb(); /* Note the two underscores */
10353#endif
Gregory P. Smith41631e82003-09-21 00:08:14 +000010354}