blob: d99df4bd2cd2056a2d0a248d2621081492add210 [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 *
Gregory P. Smithf0547d02006-06-05 17:38:04 +000067 * This module contains 6 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)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000075 *
Jesus Cea6557aac2010-03-22 14:22:26 +000076 * More datatypes added:
77 *
78 * DBLogCursor (Log Cursor)
79 *
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000080 */
81
82/* --------------------------------------------------------------------- */
83
84/*
85 * Portions of this module, associated unit tests and build scripts are the
86 * result of a contract with The Written Word (http://thewrittenword.com/)
87 * Many thanks go out to them for causing me to raise the bar on quality and
88 * functionality, resulting in a better bsddb3 package for all of us to use.
89 *
90 * --Robin
91 */
92
93/* --------------------------------------------------------------------- */
94
Gregory P. Smitha703a212003-11-03 01:04:41 +000095#include <stddef.h> /* for offsetof() */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000096#include <Python.h>
Gregory P. Smith39250532007-10-09 06:02:21 +000097
98#define COMPILING_BSDDB_C
99#include "bsddb.h"
100#undef COMPILING_BSDDB_C
101
102static char *rcs_id = "$Id$";
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000103
104/* --------------------------------------------------------------------- */
105/* Various macro definitions */
106
Gregory P. Smith7f5b6f42006-04-08 07:10:51 +0000107#if (PY_VERSION_HEX < 0x02050000)
Neal Norwitz09a29fa2006-06-12 02:05:55 +0000108typedef int Py_ssize_t;
Gregory P. Smith7f5b6f42006-04-08 07:10:51 +0000109#endif
110
Gregory P. Smith572226c2008-05-26 19:03:35 +0000111#if (PY_VERSION_HEX < 0x02060000) /* really: before python trunk r63675 */
112/* This code now uses PyBytes* API function names instead of PyString*.
113 * These #defines map to their equivalent on earlier python versions. */
114#define PyBytes_FromStringAndSize PyString_FromStringAndSize
115#define PyBytes_FromString PyString_FromString
116#define PyBytes_AsStringAndSize PyString_AsStringAndSize
117#define PyBytes_Check PyString_Check
118#define PyBytes_GET_SIZE PyString_GET_SIZE
119#define PyBytes_AS_STRING PyString_AS_STRING
120#endif
121
Jesus Ceac5a11fa2008-07-23 11:38:42 +0000122#if (PY_VERSION_HEX >= 0x03000000)
123#define NUMBER_Check PyLong_Check
124#define NUMBER_AsLong PyLong_AsLong
125#define NUMBER_FromLong PyLong_FromLong
126#else
127#define NUMBER_Check PyInt_Check
128#define NUMBER_AsLong PyInt_AsLong
129#define NUMBER_FromLong PyInt_FromLong
130#endif
131
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000132#ifdef WITH_THREAD
133
134/* These are for when calling Python --> C */
135#define MYDB_BEGIN_ALLOW_THREADS Py_BEGIN_ALLOW_THREADS;
136#define MYDB_END_ALLOW_THREADS Py_END_ALLOW_THREADS;
137
Mark Hammonda69d4092003-04-22 23:13:27 +0000138/* For 2.3, use the PyGILState_ calls */
139#if (PY_VERSION_HEX >= 0x02030000)
140#define MYDB_USE_GILSTATE
141#endif
142
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000143/* and these are for calling C --> Python */
Mark Hammonda69d4092003-04-22 23:13:27 +0000144#if defined(MYDB_USE_GILSTATE)
145#define MYDB_BEGIN_BLOCK_THREADS \
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000146 PyGILState_STATE __savestate = PyGILState_Ensure();
Mark Hammonda69d4092003-04-22 23:13:27 +0000147#define MYDB_END_BLOCK_THREADS \
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000148 PyGILState_Release(__savestate);
Mark Hammonda69d4092003-04-22 23:13:27 +0000149#else /* MYDB_USE_GILSTATE */
150/* Pre GILState API - do it the long old way */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000151static PyInterpreterState* _db_interpreterState = NULL;
152#define MYDB_BEGIN_BLOCK_THREADS { \
153 PyThreadState* prevState; \
154 PyThreadState* newState; \
155 PyEval_AcquireLock(); \
156 newState = PyThreadState_New(_db_interpreterState); \
157 prevState = PyThreadState_Swap(newState);
158
159#define MYDB_END_BLOCK_THREADS \
160 newState = PyThreadState_Swap(prevState); \
161 PyThreadState_Clear(newState); \
162 PyEval_ReleaseLock(); \
163 PyThreadState_Delete(newState); \
164 }
Mark Hammonda69d4092003-04-22 23:13:27 +0000165#endif /* MYDB_USE_GILSTATE */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000166
167#else
Mark Hammonda69d4092003-04-22 23:13:27 +0000168/* Compiled without threads - avoid all this cruft */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000169#define MYDB_BEGIN_ALLOW_THREADS
170#define MYDB_END_ALLOW_THREADS
171#define MYDB_BEGIN_BLOCK_THREADS
172#define MYDB_END_BLOCK_THREADS
173
174#endif
175
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000176/* --------------------------------------------------------------------- */
177/* Exceptions */
178
179static PyObject* DBError; /* Base class, all others derive from this */
Gregory P. Smithe2767172003-11-02 08:06:29 +0000180static PyObject* DBCursorClosedError; /* raised when trying to use a closed cursor object */
Gregory P. Smithe9477062005-06-04 06:46:59 +0000181static PyObject* DBKeyEmptyError; /* DB_KEYEMPTY: also derives from KeyError */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000182static PyObject* DBKeyExistError; /* DB_KEYEXIST */
183static PyObject* DBLockDeadlockError; /* DB_LOCK_DEADLOCK */
184static PyObject* DBLockNotGrantedError; /* DB_LOCK_NOTGRANTED */
185static PyObject* DBNotFoundError; /* DB_NOTFOUND: also derives from KeyError */
186static PyObject* DBOldVersionError; /* DB_OLD_VERSION */
187static PyObject* DBRunRecoveryError; /* DB_RUNRECOVERY */
188static PyObject* DBVerifyBadError; /* DB_VERIFY_BAD */
189static PyObject* DBNoServerError; /* DB_NOSERVER */
190static PyObject* DBNoServerHomeError; /* DB_NOSERVER_HOME */
191static PyObject* DBNoServerIDError; /* DB_NOSERVER_ID */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000192static PyObject* DBPageNotFoundError; /* DB_PAGE_NOTFOUND */
193static PyObject* DBSecondaryBadError; /* DB_SECONDARY_BAD */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000194
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000195static PyObject* DBInvalidArgError; /* EINVAL */
196static PyObject* DBAccessError; /* EACCES */
197static PyObject* DBNoSpaceError; /* ENOSPC */
Gregory P. Smith8b7e9172004-12-13 09:51:23 +0000198static PyObject* DBNoMemoryError; /* DB_BUFFER_SMALL (ENOMEM when < 4.3) */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000199static PyObject* DBAgainError; /* EAGAIN */
200static PyObject* DBBusyError; /* EBUSY */
201static PyObject* DBFileExistsError; /* EEXIST */
202static PyObject* DBNoSuchFileError; /* ENOENT */
203static PyObject* DBPermissionsError; /* EPERM */
204
Jesus Ceaef9764f2008-05-13 18:45:46 +0000205#if (DBVER >= 42)
206static PyObject* DBRepHandleDeadError; /* DB_REP_HANDLE_DEAD */
207#endif
Jesus Cea6557aac2010-03-22 14:22:26 +0000208#if (DBVER >= 44)
209static PyObject* DBRepLockoutError; /* DB_REP_LOCKOUT */
210#endif
211
212#if (DBVER >= 46)
213static PyObject* DBRepLeaseExpiredError; /* DB_REP_LEASE_EXPIRED */
214#endif
215
216#if (DBVER >= 47)
217static PyObject* DBForeignConflictError; /* DB_FOREIGN_CONFLICT */
218#endif
219
Jesus Ceaef9764f2008-05-13 18:45:46 +0000220
Jesus Ceac5a11fa2008-07-23 11:38:42 +0000221static PyObject* DBRepUnavailError; /* DB_REP_UNAVAIL */
222
Gregory P. Smith8b7e9172004-12-13 09:51:23 +0000223#if (DBVER < 43)
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000224#define DB_BUFFER_SMALL ENOMEM
Gregory P. Smith8b7e9172004-12-13 09:51:23 +0000225#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000226
Matthias Klose54cc5392010-03-15 12:46:18 +0000227#if (DBVER < 48)
228#define DB_GID_SIZE DB_XIDDATASIZE
229#endif
230
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000231
232/* --------------------------------------------------------------------- */
233/* Structure definitions */
234
Gregory P. Smith39250532007-10-09 06:02:21 +0000235#if PYTHON_API_VERSION < 1010
236#error "Python 2.1 or later required"
Gregory P. Smitha703a212003-11-03 01:04:41 +0000237#endif
238
Gregory P. Smith31c50652004-06-28 01:20:40 +0000239
Gregory P. Smith39250532007-10-09 06:02:21 +0000240/* Defaults for moduleFlags in DBEnvObject and DBObject. */
Gregory P. Smith455d46f2003-07-09 04:45:59 +0000241#define DEFAULT_GET_RETURNS_NONE 1
Gregory P. Smitha703a212003-11-03 01:04:41 +0000242#define DEFAULT_CURSOR_SET_RETURNS_NONE 1 /* 0 in pybsddb < 4.2, python < 2.4 */
Gregory P. Smith455d46f2003-07-09 04:45:59 +0000243
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000244
Jesus Ceac5a11fa2008-07-23 11:38:42 +0000245/* See comment in Python 2.6 "object.h" */
246#ifndef staticforward
247#define staticforward static
248#endif
249#ifndef statichere
250#define statichere static
251#endif
252
253staticforward PyTypeObject DB_Type, DBCursor_Type, DBEnv_Type, DBTxn_Type,
Jesus Cea6557aac2010-03-22 14:22:26 +0000254 DBLock_Type, DBLogCursor_Type;
Jesus Ceaef9764f2008-05-13 18:45:46 +0000255#if (DBVER >= 43)
256staticforward PyTypeObject DBSequence_Type;
257#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000258
Martin v. Löwis83c92012008-04-24 13:17:24 +0000259#ifndef Py_TYPE
Gregory P. Smithfc006692007-11-05 09:06:28 +0000260/* for compatibility with Python 2.5 and earlier */
Christian Heimese93237d2007-12-19 02:37:44 +0000261#define Py_TYPE(ob) (((PyObject*)(ob))->ob_type)
Gregory P. Smithfc006692007-11-05 09:06:28 +0000262#endif
263
Christian Heimese93237d2007-12-19 02:37:44 +0000264#define DBObject_Check(v) (Py_TYPE(v) == &DB_Type)
265#define DBCursorObject_Check(v) (Py_TYPE(v) == &DBCursor_Type)
Jesus Cea6557aac2010-03-22 14:22:26 +0000266#define DBLogCursorObject_Check(v) (Py_TYPE(v) == &DBLogCursor_Type)
Christian Heimese93237d2007-12-19 02:37:44 +0000267#define DBEnvObject_Check(v) (Py_TYPE(v) == &DBEnv_Type)
268#define DBTxnObject_Check(v) (Py_TYPE(v) == &DBTxn_Type)
269#define DBLockObject_Check(v) (Py_TYPE(v) == &DBLock_Type)
Gregory P. Smithf0547d02006-06-05 17:38:04 +0000270#if (DBVER >= 43)
Christian Heimese93237d2007-12-19 02:37:44 +0000271#define DBSequenceObject_Check(v) (Py_TYPE(v) == &DBSequence_Type)
Gregory P. Smithf0547d02006-06-05 17:38:04 +0000272#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000273
Jesus Ceaef9764f2008-05-13 18:45:46 +0000274#if (DBVER < 46)
275 #define _DBC_close(dbc) dbc->c_close(dbc)
276 #define _DBC_count(dbc,a,b) dbc->c_count(dbc,a,b)
277 #define _DBC_del(dbc,a) dbc->c_del(dbc,a)
278 #define _DBC_dup(dbc,a,b) dbc->c_dup(dbc,a,b)
279 #define _DBC_get(dbc,a,b,c) dbc->c_get(dbc,a,b,c)
280 #define _DBC_pget(dbc,a,b,c,d) dbc->c_pget(dbc,a,b,c,d)
281 #define _DBC_put(dbc,a,b,c) dbc->c_put(dbc,a,b,c)
282#else
283 #define _DBC_close(dbc) dbc->close(dbc)
284 #define _DBC_count(dbc,a,b) dbc->count(dbc,a,b)
285 #define _DBC_del(dbc,a) dbc->del(dbc,a)
286 #define _DBC_dup(dbc,a,b) dbc->dup(dbc,a,b)
287 #define _DBC_get(dbc,a,b,c) dbc->get(dbc,a,b,c)
288 #define _DBC_pget(dbc,a,b,c,d) dbc->pget(dbc,a,b,c,d)
289 #define _DBC_put(dbc,a,b,c) dbc->put(dbc,a,b,c)
290#endif
291
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000292
293/* --------------------------------------------------------------------- */
294/* Utility macros and functions */
295
Jesus Ceaef9764f2008-05-13 18:45:46 +0000296#define INSERT_IN_DOUBLE_LINKED_LIST(backlink,object) \
297 { \
298 object->sibling_next=backlink; \
299 object->sibling_prev_p=&(backlink); \
300 backlink=object; \
301 if (object->sibling_next) { \
302 object->sibling_next->sibling_prev_p=&(object->sibling_next); \
303 } \
304 }
305
306#define EXTRACT_FROM_DOUBLE_LINKED_LIST(object) \
307 { \
308 if (object->sibling_next) { \
309 object->sibling_next->sibling_prev_p=object->sibling_prev_p; \
310 } \
311 *(object->sibling_prev_p)=object->sibling_next; \
312 }
313
314#define EXTRACT_FROM_DOUBLE_LINKED_LIST_MAYBE_NULL(object) \
315 { \
316 if (object->sibling_next) { \
317 object->sibling_next->sibling_prev_p=object->sibling_prev_p; \
318 } \
319 if (object->sibling_prev_p) { \
320 *(object->sibling_prev_p)=object->sibling_next; \
321 } \
322 }
323
324#define INSERT_IN_DOUBLE_LINKED_LIST_TXN(backlink,object) \
325 { \
326 object->sibling_next_txn=backlink; \
327 object->sibling_prev_p_txn=&(backlink); \
328 backlink=object; \
329 if (object->sibling_next_txn) { \
330 object->sibling_next_txn->sibling_prev_p_txn= \
331 &(object->sibling_next_txn); \
332 } \
333 }
334
335#define EXTRACT_FROM_DOUBLE_LINKED_LIST_TXN(object) \
336 { \
337 if (object->sibling_next_txn) { \
338 object->sibling_next_txn->sibling_prev_p_txn= \
339 object->sibling_prev_p_txn; \
340 } \
341 *(object->sibling_prev_p_txn)=object->sibling_next_txn; \
342 }
343
344
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000345#define RETURN_IF_ERR() \
346 if (makeDBError(err)) { \
347 return NULL; \
348 }
349
350#define RETURN_NONE() Py_INCREF(Py_None); return Py_None;
351
Gregory P. Smithe2767172003-11-02 08:06:29 +0000352#define _CHECK_OBJECT_NOT_CLOSED(nonNull, pyErrObj, name) \
353 if ((nonNull) == NULL) { \
354 PyObject *errTuple = NULL; \
355 errTuple = Py_BuildValue("(is)", 0, #name " object has been closed"); \
Jesus Ceac5a11fa2008-07-23 11:38:42 +0000356 if (errTuple) { \
357 PyErr_SetObject((pyErrObj), errTuple); \
358 Py_DECREF(errTuple); \
359 } \
Gregory P. Smithe2767172003-11-02 08:06:29 +0000360 return NULL; \
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000361 }
362
Gregory P. Smithe2767172003-11-02 08:06:29 +0000363#define CHECK_DB_NOT_CLOSED(dbobj) \
364 _CHECK_OBJECT_NOT_CLOSED(dbobj->db, DBError, DB)
365
366#define CHECK_ENV_NOT_CLOSED(env) \
367 _CHECK_OBJECT_NOT_CLOSED(env->db_env, DBError, DBEnv)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000368
369#define CHECK_CURSOR_NOT_CLOSED(curs) \
Gregory P. Smithe2767172003-11-02 08:06:29 +0000370 _CHECK_OBJECT_NOT_CLOSED(curs->dbc, DBCursorClosedError, DBCursor)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000371
Jesus Cea6557aac2010-03-22 14:22:26 +0000372#define CHECK_LOGCURSOR_NOT_CLOSED(logcurs) \
373 _CHECK_OBJECT_NOT_CLOSED(logcurs->logc, DBCursorClosedError, DBLogCursor)
374
Gregory P. Smithf0547d02006-06-05 17:38:04 +0000375#if (DBVER >= 43)
376#define CHECK_SEQUENCE_NOT_CLOSED(curs) \
377 _CHECK_OBJECT_NOT_CLOSED(curs->sequence, DBError, DBSequence)
378#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000379
380#define CHECK_DBFLAG(mydb, flag) (((mydb)->flags & (flag)) || \
381 (((mydb)->myenvobj != NULL) && ((mydb)->myenvobj->flags & (flag))))
382
383#define CLEAR_DBT(dbt) (memset(&(dbt), 0, sizeof(dbt)))
384
385#define FREE_DBT(dbt) if ((dbt.flags & (DB_DBT_MALLOC|DB_DBT_REALLOC)) && \
Gregory P. Smithdc5af702004-06-27 23:32:34 +0000386 dbt.data != NULL) { free(dbt.data); dbt.data = NULL; }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000387
388
389static int makeDBError(int err);
390
391
392/* Return the access method type of the DBObject */
393static int _DB_get_type(DBObject* self)
394{
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000395 DBTYPE type;
396 int err;
Jesus Ceac5a11fa2008-07-23 11:38:42 +0000397
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000398 err = self->db->get_type(self->db, &type);
399 if (makeDBError(err)) {
400 return -1;
401 }
402 return type;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000403}
404
405
406/* Create a DBT structure (containing key and data values) from Python
407 strings. Returns 1 on success, 0 on an error. */
408static int make_dbt(PyObject* obj, DBT* dbt)
409{
410 CLEAR_DBT(*dbt);
411 if (obj == Py_None) {
412 /* no need to do anything, the structure has already been zeroed */
413 }
414 else if (!PyArg_Parse(obj, "s#", &dbt->data, &dbt->size)) {
415 PyErr_SetString(PyExc_TypeError,
Jesus Cea4907d272008-08-31 14:00:51 +0000416#if (PY_VERSION_HEX < 0x03000000)
Gregory P. Smithdc5af702004-06-27 23:32:34 +0000417 "Data values must be of type string or None.");
Jesus Cea4907d272008-08-31 14:00:51 +0000418#else
419 "Data values must be of type bytes or None.");
420#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000421 return 0;
422 }
423 return 1;
424}
425
426
427/* Recno and Queue DBs can have integer keys. This function figures out
428 what's been given, verifies that it's allowed, and then makes the DBT.
429
Gregory P. Smithdc5af702004-06-27 23:32:34 +0000430 Caller MUST call FREE_DBT(key) when done. */
Barry Warsaw9a0d7792002-12-30 20:53:52 +0000431static int
432make_key_dbt(DBObject* self, PyObject* keyobj, DBT* key, int* pflags)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000433{
434 db_recno_t recno;
435 int type;
436
437 CLEAR_DBT(*key);
Gustavo Niemeyerf073b752004-01-20 15:24:29 +0000438 if (keyobj == Py_None) {
Gustavo Niemeyer024f2de2004-01-20 15:14:55 +0000439 type = _DB_get_type(self);
Gustavo Niemeyer8974f722004-01-20 15:20:03 +0000440 if (type == -1)
441 return 0;
Gustavo Niemeyer024f2de2004-01-20 15:14:55 +0000442 if (type == DB_RECNO || type == DB_QUEUE) {
443 PyErr_SetString(
444 PyExc_TypeError,
445 "None keys not allowed for Recno and Queue DB's");
446 return 0;
447 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000448 /* no need to do anything, the structure has already been zeroed */
449 }
450
Christian Heimes593daf52008-05-26 12:51:38 +0000451 else if (PyBytes_Check(keyobj)) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000452 /* verify access method type */
453 type = _DB_get_type(self);
454 if (type == -1)
455 return 0;
456 if (type == DB_RECNO || type == DB_QUEUE) {
Barry Warsaw9a0d7792002-12-30 20:53:52 +0000457 PyErr_SetString(
458 PyExc_TypeError,
Jesus Cea4907d272008-08-31 14:00:51 +0000459#if (PY_VERSION_HEX < 0x03000000)
Barry Warsaw9a0d7792002-12-30 20:53:52 +0000460 "String keys not allowed for Recno and Queue DB's");
Jesus Cea4907d272008-08-31 14:00:51 +0000461#else
462 "Bytes keys not allowed for Recno and Queue DB's");
463#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000464 return 0;
465 }
466
Gregory P. Smith10bed542007-10-09 06:50:43 +0000467 /*
468 * NOTE(gps): I don't like doing a data copy here, it seems
469 * wasteful. But without a clean way to tell FREE_DBT if it
470 * should free key->data or not we have to. Other places in
471 * the code check for DB_THREAD and forceably set DBT_MALLOC
472 * when we otherwise would leave flags 0 to indicate that.
473 */
Christian Heimes593daf52008-05-26 12:51:38 +0000474 key->data = malloc(PyBytes_GET_SIZE(keyobj));
Gregory P. Smith10bed542007-10-09 06:50:43 +0000475 if (key->data == NULL) {
476 PyErr_SetString(PyExc_MemoryError, "Key memory allocation failed");
477 return 0;
478 }
Christian Heimes593daf52008-05-26 12:51:38 +0000479 memcpy(key->data, PyBytes_AS_STRING(keyobj),
480 PyBytes_GET_SIZE(keyobj));
Gregory P. Smith10bed542007-10-09 06:50:43 +0000481 key->flags = DB_DBT_REALLOC;
Christian Heimes593daf52008-05-26 12:51:38 +0000482 key->size = PyBytes_GET_SIZE(keyobj);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000483 }
484
Jesus Ceac5a11fa2008-07-23 11:38:42 +0000485 else if (NUMBER_Check(keyobj)) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000486 /* verify access method type */
487 type = _DB_get_type(self);
488 if (type == -1)
489 return 0;
490 if (type == DB_BTREE && pflags != NULL) {
Barry Warsaw9a0d7792002-12-30 20:53:52 +0000491 /* if BTREE then an Integer key is allowed with the
492 * DB_SET_RECNO flag */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000493 *pflags |= DB_SET_RECNO;
494 }
495 else if (type != DB_RECNO && type != DB_QUEUE) {
Barry Warsaw9a0d7792002-12-30 20:53:52 +0000496 PyErr_SetString(
497 PyExc_TypeError,
498 "Integer keys only allowed for Recno and Queue DB's");
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000499 return 0;
500 }
501
Barry Warsaw9a0d7792002-12-30 20:53:52 +0000502 /* Make a key out of the requested recno, use allocated space so DB
503 * will be able to realloc room for the real key if needed. */
Jesus Ceac5a11fa2008-07-23 11:38:42 +0000504 recno = NUMBER_AsLong(keyobj);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000505 key->data = malloc(sizeof(db_recno_t));
506 if (key->data == NULL) {
507 PyErr_SetString(PyExc_MemoryError, "Key memory allocation failed");
508 return 0;
509 }
510 key->ulen = key->size = sizeof(db_recno_t);
511 memcpy(key->data, &recno, sizeof(db_recno_t));
512 key->flags = DB_DBT_REALLOC;
513 }
514 else {
515 PyErr_Format(PyExc_TypeError,
Jesus Cea4907d272008-08-31 14:00:51 +0000516#if (PY_VERSION_HEX < 0x03000000)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000517 "String or Integer object expected for key, %s found",
Jesus Cea4907d272008-08-31 14:00:51 +0000518#else
519 "Bytes or Integer object expected for key, %s found",
520#endif
Christian Heimese93237d2007-12-19 02:37:44 +0000521 Py_TYPE(keyobj)->tp_name);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000522 return 0;
523 }
524
525 return 1;
526}
527
528
529/* Add partial record access to an existing DBT data struct.
530 If dlen and doff are set, then the DB_DBT_PARTIAL flag will be set
531 and the data storage/retrieval will be done using dlen and doff. */
532static int add_partial_dbt(DBT* d, int dlen, int doff) {
533 /* if neither were set we do nothing (-1 is the default value) */
534 if ((dlen == -1) && (doff == -1)) {
535 return 1;
536 }
537
538 if ((dlen < 0) || (doff < 0)) {
539 PyErr_SetString(PyExc_TypeError, "dlen and doff must both be >= 0");
540 return 0;
541 }
542
543 d->flags = d->flags | DB_DBT_PARTIAL;
544 d->dlen = (unsigned int) dlen;
545 d->doff = (unsigned int) doff;
546 return 1;
547}
548
Gregory P. Smith8b7e9172004-12-13 09:51:23 +0000549/* a safe strcpy() without the zeroing behaviour and semantics of strncpy. */
550/* TODO: make this use the native libc strlcpy() when available (BSD) */
551unsigned int our_strlcpy(char* dest, const char* src, unsigned int n)
552{
553 unsigned int srclen, copylen;
554
555 srclen = strlen(src);
556 if (n <= 0)
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000557 return srclen;
Gregory P. Smith8b7e9172004-12-13 09:51:23 +0000558 copylen = (srclen > n-1) ? n-1 : srclen;
559 /* populate dest[0] thru dest[copylen-1] */
560 memcpy(dest, src, copylen);
561 /* guarantee null termination */
562 dest[copylen] = 0;
563
564 return srclen;
565}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000566
Barry Warsaw9a0d7792002-12-30 20:53:52 +0000567/* Callback used to save away more information about errors from the DB
568 * library. */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000569static char _db_errmsg[1024];
Gregory P. Smith8b7e9172004-12-13 09:51:23 +0000570#if (DBVER <= 42)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000571static void _db_errorCallback(const char* prefix, char* msg)
Gregory P. Smith8b7e9172004-12-13 09:51:23 +0000572#else
573static void _db_errorCallback(const DB_ENV *db_env,
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000574 const char* prefix, const char* msg)
Gregory P. Smith8b7e9172004-12-13 09:51:23 +0000575#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000576{
Gregory P. Smith8b7e9172004-12-13 09:51:23 +0000577 our_strlcpy(_db_errmsg, msg, sizeof(_db_errmsg));
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000578}
579
580
Jesus Ceaef9764f2008-05-13 18:45:46 +0000581/*
582** We need these functions because some results
583** are undefined if pointer is NULL. Some other
584** give None instead of "".
585**
586** This functions are static and will be
587** -I hope- inlined.
588*/
589static const char *DummyString = "This string is a simple placeholder";
590static PyObject *Build_PyString(const char *p,int s)
591{
592 if (!p) {
593 p=DummyString;
594 assert(s==0);
595 }
Christian Heimes593daf52008-05-26 12:51:38 +0000596 return PyBytes_FromStringAndSize(p,s);
Jesus Ceaef9764f2008-05-13 18:45:46 +0000597}
598
599static PyObject *BuildValue_S(const void *p,int s)
600{
601 if (!p) {
602 p=DummyString;
603 assert(s==0);
604 }
Jesus Cea4907d272008-08-31 14:00:51 +0000605 return PyBytes_FromStringAndSize(p, s);
Jesus Ceaef9764f2008-05-13 18:45:46 +0000606}
607
608static PyObject *BuildValue_SS(const void *p1,int s1,const void *p2,int s2)
609{
Jesus Cea4907d272008-08-31 14:00:51 +0000610PyObject *a, *b, *r;
611
Jesus Ceaef9764f2008-05-13 18:45:46 +0000612 if (!p1) {
613 p1=DummyString;
614 assert(s1==0);
615 }
616 if (!p2) {
617 p2=DummyString;
618 assert(s2==0);
619 }
Jesus Cea4907d272008-08-31 14:00:51 +0000620
621 if (!(a = PyBytes_FromStringAndSize(p1, s1))) {
622 return NULL;
623 }
624 if (!(b = PyBytes_FromStringAndSize(p2, s2))) {
625 Py_DECREF(a);
626 return NULL;
627 }
628
629#if (PY_VERSION_HEX >= 0x02040000)
630 r = PyTuple_Pack(2, a, b) ;
631#else
632 r = Py_BuildValue("OO", a, b);
633#endif
634 Py_DECREF(a);
635 Py_DECREF(b);
636 return r;
Jesus Ceaef9764f2008-05-13 18:45:46 +0000637}
638
639static PyObject *BuildValue_IS(int i,const void *p,int s)
640{
Jesus Cea4907d272008-08-31 14:00:51 +0000641 PyObject *a, *r;
642
Jesus Ceaef9764f2008-05-13 18:45:46 +0000643 if (!p) {
644 p=DummyString;
645 assert(s==0);
646 }
Jesus Cea4907d272008-08-31 14:00:51 +0000647
648 if (!(a = PyBytes_FromStringAndSize(p, s))) {
649 return NULL;
650 }
651
652 r = Py_BuildValue("iO", i, a);
653 Py_DECREF(a);
654 return r;
Jesus Ceaef9764f2008-05-13 18:45:46 +0000655}
656
Jesus Cea4907d272008-08-31 14:00:51 +0000657static PyObject *BuildValue_LS(long l,const void *p,int s)
Jesus Ceaef9764f2008-05-13 18:45:46 +0000658{
Jesus Cea4907d272008-08-31 14:00:51 +0000659 PyObject *a, *r;
660
Jesus Ceaef9764f2008-05-13 18:45:46 +0000661 if (!p) {
662 p=DummyString;
663 assert(s==0);
664 }
Jesus Cea4907d272008-08-31 14:00:51 +0000665
666 if (!(a = PyBytes_FromStringAndSize(p, s))) {
667 return NULL;
668 }
669
670 r = Py_BuildValue("lO", l, a);
671 Py_DECREF(a);
672 return r;
Jesus Ceaef9764f2008-05-13 18:45:46 +0000673}
674
675
676
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000677/* make a nice exception object to raise for errors. */
678static int makeDBError(int err)
679{
680 char errTxt[2048]; /* really big, just in case... */
Barry Warsaw9a0d7792002-12-30 20:53:52 +0000681 PyObject *errObj = NULL;
682 PyObject *errTuple = NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000683 int exceptionRaised = 0;
Neal Norwitzdce937f2006-07-23 08:01:43 +0000684 unsigned int bytes_left;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000685
686 switch (err) {
Jesus Cea6557aac2010-03-22 14:22:26 +0000687 case 0: /* successful, no error */
688 return 0;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000689
690 case DB_KEYEMPTY: errObj = DBKeyEmptyError; break;
691 case DB_KEYEXIST: errObj = DBKeyExistError; break;
692 case DB_LOCK_DEADLOCK: errObj = DBLockDeadlockError; break;
693 case DB_LOCK_NOTGRANTED: errObj = DBLockNotGrantedError; break;
694 case DB_NOTFOUND: errObj = DBNotFoundError; break;
695 case DB_OLD_VERSION: errObj = DBOldVersionError; break;
696 case DB_RUNRECOVERY: errObj = DBRunRecoveryError; break;
697 case DB_VERIFY_BAD: errObj = DBVerifyBadError; break;
698 case DB_NOSERVER: errObj = DBNoServerError; break;
699 case DB_NOSERVER_HOME: errObj = DBNoServerHomeError; break;
700 case DB_NOSERVER_ID: errObj = DBNoServerIDError; break;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000701 case DB_PAGE_NOTFOUND: errObj = DBPageNotFoundError; break;
702 case DB_SECONDARY_BAD: errObj = DBSecondaryBadError; break;
Gregory P. Smith8b7e9172004-12-13 09:51:23 +0000703 case DB_BUFFER_SMALL: errObj = DBNoMemoryError; break;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000704
Gregory P. Smith8b7e9172004-12-13 09:51:23 +0000705#if (DBVER >= 43)
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000706 /* ENOMEM and DB_BUFFER_SMALL were one and the same until 4.3 */
707 case ENOMEM: errObj = PyExc_MemoryError; break;
Gregory P. Smith8b7e9172004-12-13 09:51:23 +0000708#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000709 case EINVAL: errObj = DBInvalidArgError; break;
710 case EACCES: errObj = DBAccessError; break;
711 case ENOSPC: errObj = DBNoSpaceError; break;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000712 case EAGAIN: errObj = DBAgainError; break;
713 case EBUSY : errObj = DBBusyError; break;
714 case EEXIST: errObj = DBFileExistsError; break;
715 case ENOENT: errObj = DBNoSuchFileError; break;
716 case EPERM : errObj = DBPermissionsError; break;
717
Jesus Ceaef9764f2008-05-13 18:45:46 +0000718#if (DBVER >= 42)
719 case DB_REP_HANDLE_DEAD : errObj = DBRepHandleDeadError; break;
720#endif
Jesus Cea6557aac2010-03-22 14:22:26 +0000721#if (DBVER >= 44)
722 case DB_REP_LOCKOUT : errObj = DBRepLockoutError; break;
723#endif
724
725#if (DBVER >= 46)
726 case DB_REP_LEASE_EXPIRED : errObj = DBRepLeaseExpiredError; break;
727#endif
728
729#if (DBVER >= 47)
730 case DB_FOREIGN_CONFLICT : errObj = DBForeignConflictError; break;
731#endif
Jesus Ceaef9764f2008-05-13 18:45:46 +0000732
Jesus Ceac5a11fa2008-07-23 11:38:42 +0000733 case DB_REP_UNAVAIL : errObj = DBRepUnavailError; break;
734
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000735 default: errObj = DBError; break;
736 }
737
738 if (errObj != NULL) {
Neal Norwitzdce937f2006-07-23 08:01:43 +0000739 bytes_left = our_strlcpy(errTxt, db_strerror(err), sizeof(errTxt));
740 /* Ensure that bytes_left never goes negative */
741 if (_db_errmsg[0] && bytes_left < (sizeof(errTxt) - 4)) {
742 bytes_left = sizeof(errTxt) - bytes_left - 4 - 1;
743 assert(bytes_left >= 0);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000744 strcat(errTxt, " -- ");
Neal Norwitzdce937f2006-07-23 08:01:43 +0000745 strncat(errTxt, _db_errmsg, bytes_left);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000746 }
Neal Norwitzdce937f2006-07-23 08:01:43 +0000747 _db_errmsg[0] = 0;
Barry Warsaw9a0d7792002-12-30 20:53:52 +0000748
Jesus Ceac5a11fa2008-07-23 11:38:42 +0000749 errTuple = Py_BuildValue("(is)", err, errTxt);
750 if (errTuple == NULL) {
751 Py_DECREF(errObj);
752 return !0;
753 }
Barry Warsaw9a0d7792002-12-30 20:53:52 +0000754 PyErr_SetObject(errObj, errTuple);
Jesus Ceac5a11fa2008-07-23 11:38:42 +0000755 Py_DECREF(errTuple);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000756 }
757
758 return ((errObj != NULL) || exceptionRaised);
759}
760
761
762
763/* set a type exception */
764static void makeTypeError(char* expected, PyObject* found)
765{
766 PyErr_Format(PyExc_TypeError, "Expected %s argument, %s found.",
Christian Heimese93237d2007-12-19 02:37:44 +0000767 expected, Py_TYPE(found)->tp_name);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000768}
769
770
771/* verify that an obj is either None or a DBTxn, and set the txn pointer */
772static int checkTxnObj(PyObject* txnobj, DB_TXN** txn)
773{
774 if (txnobj == Py_None || txnobj == NULL) {
775 *txn = NULL;
776 return 1;
777 }
778 if (DBTxnObject_Check(txnobj)) {
779 *txn = ((DBTxnObject*)txnobj)->txn;
780 return 1;
781 }
782 else
783 makeTypeError("DBTxn", txnobj);
784 return 0;
785}
786
787
788/* Delete a key from a database
789 Returns 0 on success, -1 on an error. */
790static int _DB_delete(DBObject* self, DB_TXN *txn, DBT *key, int flags)
791{
792 int err;
793
794 MYDB_BEGIN_ALLOW_THREADS;
795 err = self->db->del(self->db, txn, key, 0);
796 MYDB_END_ALLOW_THREADS;
797 if (makeDBError(err)) {
798 return -1;
799 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000800 return 0;
801}
802
803
804/* Store a key into a database
805 Returns 0 on success, -1 on an error. */
806static int _DB_put(DBObject* self, DB_TXN *txn, DBT *key, DBT *data, int flags)
807{
808 int err;
809
810 MYDB_BEGIN_ALLOW_THREADS;
811 err = self->db->put(self->db, txn, key, data, flags);
812 MYDB_END_ALLOW_THREADS;
813 if (makeDBError(err)) {
814 return -1;
815 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000816 return 0;
817}
818
819/* Get a key/data pair from a cursor */
820static PyObject* _DBCursor_get(DBCursorObject* self, int extra_flags,
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000821 PyObject *args, PyObject *kwargs, char *format)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000822{
823 int err;
824 PyObject* retval = NULL;
825 DBT key, data;
826 int dlen = -1;
827 int doff = -1;
828 int flags = 0;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +0000829 static char* kwnames[] = { "flags", "dlen", "doff", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000830
831 if (!PyArg_ParseTupleAndKeywords(args, kwargs, format, kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000832 &flags, &dlen, &doff))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000833 return NULL;
834
835 CHECK_CURSOR_NOT_CLOSED(self);
836
837 flags |= extra_flags;
838 CLEAR_DBT(key);
839 CLEAR_DBT(data);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000840 if (!add_partial_dbt(&data, dlen, doff))
841 return NULL;
842
843 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +0000844 err = _DBC_get(self->dbc, &key, &data, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000845 MYDB_END_ALLOW_THREADS;
846
Gregory P. Smithe9477062005-06-04 06:46:59 +0000847 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000848 && self->mydb->moduleFlags.getReturnsNone) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000849 Py_INCREF(Py_None);
850 retval = Py_None;
851 }
852 else if (makeDBError(err)) {
853 retval = NULL;
854 }
855 else { /* otherwise, success! */
856
857 /* if Recno or Queue, return the key as an Int */
858 switch (_DB_get_type(self->mydb)) {
859 case -1:
860 retval = NULL;
861 break;
862
863 case DB_RECNO:
864 case DB_QUEUE:
Jesus Ceaef9764f2008-05-13 18:45:46 +0000865 retval = BuildValue_IS(*((db_recno_t*)key.data), data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000866 break;
867 case DB_HASH:
868 case DB_BTREE:
869 default:
Jesus Ceaef9764f2008-05-13 18:45:46 +0000870 retval = BuildValue_SS(key.data, key.size, data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000871 break;
872 }
873 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000874 return retval;
875}
876
877
878/* add an integer to a dictionary using the given name as a key */
879static void _addIntToDict(PyObject* dict, char *name, int value)
880{
Jesus Ceac5a11fa2008-07-23 11:38:42 +0000881 PyObject* v = NUMBER_FromLong((long) value);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000882 if (!v || PyDict_SetItemString(dict, name, v))
883 PyErr_Clear();
884
885 Py_XDECREF(v);
886}
Kristján Valur Jónssonbd77c032007-04-26 15:24:54 +0000887
888/* The same, when the value is a time_t */
889static void _addTimeTToDict(PyObject* dict, char *name, time_t value)
890{
891 PyObject* v;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000892 /* if the value fits in regular int, use that. */
Jesus Ceaef9764f2008-05-13 18:45:46 +0000893#ifdef PY_LONG_LONG
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000894 if (sizeof(time_t) > sizeof(long))
895 v = PyLong_FromLongLong((PY_LONG_LONG) value);
896 else
Kristján Valur Jónssonbd77c032007-04-26 15:24:54 +0000897#endif
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000898 v = NUMBER_FromLong((long) value);
Kristján Valur Jónssonbd77c032007-04-26 15:24:54 +0000899 if (!v || PyDict_SetItemString(dict, name, v))
900 PyErr_Clear();
901
902 Py_XDECREF(v);
903}
904
Gregory P. Smithf0547d02006-06-05 17:38:04 +0000905#if (DBVER >= 43)
906/* add an db_seq_t to a dictionary using the given name as a key */
907static void _addDb_seq_tToDict(PyObject* dict, char *name, db_seq_t value)
908{
909 PyObject* v = PyLong_FromLongLong(value);
910 if (!v || PyDict_SetItemString(dict, name, v))
911 PyErr_Clear();
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000912
Gregory P. Smithf0547d02006-06-05 17:38:04 +0000913 Py_XDECREF(v);
914}
915#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000916
Jesus Ceaef9764f2008-05-13 18:45:46 +0000917static void _addDB_lsnToDict(PyObject* dict, char *name, DB_LSN value)
918{
919 PyObject *v = Py_BuildValue("(ll)",value.file,value.offset);
920 if (!v || PyDict_SetItemString(dict, name, v))
921 PyErr_Clear();
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000922
Jesus Ceaef9764f2008-05-13 18:45:46 +0000923 Py_XDECREF(v);
924}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000925
926/* --------------------------------------------------------------------- */
927/* Allocators and deallocators */
928
929static DBObject*
930newDBObject(DBEnvObject* arg, int flags)
931{
932 DBObject* self;
933 DB_ENV* db_env = NULL;
934 int err;
935
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000936 self = PyObject_New(DBObject, &DB_Type);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000937 if (self == NULL)
938 return NULL;
939
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000940 self->flags = 0;
941 self->setflags = 0;
942 self->myenvobj = NULL;
Jesus Ceac5a11fa2008-07-23 11:38:42 +0000943 self->db = NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +0000944 self->children_cursors = NULL;
945#if (DBVER >=43)
946 self->children_sequences = NULL;
947#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000948 self->associateCallback = NULL;
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +0000949 self->btCompareCallback = NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000950 self->primaryDBType = 0;
Jesus Ceac5a11fa2008-07-23 11:38:42 +0000951 Py_INCREF(Py_None);
Jesus Cea4907d272008-08-31 14:00:51 +0000952 self->private_obj = Py_None;
Gregory P. Smith31c50652004-06-28 01:20:40 +0000953 self->in_weakreflist = NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000954
955 /* keep a reference to our python DBEnv object */
956 if (arg) {
957 Py_INCREF(arg);
958 self->myenvobj = arg;
959 db_env = arg->db_env;
Jesus Ceaef9764f2008-05-13 18:45:46 +0000960 INSERT_IN_DOUBLE_LINKED_LIST(self->myenvobj->children_dbs,self);
961 } else {
962 self->sibling_prev_p=NULL;
963 self->sibling_next=NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000964 }
Jesus Ceaef9764f2008-05-13 18:45:46 +0000965 self->txn=NULL;
966 self->sibling_prev_p_txn=NULL;
967 self->sibling_next_txn=NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000968
969 if (self->myenvobj)
Gregory P. Smith455d46f2003-07-09 04:45:59 +0000970 self->moduleFlags = self->myenvobj->moduleFlags;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000971 else
Gregory P. Smith455d46f2003-07-09 04:45:59 +0000972 self->moduleFlags.getReturnsNone = DEFAULT_GET_RETURNS_NONE;
973 self->moduleFlags.cursorSetReturnsNone = DEFAULT_CURSOR_SET_RETURNS_NONE;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000974
975 MYDB_BEGIN_ALLOW_THREADS;
976 err = db_create(&self->db, db_env, flags);
Neal Norwitzdce937f2006-07-23 08:01:43 +0000977 if (self->db != NULL) {
978 self->db->set_errcall(self->db, _db_errorCallback);
Neal Norwitzdce937f2006-07-23 08:01:43 +0000979 self->db->app_private = (void*)self;
Neal Norwitzdce937f2006-07-23 08:01:43 +0000980 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000981 MYDB_END_ALLOW_THREADS;
Gregory P. Smith31c50652004-06-28 01:20:40 +0000982 /* TODO add a weakref(self) to the self->myenvobj->open_child_weakrefs
983 * list so that a DBEnv can refuse to close without aborting any open
Gregory P. Smithf0547d02006-06-05 17:38:04 +0000984 * DBTxns and closing any open DBs first. */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000985 if (makeDBError(err)) {
986 if (self->myenvobj) {
987 Py_DECREF(self->myenvobj);
988 self->myenvobj = NULL;
989 }
Gregory P. Smith664782e2008-05-17 06:12:02 +0000990 Py_DECREF(self);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000991 self = NULL;
992 }
993 return self;
994}
995
996
Jesus Ceaef9764f2008-05-13 18:45:46 +0000997/* Forward declaration */
Jesus Cea5cd5f122008-09-23 18:54:08 +0000998static PyObject *DB_close_internal(DBObject* self, int flags, int do_not_close);
Jesus Ceaef9764f2008-05-13 18:45:46 +0000999
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001000static void
1001DB_dealloc(DBObject* self)
1002{
Jesus Ceaef9764f2008-05-13 18:45:46 +00001003 PyObject *dummy;
1004
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001005 if (self->db != NULL) {
Jesus Cea5cd5f122008-09-23 18:54:08 +00001006 dummy=DB_close_internal(self, 0, 0);
1007 /*
1008 ** Raising exceptions while doing
1009 ** garbage collection is a fatal error.
1010 */
1011 if (dummy)
1012 Py_DECREF(dummy);
1013 else
1014 PyErr_Clear();
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001015 }
Gregory P. Smith31c50652004-06-28 01:20:40 +00001016 if (self->in_weakreflist != NULL) {
1017 PyObject_ClearWeakRefs((PyObject *) self);
1018 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001019 if (self->myenvobj) {
1020 Py_DECREF(self->myenvobj);
1021 self->myenvobj = NULL;
1022 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001023 if (self->associateCallback != NULL) {
1024 Py_DECREF(self->associateCallback);
1025 self->associateCallback = NULL;
1026 }
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00001027 if (self->btCompareCallback != NULL) {
1028 Py_DECREF(self->btCompareCallback);
1029 self->btCompareCallback = NULL;
1030 }
Jesus Cea4907d272008-08-31 14:00:51 +00001031 Py_DECREF(self->private_obj);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001032 PyObject_Del(self);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001033}
1034
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001035static DBCursorObject*
Jesus Ceaef9764f2008-05-13 18:45:46 +00001036newDBCursorObject(DBC* dbc, DBTxnObject *txn, DBObject* db)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001037{
Neal Norwitzb4a55812004-07-09 23:30:57 +00001038 DBCursorObject* self = PyObject_New(DBCursorObject, &DBCursor_Type);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001039 if (self == NULL)
1040 return NULL;
1041
1042 self->dbc = dbc;
1043 self->mydb = db;
Jesus Ceaef9764f2008-05-13 18:45:46 +00001044
1045 INSERT_IN_DOUBLE_LINKED_LIST(self->mydb->children_cursors,self);
1046 if (txn && ((PyObject *)txn!=Py_None)) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001047 INSERT_IN_DOUBLE_LINKED_LIST_TXN(txn->children_cursors,self);
1048 self->txn=txn;
Jesus Ceaef9764f2008-05-13 18:45:46 +00001049 } else {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001050 self->txn=NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00001051 }
1052
Gregory P. Smitha703a212003-11-03 01:04:41 +00001053 self->in_weakreflist = NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001054 Py_INCREF(self->mydb);
1055 return self;
1056}
1057
1058
Jesus Ceaef9764f2008-05-13 18:45:46 +00001059/* Forward declaration */
1060static PyObject *DBC_close_internal(DBCursorObject* self);
1061
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001062static void
1063DBCursor_dealloc(DBCursorObject* self)
1064{
Jesus Ceaef9764f2008-05-13 18:45:46 +00001065 PyObject *dummy;
Gregory P. Smitha703a212003-11-03 01:04:41 +00001066
Jesus Ceaef9764f2008-05-13 18:45:46 +00001067 if (self->dbc != NULL) {
Jesus Cea5cd5f122008-09-23 18:54:08 +00001068 dummy=DBC_close_internal(self);
1069 /*
1070 ** Raising exceptions while doing
1071 ** garbage collection is a fatal error.
1072 */
1073 if (dummy)
1074 Py_DECREF(dummy);
1075 else
1076 PyErr_Clear();
Jesus Ceaef9764f2008-05-13 18:45:46 +00001077 }
Gregory P. Smitha703a212003-11-03 01:04:41 +00001078 if (self->in_weakreflist != NULL) {
1079 PyObject_ClearWeakRefs((PyObject *) self);
1080 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00001081 Py_DECREF(self->mydb);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001082 PyObject_Del(self);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001083}
1084
1085
Jesus Cea6557aac2010-03-22 14:22:26 +00001086static DBLogCursorObject*
1087newDBLogCursorObject(DB_LOGC* dblogc, DBEnvObject* env)
1088{
1089 DBLogCursorObject* self;
1090
1091 self = PyObject_New(DBLogCursorObject, &DBLogCursor_Type);
1092
1093 if (self == NULL)
1094 return NULL;
1095
1096 self->logc = dblogc;
1097 self->env = env;
1098
1099 INSERT_IN_DOUBLE_LINKED_LIST(self->env->children_logcursors, self);
1100
1101 self->in_weakreflist = NULL;
1102 Py_INCREF(self->env);
1103 return self;
1104}
1105
1106
1107/* Forward declaration */
1108static PyObject *DBLogCursor_close_internal(DBLogCursorObject* self);
1109
1110static void
1111DBLogCursor_dealloc(DBLogCursorObject* self)
1112{
1113 PyObject *dummy;
1114
1115 if (self->logc != NULL) {
1116 dummy = DBLogCursor_close_internal(self);
1117 /*
1118 ** Raising exceptions while doing
1119 ** garbage collection is a fatal error.
1120 */
1121 if (dummy)
1122 Py_DECREF(dummy);
1123 else
1124 PyErr_Clear();
1125 }
1126 if (self->in_weakreflist != NULL) {
1127 PyObject_ClearWeakRefs((PyObject *) self);
1128 }
1129 Py_DECREF(self->env);
1130 PyObject_Del(self);
1131}
1132
1133
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001134static DBEnvObject*
1135newDBEnvObject(int flags)
1136{
1137 int err;
Neal Norwitzb4a55812004-07-09 23:30:57 +00001138 DBEnvObject* self = PyObject_New(DBEnvObject, &DBEnv_Type);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001139 if (self == NULL)
1140 return NULL;
1141
Jesus Cea5cd5f122008-09-23 18:54:08 +00001142 self->db_env = NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001143 self->closed = 1;
1144 self->flags = flags;
Gregory P. Smith455d46f2003-07-09 04:45:59 +00001145 self->moduleFlags.getReturnsNone = DEFAULT_GET_RETURNS_NONE;
1146 self->moduleFlags.cursorSetReturnsNone = DEFAULT_CURSOR_SET_RETURNS_NONE;
Jesus Ceaef9764f2008-05-13 18:45:46 +00001147 self->children_dbs = NULL;
1148 self->children_txns = NULL;
Jesus Cea6557aac2010-03-22 14:22:26 +00001149 self->children_logcursors = NULL ;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00001150 Py_INCREF(Py_None);
Jesus Cea4907d272008-08-31 14:00:51 +00001151 self->private_obj = Py_None;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00001152 Py_INCREF(Py_None);
1153 self->rep_transport = Py_None;
Gregory P. Smith31c50652004-06-28 01:20:40 +00001154 self->in_weakreflist = NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00001155 self->event_notifyCallback = NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00001156
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001157 MYDB_BEGIN_ALLOW_THREADS;
1158 err = db_env_create(&self->db_env, flags);
1159 MYDB_END_ALLOW_THREADS;
1160 if (makeDBError(err)) {
Gregory P. Smith664782e2008-05-17 06:12:02 +00001161 Py_DECREF(self);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001162 self = NULL;
1163 }
1164 else {
1165 self->db_env->set_errcall(self->db_env, _db_errorCallback);
Jesus Cea4907d272008-08-31 14:00:51 +00001166 self->db_env->app_private = self;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001167 }
1168 return self;
1169}
1170
Jesus Ceaef9764f2008-05-13 18:45:46 +00001171/* Forward declaration */
1172static PyObject *DBEnv_close_internal(DBEnvObject* self, int flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001173
1174static void
1175DBEnv_dealloc(DBEnvObject* self)
1176{
Jesus Ceaef9764f2008-05-13 18:45:46 +00001177 PyObject *dummy;
1178
Jesus Ceaac25fab2008-09-03 17:50:32 +00001179 if (self->db_env) {
Jesus Cea5cd5f122008-09-23 18:54:08 +00001180 dummy=DBEnv_close_internal(self, 0);
1181 /*
1182 ** Raising exceptions while doing
1183 ** garbage collection is a fatal error.
1184 */
1185 if (dummy)
1186 Py_DECREF(dummy);
1187 else
1188 PyErr_Clear();
Jesus Ceaef9764f2008-05-13 18:45:46 +00001189 }
1190
Jesus Ceaef9764f2008-05-13 18:45:46 +00001191 Py_XDECREF(self->event_notifyCallback);
1192 self->event_notifyCallback = NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00001193
Gregory P. Smith31c50652004-06-28 01:20:40 +00001194 if (self->in_weakreflist != NULL) {
1195 PyObject_ClearWeakRefs((PyObject *) self);
1196 }
Jesus Cea4907d272008-08-31 14:00:51 +00001197 Py_DECREF(self->private_obj);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00001198 Py_DECREF(self->rep_transport);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001199 PyObject_Del(self);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001200}
1201
1202
1203static DBTxnObject*
Jesus Ceaef9764f2008-05-13 18:45:46 +00001204newDBTxnObject(DBEnvObject* myenv, DBTxnObject *parent, DB_TXN *txn, int flags)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001205{
1206 int err;
Gregory P. Smith664782e2008-05-17 06:12:02 +00001207 DB_TXN *parent_txn = NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00001208
Neal Norwitzb4a55812004-07-09 23:30:57 +00001209 DBTxnObject* self = PyObject_New(DBTxnObject, &DBTxn_Type);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001210 if (self == NULL)
1211 return NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00001212
Gregory P. Smith31c50652004-06-28 01:20:40 +00001213 self->in_weakreflist = NULL;
Gregory P. Smith664782e2008-05-17 06:12:02 +00001214 self->children_txns = NULL;
1215 self->children_dbs = NULL;
1216 self->children_cursors = NULL;
1217 self->children_sequences = NULL;
1218 self->flag_prepare = 0;
1219 self->parent_txn = NULL;
1220 self->env = NULL;
Jesus Cea6557aac2010-03-22 14:22:26 +00001221 /* We initialize just in case "txn_begin" fails */
1222 self->txn = NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001223
Jesus Ceaef9764f2008-05-13 18:45:46 +00001224 if (parent && ((PyObject *)parent!=Py_None)) {
Gregory P. Smith664782e2008-05-17 06:12:02 +00001225 parent_txn = parent->txn;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001226 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00001227
1228 if (txn) {
Gregory P. Smith664782e2008-05-17 06:12:02 +00001229 self->txn = txn;
Jesus Ceaef9764f2008-05-13 18:45:46 +00001230 } else {
1231 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00001232 err = myenv->db_env->txn_begin(myenv->db_env, parent_txn, &(self->txn), flags);
Jesus Ceaef9764f2008-05-13 18:45:46 +00001233 MYDB_END_ALLOW_THREADS;
1234
1235 if (makeDBError(err)) {
Jesus Cea6557aac2010-03-22 14:22:26 +00001236 /* Free object half initialized */
Gregory P. Smith664782e2008-05-17 06:12:02 +00001237 Py_DECREF(self);
Jesus Ceaef9764f2008-05-13 18:45:46 +00001238 return NULL;
1239 }
1240 }
1241
Gregory P. Smith664782e2008-05-17 06:12:02 +00001242 /* Can't use 'parent' because could be 'parent==Py_None' */
1243 if (parent_txn) {
1244 self->parent_txn = parent;
Jesus Ceaef9764f2008-05-13 18:45:46 +00001245 Py_INCREF(parent);
1246 self->env = NULL;
Gregory P. Smith664782e2008-05-17 06:12:02 +00001247 INSERT_IN_DOUBLE_LINKED_LIST(parent->children_txns, self);
Jesus Ceaef9764f2008-05-13 18:45:46 +00001248 } else {
Gregory P. Smith664782e2008-05-17 06:12:02 +00001249 self->parent_txn = NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00001250 Py_INCREF(myenv);
1251 self->env = myenv;
Gregory P. Smith664782e2008-05-17 06:12:02 +00001252 INSERT_IN_DOUBLE_LINKED_LIST(myenv->children_txns, self);
Jesus Ceaef9764f2008-05-13 18:45:46 +00001253 }
1254
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001255 return self;
1256}
1257
Jesus Ceaef9764f2008-05-13 18:45:46 +00001258/* Forward declaration */
1259static PyObject *
1260DBTxn_abort_discard_internal(DBTxnObject* self, int discard);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001261
1262static void
1263DBTxn_dealloc(DBTxnObject* self)
1264{
Jesus Ceaef9764f2008-05-13 18:45:46 +00001265 PyObject *dummy;
1266
1267 if (self->txn) {
1268 int flag_prepare = self->flag_prepare;
Jesus Cea5cd5f122008-09-23 18:54:08 +00001269
Jesus Cea6557aac2010-03-22 14:22:26 +00001270 dummy=DBTxn_abort_discard_internal(self, 0);
Jesus Cea5cd5f122008-09-23 18:54:08 +00001271 /*
1272 ** Raising exceptions while doing
1273 ** garbage collection is a fatal error.
1274 */
1275 if (dummy)
1276 Py_DECREF(dummy);
1277 else
1278 PyErr_Clear();
1279
Jesus Ceaef9764f2008-05-13 18:45:46 +00001280 if (!flag_prepare) {
1281 PyErr_Warn(PyExc_RuntimeWarning,
1282 "DBTxn aborted in destructor. No prior commit() or abort().");
1283 }
1284 }
1285
Gregory P. Smith31c50652004-06-28 01:20:40 +00001286 if (self->in_weakreflist != NULL) {
1287 PyObject_ClearWeakRefs((PyObject *) self);
1288 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001289
Jesus Ceaef9764f2008-05-13 18:45:46 +00001290 if (self->env) {
1291 Py_DECREF(self->env);
1292 } else {
Jesus Cea6557aac2010-03-22 14:22:26 +00001293 /*
1294 ** We can have "self->env==NULL" and "self->parent_txn==NULL"
1295 ** if something happens when creating the transaction object
1296 ** and we abort the object while half done.
1297 */
1298 Py_XDECREF(self->parent_txn);
Gregory P. Smith31c50652004-06-28 01:20:40 +00001299 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001300 PyObject_Del(self);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001301}
1302
1303
1304static DBLockObject*
1305newDBLockObject(DBEnvObject* myenv, u_int32_t locker, DBT* obj,
1306 db_lockmode_t lock_mode, int flags)
1307{
1308 int err;
Neal Norwitzb4a55812004-07-09 23:30:57 +00001309 DBLockObject* self = PyObject_New(DBLockObject, &DBLock_Type);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001310 if (self == NULL)
1311 return NULL;
Gregory P. Smith31c50652004-06-28 01:20:40 +00001312 self->in_weakreflist = NULL;
Jesus Cea6557aac2010-03-22 14:22:26 +00001313 self->lock_initialized = 0; /* Just in case the call fails */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001314
1315 MYDB_BEGIN_ALLOW_THREADS;
Barry Warsaw9a0d7792002-12-30 20:53:52 +00001316 err = myenv->db_env->lock_get(myenv->db_env, locker, flags, obj, lock_mode,
1317 &self->lock);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001318 MYDB_END_ALLOW_THREADS;
1319 if (makeDBError(err)) {
Gregory P. Smith664782e2008-05-17 06:12:02 +00001320 Py_DECREF(self);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001321 self = NULL;
Jesus Cea6557aac2010-03-22 14:22:26 +00001322 } else {
1323 self->lock_initialized = 1;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001324 }
1325
1326 return self;
1327}
1328
1329
1330static void
1331DBLock_dealloc(DBLockObject* self)
1332{
Gregory P. Smith31c50652004-06-28 01:20:40 +00001333 if (self->in_weakreflist != NULL) {
1334 PyObject_ClearWeakRefs((PyObject *) self);
1335 }
Gregory P. Smith31c50652004-06-28 01:20:40 +00001336 /* TODO: is this lock held? should we release it? */
Jesus Cea6557aac2010-03-22 14:22:26 +00001337 /* CAUTION: The lock can be not initialized if the creation has failed */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001338
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001339 PyObject_Del(self);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001340}
1341
1342
Gregory P. Smithf0547d02006-06-05 17:38:04 +00001343#if (DBVER >= 43)
1344static DBSequenceObject*
1345newDBSequenceObject(DBObject* mydb, int flags)
1346{
1347 int err;
1348 DBSequenceObject* self = PyObject_New(DBSequenceObject, &DBSequence_Type);
1349 if (self == NULL)
1350 return NULL;
1351 Py_INCREF(mydb);
1352 self->mydb = mydb;
Gregory P. Smithf0547d02006-06-05 17:38:04 +00001353
Jesus Ceaef9764f2008-05-13 18:45:46 +00001354 INSERT_IN_DOUBLE_LINKED_LIST(self->mydb->children_sequences,self);
Gregory P. Smith664782e2008-05-17 06:12:02 +00001355 self->txn = NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00001356
1357 self->in_weakreflist = NULL;
Jesus Cea6557aac2010-03-22 14:22:26 +00001358 self->sequence = NULL; /* Just in case the call fails */
Gregory P. Smithf0547d02006-06-05 17:38:04 +00001359
1360 MYDB_BEGIN_ALLOW_THREADS;
1361 err = db_sequence_create(&self->sequence, self->mydb->db, flags);
1362 MYDB_END_ALLOW_THREADS;
1363 if (makeDBError(err)) {
Gregory P. Smith664782e2008-05-17 06:12:02 +00001364 Py_DECREF(self);
Gregory P. Smithf0547d02006-06-05 17:38:04 +00001365 self = NULL;
1366 }
1367
1368 return self;
1369}
1370
Jesus Ceaef9764f2008-05-13 18:45:46 +00001371/* Forward declaration */
1372static PyObject
1373*DBSequence_close_internal(DBSequenceObject* self, int flags, int do_not_close);
Gregory P. Smithf0547d02006-06-05 17:38:04 +00001374
1375static void
1376DBSequence_dealloc(DBSequenceObject* self)
1377{
Jesus Ceaef9764f2008-05-13 18:45:46 +00001378 PyObject *dummy;
1379
1380 if (self->sequence != NULL) {
1381 dummy=DBSequence_close_internal(self,0,0);
Jesus Cea5cd5f122008-09-23 18:54:08 +00001382 /*
1383 ** Raising exceptions while doing
1384 ** garbage collection is a fatal error.
1385 */
1386 if (dummy)
1387 Py_DECREF(dummy);
1388 else
1389 PyErr_Clear();
Jesus Ceaef9764f2008-05-13 18:45:46 +00001390 }
1391
Gregory P. Smithf0547d02006-06-05 17:38:04 +00001392 if (self->in_weakreflist != NULL) {
1393 PyObject_ClearWeakRefs((PyObject *) self);
1394 }
Gregory P. Smithf0547d02006-06-05 17:38:04 +00001395
1396 Py_DECREF(self->mydb);
1397 PyObject_Del(self);
1398}
1399#endif
1400
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001401/* --------------------------------------------------------------------- */
1402/* DB methods */
1403
1404static PyObject*
Jesus Cea4907d272008-08-31 14:00:51 +00001405DB_append(DBObject* self, PyObject* args, PyObject* kwargs)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001406{
1407 PyObject* txnobj = NULL;
1408 PyObject* dataobj;
1409 db_recno_t recno;
1410 DBT key, data;
1411 DB_TXN *txn = NULL;
Jesus Cea4907d272008-08-31 14:00:51 +00001412 static char* kwnames[] = { "data", "txn", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001413
Jesus Cea4907d272008-08-31 14:00:51 +00001414 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O:append", kwnames,
1415 &dataobj, &txnobj))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001416 return NULL;
1417
1418 CHECK_DB_NOT_CLOSED(self);
1419
1420 /* make a dummy key out of a recno */
1421 recno = 0;
1422 CLEAR_DBT(key);
1423 key.data = &recno;
1424 key.size = sizeof(recno);
1425 key.ulen = key.size;
1426 key.flags = DB_DBT_USERMEM;
1427
1428 if (!make_dbt(dataobj, &data)) return NULL;
1429 if (!checkTxnObj(txnobj, &txn)) return NULL;
1430
1431 if (-1 == _DB_put(self, txn, &key, &data, DB_APPEND))
1432 return NULL;
1433
Jesus Ceac5a11fa2008-07-23 11:38:42 +00001434 return NUMBER_FromLong(recno);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001435}
1436
1437
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001438static int
Barry Warsaw9a0d7792002-12-30 20:53:52 +00001439_db_associateCallback(DB* db, const DBT* priKey, const DBT* priData,
1440 DBT* secKey)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001441{
1442 int retval = DB_DONOTINDEX;
1443 DBObject* secondaryDB = (DBObject*)db->app_private;
1444 PyObject* callback = secondaryDB->associateCallback;
1445 int type = secondaryDB->primaryDBType;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001446 PyObject* args;
Thomas Wouters89ba3812006-03-07 14:14:51 +00001447 PyObject* result = NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001448
1449
1450 if (callback != NULL) {
1451 MYDB_BEGIN_BLOCK_THREADS;
1452
Thomas Woutersb3153832006-03-08 01:47:19 +00001453 if (type == DB_RECNO || type == DB_QUEUE)
Jesus Ceaef9764f2008-05-13 18:45:46 +00001454 args = BuildValue_LS(*((db_recno_t*)priKey->data), priData->data, priData->size);
Thomas Woutersb3153832006-03-08 01:47:19 +00001455 else
Jesus Ceaef9764f2008-05-13 18:45:46 +00001456 args = BuildValue_SS(priKey->data, priKey->size, priData->data, priData->size);
Thomas Wouters098f6942006-03-07 14:13:17 +00001457 if (args != NULL) {
Thomas Wouters098f6942006-03-07 14:13:17 +00001458 result = PyEval_CallObject(callback, args);
1459 }
1460 if (args == NULL || result == NULL) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001461 PyErr_Print();
1462 }
1463 else if (result == Py_None) {
1464 retval = DB_DONOTINDEX;
1465 }
Jesus Ceac5a11fa2008-07-23 11:38:42 +00001466 else if (NUMBER_Check(result)) {
1467 retval = NUMBER_AsLong(result);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001468 }
Christian Heimes593daf52008-05-26 12:51:38 +00001469 else if (PyBytes_Check(result)) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001470 char* data;
Martin v. Löwis18e16552006-02-15 17:27:45 +00001471 Py_ssize_t size;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001472
1473 CLEAR_DBT(*secKey);
Christian Heimes593daf52008-05-26 12:51:38 +00001474 PyBytes_AsStringAndSize(result, &data, &size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001475 secKey->flags = DB_DBT_APPMALLOC; /* DB will free */
1476 secKey->data = malloc(size); /* TODO, check this */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001477 if (secKey->data) {
1478 memcpy(secKey->data, data, size);
1479 secKey->size = size;
1480 retval = 0;
1481 }
1482 else {
1483 PyErr_SetString(PyExc_MemoryError,
Barry Warsaw9a0d7792002-12-30 20:53:52 +00001484 "malloc failed in _db_associateCallback");
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001485 PyErr_Print();
1486 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001487 }
Jesus Cea6557aac2010-03-22 14:22:26 +00001488#if (DBVER >= 46)
1489 else if (PyList_Check(result))
1490 {
1491 char* data;
1492 Py_ssize_t size;
1493 int i, listlen;
1494 DBT* dbts;
1495
1496 listlen = PyList_Size(result);
1497
1498 dbts = (DBT *)malloc(sizeof(DBT) * listlen);
1499
1500 for (i=0; i<listlen; i++)
1501 {
1502 if (!PyBytes_Check(PyList_GetItem(result, i)))
1503 {
1504 PyErr_SetString(
1505 PyExc_TypeError,
1506#if (PY_VERSION_HEX < 0x03000000)
1507"The list returned by DB->associate callback should be a list of strings.");
1508#else
1509"The list returned by DB->associate callback should be a list of bytes.");
1510#endif
1511 PyErr_Print();
1512 }
1513
1514 PyBytes_AsStringAndSize(
1515 PyList_GetItem(result, i),
1516 &data, &size);
1517
1518 CLEAR_DBT(dbts[i]);
1519 dbts[i].data = malloc(size); /* TODO, check this */
1520
1521 if (dbts[i].data)
1522 {
1523 memcpy(dbts[i].data, data, size);
1524 dbts[i].size = size;
1525 dbts[i].ulen = dbts[i].size;
1526 dbts[i].flags = DB_DBT_APPMALLOC; /* DB will free */
1527 }
1528 else
1529 {
1530 PyErr_SetString(PyExc_MemoryError,
1531 "malloc failed in _db_associateCallback (list)");
1532 PyErr_Print();
1533 }
1534 }
1535
1536 CLEAR_DBT(*secKey);
1537
1538 secKey->data = dbts;
1539 secKey->size = listlen;
1540 secKey->flags = DB_DBT_APPMALLOC | DB_DBT_MULTIPLE;
1541 retval = 0;
1542 }
1543#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001544 else {
Barry Warsaw9a0d7792002-12-30 20:53:52 +00001545 PyErr_SetString(
1546 PyExc_TypeError,
Jesus Cea6557aac2010-03-22 14:22:26 +00001547#if (PY_VERSION_HEX < 0x03000000)
1548"DB associate callback should return DB_DONOTINDEX/string/list of strings.");
1549#else
1550"DB associate callback should return DB_DONOTINDEX/bytes/list of bytes.");
1551#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001552 PyErr_Print();
1553 }
1554
Thomas Woutersb3153832006-03-08 01:47:19 +00001555 Py_XDECREF(args);
1556 Py_XDECREF(result);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001557
1558 MYDB_END_BLOCK_THREADS;
1559 }
1560 return retval;
1561}
1562
1563
1564static PyObject*
1565DB_associate(DBObject* self, PyObject* args, PyObject* kwargs)
1566{
1567 int err, flags=0;
1568 DBObject* secondaryDB;
1569 PyObject* callback;
Barry Warsaw9a0d7792002-12-30 20:53:52 +00001570 PyObject *txnobj = NULL;
1571 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00001572 static char* kwnames[] = {"secondaryDB", "callback", "flags", "txn",
Jeremy Hyltonaf68c872005-12-10 18:50:16 +00001573 NULL};
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001574
Barry Warsaw9a0d7792002-12-30 20:53:52 +00001575 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|iO:associate", kwnames,
1576 &secondaryDB, &callback, &flags,
1577 &txnobj)) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001578 return NULL;
Barry Warsaw9a0d7792002-12-30 20:53:52 +00001579 }
1580
Barry Warsaw9a0d7792002-12-30 20:53:52 +00001581 if (!checkTxnObj(txnobj, &txn)) return NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001582
1583 CHECK_DB_NOT_CLOSED(self);
1584 if (!DBObject_Check(secondaryDB)) {
1585 makeTypeError("DB", (PyObject*)secondaryDB);
1586 return NULL;
1587 }
Gregory P. Smith91116b62005-06-06 10:28:06 +00001588 CHECK_DB_NOT_CLOSED(secondaryDB);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001589 if (callback == Py_None) {
1590 callback = NULL;
1591 }
1592 else if (!PyCallable_Check(callback)) {
1593 makeTypeError("Callable", callback);
1594 return NULL;
1595 }
1596
1597 /* Save a reference to the callback in the secondary DB. */
Gregory P. Smith692ca9a2005-06-06 09:55:06 +00001598 Py_XDECREF(secondaryDB->associateCallback);
Thomas Woutersb3153832006-03-08 01:47:19 +00001599 Py_XINCREF(callback);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001600 secondaryDB->associateCallback = callback;
1601 secondaryDB->primaryDBType = _DB_get_type(self);
1602
Martin v. Löwisb2c7aff2002-11-23 11:26:07 +00001603 /* PyEval_InitThreads is called here due to a quirk in python 1.5
1604 * - 2.2.1 (at least) according to Russell Williamson <merel@wt.net>:
1605 * The global interepreter lock is not initialized until the first
1606 * thread is created using thread.start_new_thread() or fork() is
1607 * called. that would cause the ALLOW_THREADS here to segfault due
1608 * to a null pointer reference if no threads or child processes
1609 * have been created. This works around that and is a no-op if
1610 * threads have already been initialized.
1611 * (see pybsddb-users mailing list post on 2002-08-07)
1612 */
Gregory P. Smithaa71f5f2003-01-17 07:56:16 +00001613#ifdef WITH_THREAD
Martin v. Löwisb2c7aff2002-11-23 11:26:07 +00001614 PyEval_InitThreads();
Gregory P. Smithaa71f5f2003-01-17 07:56:16 +00001615#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001616 MYDB_BEGIN_ALLOW_THREADS;
Barry Warsaw9a0d7792002-12-30 20:53:52 +00001617 err = self->db->associate(self->db,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001618 txn,
Barry Warsaw9a0d7792002-12-30 20:53:52 +00001619 secondaryDB->db,
1620 _db_associateCallback,
1621 flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001622 MYDB_END_ALLOW_THREADS;
1623
1624 if (err) {
Gregory P. Smith692ca9a2005-06-06 09:55:06 +00001625 Py_XDECREF(secondaryDB->associateCallback);
1626 secondaryDB->associateCallback = NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001627 secondaryDB->primaryDBType = 0;
1628 }
1629
1630 RETURN_IF_ERR();
1631 RETURN_NONE();
1632}
1633
1634
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001635static PyObject*
Jesus Cea5cd5f122008-09-23 18:54:08 +00001636DB_close_internal(DBObject* self, int flags, int do_not_close)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001637{
Jesus Ceaef9764f2008-05-13 18:45:46 +00001638 PyObject *dummy;
Jesus Cea5cd5f122008-09-23 18:54:08 +00001639 int err = 0;
Jesus Ceaef9764f2008-05-13 18:45:46 +00001640
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001641 if (self->db != NULL) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00001642 /* Can be NULL if db is not in an environment */
1643 EXTRACT_FROM_DOUBLE_LINKED_LIST_MAYBE_NULL(self);
Jesus Cea4907d272008-08-31 14:00:51 +00001644
Jesus Ceaef9764f2008-05-13 18:45:46 +00001645 if (self->txn) {
1646 EXTRACT_FROM_DOUBLE_LINKED_LIST_TXN(self);
1647 self->txn=NULL;
1648 }
1649
1650 while(self->children_cursors) {
1651 dummy=DBC_close_internal(self->children_cursors);
1652 Py_XDECREF(dummy);
1653 }
1654
1655#if (DBVER >= 43)
1656 while(self->children_sequences) {
1657 dummy=DBSequence_close_internal(self->children_sequences,0,0);
1658 Py_XDECREF(dummy);
1659 }
1660#endif
1661
Jesus Cea5cd5f122008-09-23 18:54:08 +00001662 /*
1663 ** "do_not_close" is used to dispose all related objects in the
1664 ** tree, without actually releasing the "root" object.
1665 ** This is done, for example, because function calls like
1666 ** "DB.verify()" implicitly close the underlying handle. So
1667 ** the handle doesn't need to be closed, but related objects
1668 ** must be cleaned up.
1669 */
1670 if (!do_not_close) {
1671 MYDB_BEGIN_ALLOW_THREADS;
1672 err = self->db->close(self->db, flags);
1673 MYDB_END_ALLOW_THREADS;
1674 self->db = NULL;
1675 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001676 RETURN_IF_ERR();
1677 }
1678 RETURN_NONE();
1679}
1680
Jesus Ceaef9764f2008-05-13 18:45:46 +00001681static PyObject*
1682DB_close(DBObject* self, PyObject* args)
1683{
1684 int flags=0;
1685 if (!PyArg_ParseTuple(args,"|i:close", &flags))
1686 return NULL;
Jesus Cea5cd5f122008-09-23 18:54:08 +00001687 return DB_close_internal(self, flags, 0);
Jesus Ceaef9764f2008-05-13 18:45:46 +00001688}
1689
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001690
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001691static PyObject*
1692_DB_consume(DBObject* self, PyObject* args, PyObject* kwargs, int consume_flag)
1693{
1694 int err, flags=0, type;
1695 PyObject* txnobj = NULL;
1696 PyObject* retval = NULL;
1697 DBT key, data;
1698 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00001699 static char* kwnames[] = { "txn", "flags", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001700
1701 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Oi:consume", kwnames,
1702 &txnobj, &flags))
1703 return NULL;
1704
1705 CHECK_DB_NOT_CLOSED(self);
1706 type = _DB_get_type(self);
1707 if (type == -1)
1708 return NULL;
1709 if (type != DB_QUEUE) {
Barry Warsaw9a0d7792002-12-30 20:53:52 +00001710 PyErr_SetString(PyExc_TypeError,
1711 "Consume methods only allowed for Queue DB's");
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001712 return NULL;
1713 }
1714 if (!checkTxnObj(txnobj, &txn))
1715 return NULL;
1716
1717 CLEAR_DBT(key);
1718 CLEAR_DBT(data);
1719 if (CHECK_DBFLAG(self, DB_THREAD)) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00001720 /* Tell Berkeley DB to malloc the return value (thread safe) */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001721 data.flags = DB_DBT_MALLOC;
1722 key.flags = DB_DBT_MALLOC;
1723 }
1724
1725 MYDB_BEGIN_ALLOW_THREADS;
1726 err = self->db->get(self->db, txn, &key, &data, flags|consume_flag);
1727 MYDB_END_ALLOW_THREADS;
1728
Gregory P. Smithe9477062005-06-04 06:46:59 +00001729 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001730 && self->moduleFlags.getReturnsNone) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001731 err = 0;
1732 Py_INCREF(Py_None);
1733 retval = Py_None;
1734 }
1735 else if (!err) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00001736 retval = BuildValue_SS(key.data, key.size, data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001737 FREE_DBT(key);
1738 FREE_DBT(data);
1739 }
1740
1741 RETURN_IF_ERR();
1742 return retval;
1743}
1744
1745static PyObject*
1746DB_consume(DBObject* self, PyObject* args, PyObject* kwargs, int consume_flag)
1747{
1748 return _DB_consume(self, args, kwargs, DB_CONSUME);
1749}
1750
1751static PyObject*
Barry Warsaw9a0d7792002-12-30 20:53:52 +00001752DB_consume_wait(DBObject* self, PyObject* args, PyObject* kwargs,
1753 int consume_flag)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001754{
1755 return _DB_consume(self, args, kwargs, DB_CONSUME_WAIT);
1756}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001757
1758
1759static PyObject*
1760DB_cursor(DBObject* self, PyObject* args, PyObject* kwargs)
1761{
1762 int err, flags=0;
1763 DBC* dbc;
1764 PyObject* txnobj = NULL;
1765 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00001766 static char* kwnames[] = { "txn", "flags", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001767
1768 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Oi:cursor", kwnames,
1769 &txnobj, &flags))
1770 return NULL;
1771 CHECK_DB_NOT_CLOSED(self);
1772 if (!checkTxnObj(txnobj, &txn))
1773 return NULL;
1774
1775 MYDB_BEGIN_ALLOW_THREADS;
1776 err = self->db->cursor(self->db, txn, &dbc, flags);
1777 MYDB_END_ALLOW_THREADS;
1778 RETURN_IF_ERR();
Jesus Ceaef9764f2008-05-13 18:45:46 +00001779 return (PyObject*) newDBCursorObject(dbc, (DBTxnObject *)txnobj, self);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001780}
1781
1782
1783static PyObject*
1784DB_delete(DBObject* self, PyObject* args, PyObject* kwargs)
1785{
1786 PyObject* txnobj = NULL;
1787 int flags = 0;
1788 PyObject* keyobj;
1789 DBT key;
1790 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00001791 static char* kwnames[] = { "key", "txn", "flags", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001792
1793 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|Oi:delete", kwnames,
1794 &keyobj, &txnobj, &flags))
1795 return NULL;
1796 CHECK_DB_NOT_CLOSED(self);
1797 if (!make_key_dbt(self, keyobj, &key, NULL))
1798 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00001799 if (!checkTxnObj(txnobj, &txn)) {
1800 FREE_DBT(key);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001801 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00001802 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001803
Gregory P. Smithdc5af702004-06-27 23:32:34 +00001804 if (-1 == _DB_delete(self, txn, &key, 0)) {
1805 FREE_DBT(key);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001806 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00001807 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001808
1809 FREE_DBT(key);
1810 RETURN_NONE();
1811}
1812
1813
Jesus Cea6557aac2010-03-22 14:22:26 +00001814#if (DBVER >= 47)
1815/*
1816** This function is available since Berkeley DB 4.4,
1817** but 4.6 version is so buggy that we only support
1818** it from BDB 4.7 and newer.
1819*/
1820static PyObject*
1821DB_compact(DBObject* self, PyObject* args, PyObject* kwargs)
1822{
1823 PyObject* txnobj = NULL;
1824 PyObject *startobj = NULL, *stopobj = NULL;
1825 int flags = 0;
1826 DB_TXN *txn = NULL;
1827 DBT *start_p = NULL, *stop_p = NULL;
1828 DBT start, stop;
1829 int err;
1830 DB_COMPACT c_data = { 0 };
1831 static char* kwnames[] = { "txn", "start", "stop", "flags",
1832 "compact_fillpercent", "compact_pages",
1833 "compact_timeout", NULL };
1834
1835
1836 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OOOiiiI:compact", kwnames,
1837 &txnobj, &startobj, &stopobj, &flags,
1838 &c_data.compact_fillpercent,
1839 &c_data.compact_pages,
1840 &c_data.compact_timeout))
1841 return NULL;
1842
1843 CHECK_DB_NOT_CLOSED(self);
1844 if (!checkTxnObj(txnobj, &txn)) {
1845 return NULL;
1846 }
1847
1848 if (startobj && make_key_dbt(self, startobj, &start, NULL)) {
1849 start_p = &start;
1850 }
1851 if (stopobj && make_key_dbt(self, stopobj, &stop, NULL)) {
1852 stop_p = &stop;
1853 }
1854
1855 MYDB_BEGIN_ALLOW_THREADS;
1856 err = self->db->compact(self->db, txn, start_p, stop_p, &c_data,
1857 flags, NULL);
1858 MYDB_END_ALLOW_THREADS;
1859
1860 if (startobj)
1861 FREE_DBT(start);
1862 if (stopobj)
1863 FREE_DBT(stop);
1864
1865 RETURN_IF_ERR();
1866
1867 return PyLong_FromUnsignedLong(c_data.compact_pages_truncated);
1868}
1869#endif
1870
1871
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001872static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00001873DB_fd(DBObject* self)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001874{
1875 int err, the_fd;
1876
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001877 CHECK_DB_NOT_CLOSED(self);
1878
1879 MYDB_BEGIN_ALLOW_THREADS;
1880 err = self->db->fd(self->db, &the_fd);
1881 MYDB_END_ALLOW_THREADS;
1882 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00001883 return NUMBER_FromLong(the_fd);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001884}
1885
1886
Jesus Cea6557aac2010-03-22 14:22:26 +00001887#if (DBVER >= 46)
1888static PyObject*
1889DB_exists(DBObject* self, PyObject* args, PyObject* kwargs)
1890{
1891 int err, flags=0;
1892 PyObject* txnobj = NULL;
1893 PyObject* keyobj;
1894 DBT key;
1895 DB_TXN *txn;
1896
1897 static char* kwnames[] = {"key", "txn", "flags", NULL};
1898
1899 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|Oi:exists", kwnames,
1900 &keyobj, &txnobj, &flags))
1901 return NULL;
1902
1903 CHECK_DB_NOT_CLOSED(self);
1904 if (!make_key_dbt(self, keyobj, &key, NULL))
1905 return NULL;
1906 if (!checkTxnObj(txnobj, &txn)) {
1907 FREE_DBT(key);
1908 return NULL;
1909 }
1910
1911 MYDB_BEGIN_ALLOW_THREADS;
1912 err = self->db->exists(self->db, txn, &key, flags);
1913 MYDB_END_ALLOW_THREADS;
1914
1915 FREE_DBT(key);
1916
1917 if (!err) {
1918 Py_INCREF(Py_True);
1919 return Py_True;
1920 }
1921 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)) {
1922 Py_INCREF(Py_False);
1923 return Py_False;
1924 }
1925
1926 /*
1927 ** If we reach there, there was an error. The
1928 ** "return" should be unreachable.
1929 */
1930 RETURN_IF_ERR();
1931 assert(0); /* This coude SHOULD be unreachable */
1932 return NULL;
1933}
1934#endif
1935
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001936static PyObject*
1937DB_get(DBObject* self, PyObject* args, PyObject* kwargs)
1938{
1939 int err, flags=0;
1940 PyObject* txnobj = NULL;
1941 PyObject* keyobj;
1942 PyObject* dfltobj = NULL;
1943 PyObject* retval = NULL;
1944 int dlen = -1;
1945 int doff = -1;
1946 DBT key, data;
1947 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00001948 static char* kwnames[] = {"key", "default", "txn", "flags", "dlen",
Jeremy Hyltonaf68c872005-12-10 18:50:16 +00001949 "doff", NULL};
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001950
1951 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|OOiii:get", kwnames,
Barry Warsaw9a0d7792002-12-30 20:53:52 +00001952 &keyobj, &dfltobj, &txnobj, &flags, &dlen,
1953 &doff))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001954 return NULL;
1955
1956 CHECK_DB_NOT_CLOSED(self);
1957 if (!make_key_dbt(self, keyobj, &key, &flags))
1958 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00001959 if (!checkTxnObj(txnobj, &txn)) {
1960 FREE_DBT(key);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001961 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00001962 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001963
1964 CLEAR_DBT(data);
1965 if (CHECK_DBFLAG(self, DB_THREAD)) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00001966 /* Tell Berkeley DB to malloc the return value (thread safe) */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001967 data.flags = DB_DBT_MALLOC;
1968 }
Gregory P. Smithdc5af702004-06-27 23:32:34 +00001969 if (!add_partial_dbt(&data, dlen, doff)) {
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 MYDB_BEGIN_ALLOW_THREADS;
1975 err = self->db->get(self->db, txn, &key, &data, flags);
1976 MYDB_END_ALLOW_THREADS;
1977
Gregory P. Smithe9477062005-06-04 06:46:59 +00001978 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY) && (dfltobj != NULL)) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001979 err = 0;
1980 Py_INCREF(dfltobj);
1981 retval = dfltobj;
1982 }
Gregory P. Smithe9477062005-06-04 06:46:59 +00001983 else if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001984 && self->moduleFlags.getReturnsNone) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001985 err = 0;
1986 Py_INCREF(Py_None);
1987 retval = Py_None;
1988 }
1989 else if (!err) {
1990 if (flags & DB_SET_RECNO) /* return both key and data */
Jesus Ceaef9764f2008-05-13 18:45:46 +00001991 retval = BuildValue_SS(key.data, key.size, data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001992 else /* return just the data */
Jesus Ceaef9764f2008-05-13 18:45:46 +00001993 retval = Build_PyString(data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001994 FREE_DBT(data);
1995 }
Gregory P. Smithdc5af702004-06-27 23:32:34 +00001996 FREE_DBT(key);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001997
1998 RETURN_IF_ERR();
1999 return retval;
2000}
2001
Gregory P. Smith19699a92004-06-28 04:06:49 +00002002static PyObject*
2003DB_pget(DBObject* self, PyObject* args, PyObject* kwargs)
2004{
2005 int err, flags=0;
2006 PyObject* txnobj = NULL;
2007 PyObject* keyobj;
2008 PyObject* dfltobj = NULL;
2009 PyObject* retval = NULL;
2010 int dlen = -1;
2011 int doff = -1;
2012 DBT key, pkey, data;
2013 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002014 static char* kwnames[] = {"key", "default", "txn", "flags", "dlen",
Jeremy Hyltonaf68c872005-12-10 18:50:16 +00002015 "doff", NULL};
Gregory P. Smith19699a92004-06-28 04:06:49 +00002016
2017 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|OOiii:pget", kwnames,
2018 &keyobj, &dfltobj, &txnobj, &flags, &dlen,
2019 &doff))
2020 return NULL;
2021
2022 CHECK_DB_NOT_CLOSED(self);
2023 if (!make_key_dbt(self, keyobj, &key, &flags))
2024 return NULL;
2025 if (!checkTxnObj(txnobj, &txn)) {
2026 FREE_DBT(key);
2027 return NULL;
2028 }
2029
2030 CLEAR_DBT(data);
2031 if (CHECK_DBFLAG(self, DB_THREAD)) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00002032 /* Tell Berkeley DB to malloc the return value (thread safe) */
Gregory P. Smith19699a92004-06-28 04:06:49 +00002033 data.flags = DB_DBT_MALLOC;
2034 }
2035 if (!add_partial_dbt(&data, dlen, doff)) {
2036 FREE_DBT(key);
2037 return NULL;
2038 }
2039
2040 CLEAR_DBT(pkey);
2041 pkey.flags = DB_DBT_MALLOC;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002042
Gregory P. Smith19699a92004-06-28 04:06:49 +00002043 MYDB_BEGIN_ALLOW_THREADS;
2044 err = self->db->pget(self->db, txn, &key, &pkey, &data, flags);
2045 MYDB_END_ALLOW_THREADS;
2046
Gregory P. Smithe9477062005-06-04 06:46:59 +00002047 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY) && (dfltobj != NULL)) {
Gregory P. Smith19699a92004-06-28 04:06:49 +00002048 err = 0;
2049 Py_INCREF(dfltobj);
2050 retval = dfltobj;
2051 }
Gregory P. Smithe9477062005-06-04 06:46:59 +00002052 else if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002053 && self->moduleFlags.getReturnsNone) {
Gregory P. Smith19699a92004-06-28 04:06:49 +00002054 err = 0;
2055 Py_INCREF(Py_None);
2056 retval = Py_None;
2057 }
2058 else if (!err) {
2059 PyObject *pkeyObj;
2060 PyObject *dataObj;
Jesus Ceaef9764f2008-05-13 18:45:46 +00002061 dataObj = Build_PyString(data.data, data.size);
Gregory P. Smith19699a92004-06-28 04:06:49 +00002062
2063 if (self->primaryDBType == DB_RECNO ||
2064 self->primaryDBType == DB_QUEUE)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002065 pkeyObj = NUMBER_FromLong(*(int *)pkey.data);
Gregory P. Smith19699a92004-06-28 04:06:49 +00002066 else
Jesus Ceaef9764f2008-05-13 18:45:46 +00002067 pkeyObj = Build_PyString(pkey.data, pkey.size);
Gregory P. Smith19699a92004-06-28 04:06:49 +00002068
2069 if (flags & DB_SET_RECNO) /* return key , pkey and data */
2070 {
2071 PyObject *keyObj;
2072 int type = _DB_get_type(self);
2073 if (type == DB_RECNO || type == DB_QUEUE)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002074 keyObj = NUMBER_FromLong(*(int *)key.data);
Gregory P. Smith19699a92004-06-28 04:06:49 +00002075 else
Jesus Ceaef9764f2008-05-13 18:45:46 +00002076 keyObj = Build_PyString(key.data, key.size);
Gregory P. Smithfd049a62006-01-30 00:22:08 +00002077#if (PY_VERSION_HEX >= 0x02040000)
Gregory P. Smith4e414d82006-01-24 19:55:02 +00002078 retval = PyTuple_Pack(3, keyObj, pkeyObj, dataObj);
Gregory P. Smithfd049a62006-01-30 00:22:08 +00002079#else
2080 retval = Py_BuildValue("OOO", keyObj, pkeyObj, dataObj);
2081#endif
Thomas Woutersb3153832006-03-08 01:47:19 +00002082 Py_DECREF(keyObj);
Gregory P. Smith19699a92004-06-28 04:06:49 +00002083 }
2084 else /* return just the pkey and data */
2085 {
Gregory P. Smithfd049a62006-01-30 00:22:08 +00002086#if (PY_VERSION_HEX >= 0x02040000)
Gregory P. Smith4e414d82006-01-24 19:55:02 +00002087 retval = PyTuple_Pack(2, pkeyObj, dataObj);
Gregory P. Smithfd049a62006-01-30 00:22:08 +00002088#else
2089 retval = Py_BuildValue("OO", pkeyObj, dataObj);
2090#endif
Gregory P. Smith19699a92004-06-28 04:06:49 +00002091 }
Thomas Woutersb3153832006-03-08 01:47:19 +00002092 Py_DECREF(dataObj);
2093 Py_DECREF(pkeyObj);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002094 FREE_DBT(pkey);
Gregory P. Smith19699a92004-06-28 04:06:49 +00002095 FREE_DBT(data);
2096 }
2097 FREE_DBT(key);
2098
2099 RETURN_IF_ERR();
2100 return retval;
2101}
2102
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002103
2104/* Return size of entry */
2105static PyObject*
2106DB_get_size(DBObject* self, PyObject* args, PyObject* kwargs)
2107{
2108 int err, flags=0;
2109 PyObject* txnobj = NULL;
2110 PyObject* keyobj;
2111 PyObject* retval = NULL;
2112 DBT key, data;
2113 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002114 static char* kwnames[] = { "key", "txn", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002115
2116 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O:get_size", kwnames,
2117 &keyobj, &txnobj))
2118 return NULL;
2119 CHECK_DB_NOT_CLOSED(self);
2120 if (!make_key_dbt(self, keyobj, &key, &flags))
2121 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00002122 if (!checkTxnObj(txnobj, &txn)) {
2123 FREE_DBT(key);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002124 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00002125 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002126 CLEAR_DBT(data);
2127
Gregory P. Smith8b7e9172004-12-13 09:51:23 +00002128 /* We don't allocate any memory, forcing a DB_BUFFER_SMALL error and
2129 thus getting the record size. */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002130 data.flags = DB_DBT_USERMEM;
2131 data.ulen = 0;
2132 MYDB_BEGIN_ALLOW_THREADS;
2133 err = self->db->get(self->db, txn, &key, &data, flags);
2134 MYDB_END_ALLOW_THREADS;
Gregory P. Smith8b7e9172004-12-13 09:51:23 +00002135 if (err == DB_BUFFER_SMALL) {
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002136 retval = NUMBER_FromLong((long)data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002137 err = 0;
2138 }
2139
2140 FREE_DBT(key);
2141 FREE_DBT(data);
2142 RETURN_IF_ERR();
2143 return retval;
2144}
2145
2146
2147static PyObject*
2148DB_get_both(DBObject* self, PyObject* args, PyObject* kwargs)
2149{
2150 int err, flags=0;
2151 PyObject* txnobj = NULL;
2152 PyObject* keyobj;
2153 PyObject* dataobj;
2154 PyObject* retval = NULL;
2155 DBT key, data;
Neal Norwitz994ebed2007-06-03 20:32:50 +00002156 void *orig_data;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002157 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002158 static char* kwnames[] = { "key", "data", "txn", "flags", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002159
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002160 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|Oi:get_both", kwnames,
2161 &keyobj, &dataobj, &txnobj, &flags))
2162 return NULL;
2163
2164 CHECK_DB_NOT_CLOSED(self);
2165 if (!make_key_dbt(self, keyobj, &key, NULL))
2166 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00002167 if ( !make_dbt(dataobj, &data) ||
2168 !checkTxnObj(txnobj, &txn) )
2169 {
2170 FREE_DBT(key);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002171 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00002172 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002173
2174 flags |= DB_GET_BOTH;
Neal Norwitz994ebed2007-06-03 20:32:50 +00002175 orig_data = data.data;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002176
2177 if (CHECK_DBFLAG(self, DB_THREAD)) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00002178 /* Tell Berkeley DB to malloc the return value (thread safe) */
Neal Norwitz994ebed2007-06-03 20:32:50 +00002179 /* XXX(nnorwitz): At least 4.4.20 and 4.5.20 require this flag. */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002180 data.flags = DB_DBT_MALLOC;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002181 }
2182
2183 MYDB_BEGIN_ALLOW_THREADS;
2184 err = self->db->get(self->db, txn, &key, &data, flags);
2185 MYDB_END_ALLOW_THREADS;
2186
Gregory P. Smithe9477062005-06-04 06:46:59 +00002187 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002188 && self->moduleFlags.getReturnsNone) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002189 err = 0;
2190 Py_INCREF(Py_None);
2191 retval = Py_None;
2192 }
2193 else if (!err) {
Neal Norwitz994ebed2007-06-03 20:32:50 +00002194 /* XXX(nnorwitz): can we do: retval = dataobj; Py_INCREF(retval); */
Jesus Ceaef9764f2008-05-13 18:45:46 +00002195 retval = Build_PyString(data.data, data.size);
Neal Norwitz994ebed2007-06-03 20:32:50 +00002196
2197 /* Even though the flags require DB_DBT_MALLOC, data is not always
2198 allocated. 4.4: allocated, 4.5: *not* allocated. :-( */
2199 if (data.data != orig_data)
2200 FREE_DBT(data);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002201 }
2202
2203 FREE_DBT(key);
2204 RETURN_IF_ERR();
2205 return retval;
2206}
2207
2208
2209static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002210DB_get_byteswapped(DBObject* self)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002211{
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002212 int err = 0;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002213 int retval = -1;
2214
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002215 CHECK_DB_NOT_CLOSED(self);
2216
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002217 MYDB_BEGIN_ALLOW_THREADS;
2218 err = self->db->get_byteswapped(self->db, &retval);
2219 MYDB_END_ALLOW_THREADS;
2220 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002221 return NUMBER_FromLong(retval);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002222}
2223
2224
2225static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002226DB_get_type(DBObject* self)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002227{
2228 int type;
2229
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002230 CHECK_DB_NOT_CLOSED(self);
2231
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002232 type = _DB_get_type(self);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002233 if (type == -1)
2234 return NULL;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002235 return NUMBER_FromLong(type);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002236}
2237
2238
2239static PyObject*
2240DB_join(DBObject* self, PyObject* args)
2241{
2242 int err, flags=0;
2243 int length, x;
2244 PyObject* cursorsObj;
2245 DBC** cursors;
2246 DBC* dbc;
2247
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002248 if (!PyArg_ParseTuple(args,"O|i:join", &cursorsObj, &flags))
2249 return NULL;
2250
2251 CHECK_DB_NOT_CLOSED(self);
2252
2253 if (!PySequence_Check(cursorsObj)) {
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002254 PyErr_SetString(PyExc_TypeError,
2255 "Sequence of DBCursor objects expected");
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002256 return NULL;
2257 }
2258
2259 length = PyObject_Length(cursorsObj);
2260 cursors = malloc((length+1) * sizeof(DBC*));
Neal Norwitz5aa96892006-08-13 18:11:43 +00002261 if (!cursors) {
Jesus Cea6557aac2010-03-22 14:22:26 +00002262 PyErr_NoMemory();
2263 return NULL;
Neal Norwitz5aa96892006-08-13 18:11:43 +00002264 }
2265
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002266 cursors[length] = NULL;
2267 for (x=0; x<length; x++) {
2268 PyObject* item = PySequence_GetItem(cursorsObj, x);
Thomas Woutersb3153832006-03-08 01:47:19 +00002269 if (item == NULL) {
2270 free(cursors);
2271 return NULL;
2272 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002273 if (!DBCursorObject_Check(item)) {
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002274 PyErr_SetString(PyExc_TypeError,
2275 "Sequence of DBCursor objects expected");
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002276 free(cursors);
2277 return NULL;
2278 }
2279 cursors[x] = ((DBCursorObject*)item)->dbc;
Thomas Woutersb2820ae2006-03-12 00:01:38 +00002280 Py_DECREF(item);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002281 }
2282
2283 MYDB_BEGIN_ALLOW_THREADS;
2284 err = self->db->join(self->db, cursors, &dbc, flags);
2285 MYDB_END_ALLOW_THREADS;
2286 free(cursors);
2287 RETURN_IF_ERR();
2288
Gregory P. Smith7441e652003-11-03 21:35:31 +00002289 /* FIXME: this is a buggy interface. The returned cursor
2290 contains internal references to the passed in cursors
2291 but does not hold python references to them or prevent
2292 them from being closed prematurely. This can cause
2293 python to crash when things are done in the wrong order. */
Jesus Ceaef9764f2008-05-13 18:45:46 +00002294 return (PyObject*) newDBCursorObject(dbc, NULL, self);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002295}
2296
2297
2298static PyObject*
2299DB_key_range(DBObject* self, PyObject* args, PyObject* kwargs)
2300{
2301 int err, flags=0;
2302 PyObject* txnobj = NULL;
2303 PyObject* keyobj;
2304 DBT key;
2305 DB_TXN *txn = NULL;
2306 DB_KEY_RANGE range;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002307 static char* kwnames[] = { "key", "txn", "flags", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002308
2309 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|Oi:key_range", kwnames,
2310 &keyobj, &txnobj, &flags))
2311 return NULL;
2312 CHECK_DB_NOT_CLOSED(self);
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002313 if (!make_dbt(keyobj, &key))
2314 /* BTree only, don't need to allow for an int key */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002315 return NULL;
2316 if (!checkTxnObj(txnobj, &txn))
2317 return NULL;
2318
2319 MYDB_BEGIN_ALLOW_THREADS;
2320 err = self->db->key_range(self->db, txn, &key, &range, flags);
2321 MYDB_END_ALLOW_THREADS;
2322
2323 RETURN_IF_ERR();
2324 return Py_BuildValue("ddd", range.less, range.equal, range.greater);
2325}
2326
2327
2328static PyObject*
2329DB_open(DBObject* self, PyObject* args, PyObject* kwargs)
2330{
2331 int err, type = DB_UNKNOWN, flags=0, mode=0660;
2332 char* filename = NULL;
2333 char* dbname = NULL;
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002334 PyObject *txnobj = NULL;
2335 DB_TXN *txn = NULL;
2336 /* with dbname */
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002337 static char* kwnames[] = {
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002338 "filename", "dbname", "dbtype", "flags", "mode", "txn", NULL};
2339 /* without dbname */
Tim Peters85b10522006-02-28 18:33:35 +00002340 static char* kwnames_basic[] = {
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002341 "filename", "dbtype", "flags", "mode", "txn", NULL};
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002342
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002343 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "z|ziiiO:open", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002344 &filename, &dbname, &type, &flags, &mode,
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002345 &txnobj))
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002346 {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002347 PyErr_Clear();
2348 type = DB_UNKNOWN; flags = 0; mode = 0660;
2349 filename = NULL; dbname = NULL;
2350 if (!PyArg_ParseTupleAndKeywords(args, kwargs,"z|iiiO:open",
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002351 kwnames_basic,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002352 &filename, &type, &flags, &mode,
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002353 &txnobj))
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002354 return NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002355 }
2356
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002357 if (!checkTxnObj(txnobj, &txn)) return NULL;
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002358
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002359 if (NULL == self->db) {
Thomas Woutersb3153832006-03-08 01:47:19 +00002360 PyObject *t = Py_BuildValue("(is)", 0,
2361 "Cannot call open() twice for DB object");
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002362 if (t) {
2363 PyErr_SetObject(DBError, t);
2364 Py_DECREF(t);
2365 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002366 return NULL;
2367 }
2368
Jesus Ceaef9764f2008-05-13 18:45:46 +00002369 if (txn) { /* Can't use 'txnobj' because could be 'txnobj==Py_None' */
2370 INSERT_IN_DOUBLE_LINKED_LIST_TXN(((DBTxnObject *)txnobj)->children_dbs,self);
2371 self->txn=(DBTxnObject *)txnobj;
2372 } else {
2373 self->txn=NULL;
2374 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00002375
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002376 MYDB_BEGIN_ALLOW_THREADS;
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002377 err = self->db->open(self->db, txn, filename, dbname, type, flags, mode);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002378 MYDB_END_ALLOW_THREADS;
Jesus Cea6557aac2010-03-22 14:22:26 +00002379
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002380 if (makeDBError(err)) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00002381 PyObject *dummy;
2382
Jesus Cea5cd5f122008-09-23 18:54:08 +00002383 dummy=DB_close_internal(self, 0, 0);
Jesus Ceaef9764f2008-05-13 18:45:46 +00002384 Py_XDECREF(dummy);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002385 return NULL;
2386 }
2387
Gregory P. Smithfc006692007-11-05 09:06:28 +00002388#if (DBVER >= 42)
Gregory P. Smithec10a4a2007-11-05 02:32:26 +00002389 self->db->get_flags(self->db, &self->setflags);
Gregory P. Smithfc006692007-11-05 09:06:28 +00002390#endif
Gregory P. Smithec10a4a2007-11-05 02:32:26 +00002391
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_DECREF(self->private_obj);
2503 Py_INCREF(private_obj);
2504 self->private_obj = private_obj;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002505 RETURN_NONE();
2506}
2507
Jesus Cea6557aac2010-03-22 14:22:26 +00002508#if (DBVER >= 46)
2509static PyObject*
2510DB_set_priority(DBObject* self, PyObject* args)
2511{
2512 int err, priority;
2513
2514 if (!PyArg_ParseTuple(args,"i:set_priority", &priority))
2515 return NULL;
2516 CHECK_DB_NOT_CLOSED(self);
2517
2518 MYDB_BEGIN_ALLOW_THREADS;
2519 err = self->db->set_priority(self->db, priority);
2520 MYDB_END_ALLOW_THREADS;
2521 RETURN_IF_ERR();
2522 RETURN_NONE();
2523}
2524
2525static PyObject*
2526DB_get_priority(DBObject* self)
2527{
2528 int err = 0;
2529 DB_CACHE_PRIORITY priority;
2530
2531 CHECK_DB_NOT_CLOSED(self);
2532
2533 MYDB_BEGIN_ALLOW_THREADS;
2534 err = self->db->get_priority(self->db, &priority);
2535 MYDB_END_ALLOW_THREADS;
2536 RETURN_IF_ERR();
2537 return NUMBER_FromLong(priority);
2538}
2539#endif
2540
2541static PyObject*
2542DB_set_q_extentsize(DBObject* self, PyObject* args)
2543{
2544 int err;
2545 u_int32_t extentsize;
2546
2547 if (!PyArg_ParseTuple(args,"i:set_q_extentsize", &extentsize))
2548 return NULL;
2549 CHECK_DB_NOT_CLOSED(self);
2550
2551 MYDB_BEGIN_ALLOW_THREADS;
2552 err = self->db->set_q_extentsize(self->db, extentsize);
2553 MYDB_END_ALLOW_THREADS;
2554 RETURN_IF_ERR();
2555 RETURN_NONE();
2556}
2557
2558#if (DBVER >= 42)
2559static PyObject*
2560DB_get_q_extentsize(DBObject* self)
2561{
2562 int err = 0;
2563 u_int32_t extentsize;
2564
2565 CHECK_DB_NOT_CLOSED(self);
2566
2567 MYDB_BEGIN_ALLOW_THREADS;
2568 err = self->db->get_q_extentsize(self->db, &extentsize);
2569 MYDB_END_ALLOW_THREADS;
2570 RETURN_IF_ERR();
2571 return NUMBER_FromLong(extentsize);
2572}
2573#endif
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002574
2575static PyObject*
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002576DB_set_bt_minkey(DBObject* self, PyObject* args)
2577{
2578 int err, minkey;
2579
Jesus Cea6557aac2010-03-22 14:22:26 +00002580 if (!PyArg_ParseTuple(args,"i:set_bt_minkey", &minkey))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002581 return NULL;
2582 CHECK_DB_NOT_CLOSED(self);
2583
2584 MYDB_BEGIN_ALLOW_THREADS;
2585 err = self->db->set_bt_minkey(self->db, minkey);
2586 MYDB_END_ALLOW_THREADS;
2587 RETURN_IF_ERR();
2588 RETURN_NONE();
2589}
2590
Jesus Cea6557aac2010-03-22 14:22:26 +00002591#if (DBVER >= 42)
2592static PyObject*
2593DB_get_bt_minkey(DBObject* self)
2594{
2595 int err;
2596 u_int32_t bt_minkey;
2597
2598 CHECK_DB_NOT_CLOSED(self);
2599
2600 MYDB_BEGIN_ALLOW_THREADS;
2601 err = self->db->get_bt_minkey(self->db, &bt_minkey);
2602 MYDB_END_ALLOW_THREADS;
2603 RETURN_IF_ERR();
2604 return NUMBER_FromLong(bt_minkey);
2605}
2606#endif
2607
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002608static int
Georg Brandlef1701f2006-03-07 14:57:48 +00002609_default_cmp(const DBT *leftKey,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002610 const DBT *rightKey)
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002611{
2612 int res;
2613 int lsize = leftKey->size, rsize = rightKey->size;
2614
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002615 res = memcmp(leftKey->data, rightKey->data,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002616 lsize < rsize ? lsize : rsize);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002617
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002618 if (res == 0) {
2619 if (lsize < rsize) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002620 res = -1;
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002621 }
2622 else if (lsize > rsize) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002623 res = 1;
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002624 }
2625 }
2626 return res;
2627}
2628
2629static int
Jesus Ceaef9764f2008-05-13 18:45:46 +00002630_db_compareCallback(DB* db,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002631 const DBT *leftKey,
2632 const DBT *rightKey)
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002633{
2634 int res = 0;
2635 PyObject *args;
Thomas Woutersb2820ae2006-03-12 00:01:38 +00002636 PyObject *result = NULL;
Georg Brandlef1701f2006-03-07 14:57:48 +00002637 DBObject *self = (DBObject *)db->app_private;
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002638
2639 if (self == NULL || self->btCompareCallback == NULL) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002640 MYDB_BEGIN_BLOCK_THREADS;
2641 PyErr_SetString(PyExc_TypeError,
2642 (self == 0
2643 ? "DB_bt_compare db is NULL."
2644 : "DB_bt_compare callback is NULL."));
2645 /* we're in a callback within the DB code, we can't raise */
2646 PyErr_Print();
2647 res = _default_cmp(leftKey, rightKey);
2648 MYDB_END_BLOCK_THREADS;
Georg Brandlef1701f2006-03-07 14:57:48 +00002649 } else {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002650 MYDB_BEGIN_BLOCK_THREADS;
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002651
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002652 args = BuildValue_SS(leftKey->data, leftKey->size, rightKey->data, rightKey->size);
2653 if (args != NULL) {
2654 result = PyEval_CallObject(self->btCompareCallback, args);
2655 }
2656 if (args == NULL || result == NULL) {
2657 /* we're in a callback within the DB code, we can't raise */
2658 PyErr_Print();
2659 res = _default_cmp(leftKey, rightKey);
2660 } else if (NUMBER_Check(result)) {
2661 res = NUMBER_AsLong(result);
2662 } else {
2663 PyErr_SetString(PyExc_TypeError,
2664 "DB_bt_compare callback MUST return an int.");
2665 /* we're in a callback within the DB code, we can't raise */
2666 PyErr_Print();
2667 res = _default_cmp(leftKey, rightKey);
2668 }
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002669
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002670 Py_XDECREF(args);
2671 Py_XDECREF(result);
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002672
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002673 MYDB_END_BLOCK_THREADS;
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002674 }
2675 return res;
2676}
2677
2678static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002679DB_set_bt_compare(DBObject* self, PyObject* comparator)
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002680{
2681 int err;
Thomas Woutersb3153832006-03-08 01:47:19 +00002682 PyObject *tuple, *result;
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002683
Georg Brandlef1701f2006-03-07 14:57:48 +00002684 CHECK_DB_NOT_CLOSED(self);
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002685
Georg Brandlef1701f2006-03-07 14:57:48 +00002686 if (!PyCallable_Check(comparator)) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002687 makeTypeError("Callable", comparator);
2688 return NULL;
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002689 }
2690
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002691 /*
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002692 * Perform a test call of the comparator function with two empty
2693 * string objects here. verify that it returns an int (0).
2694 * err if not.
2695 */
Thomas Woutersb3153832006-03-08 01:47:19 +00002696 tuple = Py_BuildValue("(ss)", "", "");
Georg Brandlef1701f2006-03-07 14:57:48 +00002697 result = PyEval_CallObject(comparator, tuple);
2698 Py_DECREF(tuple);
Thomas Woutersb3153832006-03-08 01:47:19 +00002699 if (result == NULL)
2700 return NULL;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002701 if (!NUMBER_Check(result)) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002702 Py_DECREF(result);
2703 PyErr_SetString(PyExc_TypeError,
2704 "callback MUST return an int");
2705 return NULL;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002706 } else if (NUMBER_AsLong(result) != 0) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002707 Py_DECREF(result);
2708 PyErr_SetString(PyExc_TypeError,
2709 "callback failed to return 0 on two empty strings");
2710 return NULL;
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002711 }
Thomas Woutersb3153832006-03-08 01:47:19 +00002712 Py_DECREF(result);
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002713
2714 /* We don't accept multiple set_bt_compare operations, in order to
2715 * simplify the code. This would have no real use, as one cannot
2716 * change the function once the db is opened anyway */
2717 if (self->btCompareCallback != NULL) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002718 PyErr_SetString(PyExc_RuntimeError, "set_bt_compare() cannot be called more than once");
2719 return NULL;
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002720 }
2721
Georg Brandlef1701f2006-03-07 14:57:48 +00002722 Py_INCREF(comparator);
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002723 self->btCompareCallback = comparator;
2724
2725 /* This is to workaround a problem with un-initialized threads (see
2726 comment in DB_associate) */
2727#ifdef WITH_THREAD
2728 PyEval_InitThreads();
2729#endif
2730
Thomas Woutersb3153832006-03-08 01:47:19 +00002731 err = self->db->set_bt_compare(self->db, _db_compareCallback);
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002732
2733 if (err) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002734 /* restore the old state in case of error */
2735 Py_DECREF(comparator);
2736 self->btCompareCallback = NULL;
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002737 }
2738
Georg Brandlef1701f2006-03-07 14:57:48 +00002739 RETURN_IF_ERR();
2740 RETURN_NONE();
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002741}
2742
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002743
2744static PyObject*
2745DB_set_cachesize(DBObject* self, PyObject* args)
2746{
2747 int err;
2748 int gbytes = 0, bytes = 0, ncache = 0;
2749
2750 if (!PyArg_ParseTuple(args,"ii|i:set_cachesize",
2751 &gbytes,&bytes,&ncache))
2752 return NULL;
2753 CHECK_DB_NOT_CLOSED(self);
2754
2755 MYDB_BEGIN_ALLOW_THREADS;
2756 err = self->db->set_cachesize(self->db, gbytes, bytes, ncache);
2757 MYDB_END_ALLOW_THREADS;
2758 RETURN_IF_ERR();
2759 RETURN_NONE();
2760}
2761
Jesus Cea6557aac2010-03-22 14:22:26 +00002762#if (DBVER >= 42)
2763static PyObject*
2764DB_get_cachesize(DBObject* self)
2765{
2766 int err;
2767 u_int32_t gbytes, bytes;
2768 int ncache;
2769
2770 CHECK_DB_NOT_CLOSED(self);
2771
2772 MYDB_BEGIN_ALLOW_THREADS;
2773 err = self->db->get_cachesize(self->db, &gbytes, &bytes, &ncache);
2774 MYDB_END_ALLOW_THREADS;
2775
2776 RETURN_IF_ERR();
2777
2778 return Py_BuildValue("(iii)", gbytes, bytes, ncache);
2779}
2780#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002781
2782static PyObject*
2783DB_set_flags(DBObject* self, PyObject* args)
2784{
2785 int err, flags;
2786
2787 if (!PyArg_ParseTuple(args,"i:set_flags", &flags))
2788 return NULL;
2789 CHECK_DB_NOT_CLOSED(self);
2790
2791 MYDB_BEGIN_ALLOW_THREADS;
2792 err = self->db->set_flags(self->db, flags);
2793 MYDB_END_ALLOW_THREADS;
2794 RETURN_IF_ERR();
2795
2796 self->setflags |= flags;
2797 RETURN_NONE();
2798}
2799
Jesus Cea6557aac2010-03-22 14:22:26 +00002800#if (DBVER >= 42)
2801static PyObject*
2802DB_get_flags(DBObject* self)
2803{
2804 int err;
2805 u_int32_t flags;
2806
2807 CHECK_DB_NOT_CLOSED(self);
2808
2809 MYDB_BEGIN_ALLOW_THREADS;
2810 err = self->db->get_flags(self->db, &flags);
2811 MYDB_END_ALLOW_THREADS;
2812 RETURN_IF_ERR();
2813 return NUMBER_FromLong(flags);
2814}
2815#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002816
2817static PyObject*
2818DB_set_h_ffactor(DBObject* self, PyObject* args)
2819{
2820 int err, ffactor;
2821
2822 if (!PyArg_ParseTuple(args,"i:set_h_ffactor", &ffactor))
2823 return NULL;
2824 CHECK_DB_NOT_CLOSED(self);
2825
2826 MYDB_BEGIN_ALLOW_THREADS;
2827 err = self->db->set_h_ffactor(self->db, ffactor);
2828 MYDB_END_ALLOW_THREADS;
2829 RETURN_IF_ERR();
2830 RETURN_NONE();
2831}
2832
Jesus Cea6557aac2010-03-22 14:22:26 +00002833#if (DBVER >= 42)
2834static PyObject*
2835DB_get_h_ffactor(DBObject* self)
2836{
2837 int err;
2838 u_int32_t ffactor;
2839
2840 CHECK_DB_NOT_CLOSED(self);
2841
2842 MYDB_BEGIN_ALLOW_THREADS;
2843 err = self->db->get_h_ffactor(self->db, &ffactor);
2844 MYDB_END_ALLOW_THREADS;
2845 RETURN_IF_ERR();
2846 return NUMBER_FromLong(ffactor);
2847}
2848#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002849
2850static PyObject*
2851DB_set_h_nelem(DBObject* self, PyObject* args)
2852{
2853 int err, nelem;
2854
2855 if (!PyArg_ParseTuple(args,"i:set_h_nelem", &nelem))
2856 return NULL;
2857 CHECK_DB_NOT_CLOSED(self);
2858
2859 MYDB_BEGIN_ALLOW_THREADS;
2860 err = self->db->set_h_nelem(self->db, nelem);
2861 MYDB_END_ALLOW_THREADS;
2862 RETURN_IF_ERR();
2863 RETURN_NONE();
2864}
2865
Jesus Cea6557aac2010-03-22 14:22:26 +00002866#if (DBVER >= 42)
2867static PyObject*
2868DB_get_h_nelem(DBObject* self)
2869{
2870 int err;
2871 u_int32_t nelem;
2872
2873 CHECK_DB_NOT_CLOSED(self);
2874
2875 MYDB_BEGIN_ALLOW_THREADS;
2876 err = self->db->get_h_nelem(self->db, &nelem);
2877 MYDB_END_ALLOW_THREADS;
2878 RETURN_IF_ERR();
2879 return NUMBER_FromLong(nelem);
2880}
2881#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002882
2883static PyObject*
2884DB_set_lorder(DBObject* self, PyObject* args)
2885{
2886 int err, lorder;
2887
2888 if (!PyArg_ParseTuple(args,"i:set_lorder", &lorder))
2889 return NULL;
2890 CHECK_DB_NOT_CLOSED(self);
2891
2892 MYDB_BEGIN_ALLOW_THREADS;
2893 err = self->db->set_lorder(self->db, lorder);
2894 MYDB_END_ALLOW_THREADS;
2895 RETURN_IF_ERR();
2896 RETURN_NONE();
2897}
2898
Jesus Cea6557aac2010-03-22 14:22:26 +00002899#if (DBVER >= 42)
2900static PyObject*
2901DB_get_lorder(DBObject* self)
2902{
2903 int err;
2904 int lorder;
2905
2906 CHECK_DB_NOT_CLOSED(self);
2907
2908 MYDB_BEGIN_ALLOW_THREADS;
2909 err = self->db->get_lorder(self->db, &lorder);
2910 MYDB_END_ALLOW_THREADS;
2911 RETURN_IF_ERR();
2912 return NUMBER_FromLong(lorder);
2913}
2914#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002915
2916static PyObject*
2917DB_set_pagesize(DBObject* self, PyObject* args)
2918{
2919 int err, pagesize;
2920
2921 if (!PyArg_ParseTuple(args,"i:set_pagesize", &pagesize))
2922 return NULL;
2923 CHECK_DB_NOT_CLOSED(self);
2924
2925 MYDB_BEGIN_ALLOW_THREADS;
2926 err = self->db->set_pagesize(self->db, pagesize);
2927 MYDB_END_ALLOW_THREADS;
2928 RETURN_IF_ERR();
2929 RETURN_NONE();
2930}
2931
Jesus Cea6557aac2010-03-22 14:22:26 +00002932#if (DBVER >= 42)
2933static PyObject*
2934DB_get_pagesize(DBObject* self)
2935{
2936 int err;
2937 u_int32_t pagesize;
2938
2939 CHECK_DB_NOT_CLOSED(self);
2940
2941 MYDB_BEGIN_ALLOW_THREADS;
2942 err = self->db->get_pagesize(self->db, &pagesize);
2943 MYDB_END_ALLOW_THREADS;
2944 RETURN_IF_ERR();
2945 return NUMBER_FromLong(pagesize);
2946}
2947#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002948
2949static PyObject*
2950DB_set_re_delim(DBObject* self, PyObject* args)
2951{
2952 int err;
2953 char delim;
2954
2955 if (!PyArg_ParseTuple(args,"b:set_re_delim", &delim)) {
2956 PyErr_Clear();
2957 if (!PyArg_ParseTuple(args,"c:set_re_delim", &delim))
2958 return NULL;
2959 }
2960
2961 CHECK_DB_NOT_CLOSED(self);
2962
2963 MYDB_BEGIN_ALLOW_THREADS;
2964 err = self->db->set_re_delim(self->db, delim);
2965 MYDB_END_ALLOW_THREADS;
2966 RETURN_IF_ERR();
2967 RETURN_NONE();
2968}
2969
Jesus Cea6557aac2010-03-22 14:22:26 +00002970#if (DBVER >= 42)
2971static PyObject*
2972DB_get_re_delim(DBObject* self)
2973{
2974 int err, re_delim;
2975
2976 CHECK_DB_NOT_CLOSED(self);
2977
2978 MYDB_BEGIN_ALLOW_THREADS;
2979 err = self->db->get_re_delim(self->db, &re_delim);
2980 MYDB_END_ALLOW_THREADS;
2981 RETURN_IF_ERR();
2982 return NUMBER_FromLong(re_delim);
2983}
2984#endif
2985
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002986static PyObject*
2987DB_set_re_len(DBObject* self, PyObject* args)
2988{
2989 int err, len;
2990
2991 if (!PyArg_ParseTuple(args,"i:set_re_len", &len))
2992 return NULL;
2993 CHECK_DB_NOT_CLOSED(self);
2994
2995 MYDB_BEGIN_ALLOW_THREADS;
2996 err = self->db->set_re_len(self->db, len);
2997 MYDB_END_ALLOW_THREADS;
2998 RETURN_IF_ERR();
2999 RETURN_NONE();
3000}
3001
Jesus Cea6557aac2010-03-22 14:22:26 +00003002#if (DBVER >= 42)
3003static PyObject*
3004DB_get_re_len(DBObject* self)
3005{
3006 int err;
3007 u_int32_t re_len;
3008
3009 CHECK_DB_NOT_CLOSED(self);
3010
3011 MYDB_BEGIN_ALLOW_THREADS;
3012 err = self->db->get_re_len(self->db, &re_len);
3013 MYDB_END_ALLOW_THREADS;
3014 RETURN_IF_ERR();
3015 return NUMBER_FromLong(re_len);
3016}
3017#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003018
3019static PyObject*
3020DB_set_re_pad(DBObject* self, PyObject* args)
3021{
3022 int err;
3023 char pad;
3024
3025 if (!PyArg_ParseTuple(args,"b:set_re_pad", &pad)) {
3026 PyErr_Clear();
3027 if (!PyArg_ParseTuple(args,"c:set_re_pad", &pad))
3028 return NULL;
3029 }
3030 CHECK_DB_NOT_CLOSED(self);
3031
3032 MYDB_BEGIN_ALLOW_THREADS;
3033 err = self->db->set_re_pad(self->db, pad);
3034 MYDB_END_ALLOW_THREADS;
3035 RETURN_IF_ERR();
3036 RETURN_NONE();
3037}
3038
Jesus Cea6557aac2010-03-22 14:22:26 +00003039#if (DBVER >= 42)
3040static PyObject*
3041DB_get_re_pad(DBObject* self)
3042{
3043 int err, re_pad;
3044
3045 CHECK_DB_NOT_CLOSED(self);
3046
3047 MYDB_BEGIN_ALLOW_THREADS;
3048 err = self->db->get_re_pad(self->db, &re_pad);
3049 MYDB_END_ALLOW_THREADS;
3050 RETURN_IF_ERR();
3051 return NUMBER_FromLong(re_pad);
3052}
3053#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003054
3055static PyObject*
3056DB_set_re_source(DBObject* self, PyObject* args)
3057{
3058 int err;
Jesus Cea6557aac2010-03-22 14:22:26 +00003059 char *source;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003060
Jesus Cea6557aac2010-03-22 14:22:26 +00003061 if (!PyArg_ParseTuple(args,"s:set_re_source", &source))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003062 return NULL;
3063 CHECK_DB_NOT_CLOSED(self);
3064
3065 MYDB_BEGIN_ALLOW_THREADS;
Jesus Cea6557aac2010-03-22 14:22:26 +00003066 err = self->db->set_re_source(self->db, source);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003067 MYDB_END_ALLOW_THREADS;
3068 RETURN_IF_ERR();
3069 RETURN_NONE();
3070}
3071
Jesus Cea6557aac2010-03-22 14:22:26 +00003072#if (DBVER >= 42)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003073static PyObject*
Jesus Cea6557aac2010-03-22 14:22:26 +00003074DB_get_re_source(DBObject* self)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003075{
3076 int err;
Jesus Cea6557aac2010-03-22 14:22:26 +00003077 const char *source;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003078
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003079 CHECK_DB_NOT_CLOSED(self);
3080
3081 MYDB_BEGIN_ALLOW_THREADS;
Jesus Cea6557aac2010-03-22 14:22:26 +00003082 err = self->db->get_re_source(self->db, &source);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003083 MYDB_END_ALLOW_THREADS;
3084 RETURN_IF_ERR();
Jesus Cea6557aac2010-03-22 14:22:26 +00003085 return PyBytes_FromString(source);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003086}
Jesus Cea6557aac2010-03-22 14:22:26 +00003087#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003088
3089static PyObject*
Gregory P. Smith8b7e9172004-12-13 09:51:23 +00003090DB_stat(DBObject* self, PyObject* args, PyObject* kwargs)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003091{
3092 int err, flags = 0, type;
3093 void* sp;
3094 PyObject* d;
Gregory P. Smith8b7e9172004-12-13 09:51:23 +00003095#if (DBVER >= 43)
3096 PyObject* txnobj = NULL;
3097 DB_TXN *txn = NULL;
Gregory P. Smith2fa06792006-09-19 17:35:04 +00003098 static char* kwnames[] = { "flags", "txn", NULL };
Gregory P. Smith8b7e9172004-12-13 09:51:23 +00003099#else
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003100 static char* kwnames[] = { "flags", NULL };
Gregory P. Smith8b7e9172004-12-13 09:51:23 +00003101#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003102
Gregory P. Smith8b7e9172004-12-13 09:51:23 +00003103#if (DBVER >= 43)
3104 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|iO:stat", kwnames,
3105 &flags, &txnobj))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003106 return NULL;
Gregory P. Smith8b7e9172004-12-13 09:51:23 +00003107 if (!checkTxnObj(txnobj, &txn))
3108 return NULL;
3109#else
3110 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:stat", kwnames, &flags))
3111 return NULL;
3112#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003113 CHECK_DB_NOT_CLOSED(self);
3114
3115 MYDB_BEGIN_ALLOW_THREADS;
Gregory P. Smith8b7e9172004-12-13 09:51:23 +00003116#if (DBVER >= 43)
3117 err = self->db->stat(self->db, txn, &sp, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003118#else
Jesus Ceac5a11fa2008-07-23 11:38:42 +00003119 err = self->db->stat(self->db, &sp, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003120#endif
3121 MYDB_END_ALLOW_THREADS;
3122 RETURN_IF_ERR();
3123
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003124 /* Turn the stat structure into a dictionary */
3125 type = _DB_get_type(self);
3126 if ((type == -1) || ((d = PyDict_New()) == NULL)) {
3127 free(sp);
3128 return NULL;
3129 }
3130
3131#define MAKE_HASH_ENTRY(name) _addIntToDict(d, #name, ((DB_HASH_STAT*)sp)->hash_##name)
3132#define MAKE_BT_ENTRY(name) _addIntToDict(d, #name, ((DB_BTREE_STAT*)sp)->bt_##name)
3133#define MAKE_QUEUE_ENTRY(name) _addIntToDict(d, #name, ((DB_QUEUE_STAT*)sp)->qs_##name)
3134
3135 switch (type) {
3136 case DB_HASH:
3137 MAKE_HASH_ENTRY(magic);
3138 MAKE_HASH_ENTRY(version);
3139 MAKE_HASH_ENTRY(nkeys);
3140 MAKE_HASH_ENTRY(ndata);
Jesus Ceaef9764f2008-05-13 18:45:46 +00003141#if (DBVER >= 46)
3142 MAKE_HASH_ENTRY(pagecnt);
3143#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003144 MAKE_HASH_ENTRY(pagesize);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003145 MAKE_HASH_ENTRY(ffactor);
3146 MAKE_HASH_ENTRY(buckets);
3147 MAKE_HASH_ENTRY(free);
3148 MAKE_HASH_ENTRY(bfree);
3149 MAKE_HASH_ENTRY(bigpages);
3150 MAKE_HASH_ENTRY(big_bfree);
3151 MAKE_HASH_ENTRY(overflows);
3152 MAKE_HASH_ENTRY(ovfl_free);
3153 MAKE_HASH_ENTRY(dup);
3154 MAKE_HASH_ENTRY(dup_free);
3155 break;
3156
3157 case DB_BTREE:
3158 case DB_RECNO:
3159 MAKE_BT_ENTRY(magic);
3160 MAKE_BT_ENTRY(version);
3161 MAKE_BT_ENTRY(nkeys);
3162 MAKE_BT_ENTRY(ndata);
Jesus Ceaef9764f2008-05-13 18:45:46 +00003163#if (DBVER >= 46)
3164 MAKE_BT_ENTRY(pagecnt);
3165#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003166 MAKE_BT_ENTRY(pagesize);
3167 MAKE_BT_ENTRY(minkey);
3168 MAKE_BT_ENTRY(re_len);
3169 MAKE_BT_ENTRY(re_pad);
3170 MAKE_BT_ENTRY(levels);
3171 MAKE_BT_ENTRY(int_pg);
3172 MAKE_BT_ENTRY(leaf_pg);
3173 MAKE_BT_ENTRY(dup_pg);
3174 MAKE_BT_ENTRY(over_pg);
Jesus Ceaef9764f2008-05-13 18:45:46 +00003175#if (DBVER >= 43)
3176 MAKE_BT_ENTRY(empty_pg);
3177#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003178 MAKE_BT_ENTRY(free);
3179 MAKE_BT_ENTRY(int_pgfree);
3180 MAKE_BT_ENTRY(leaf_pgfree);
3181 MAKE_BT_ENTRY(dup_pgfree);
3182 MAKE_BT_ENTRY(over_pgfree);
3183 break;
3184
3185 case DB_QUEUE:
3186 MAKE_QUEUE_ENTRY(magic);
3187 MAKE_QUEUE_ENTRY(version);
3188 MAKE_QUEUE_ENTRY(nkeys);
3189 MAKE_QUEUE_ENTRY(ndata);
3190 MAKE_QUEUE_ENTRY(pagesize);
Jesus Ceaef9764f2008-05-13 18:45:46 +00003191 MAKE_QUEUE_ENTRY(extentsize);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003192 MAKE_QUEUE_ENTRY(pages);
3193 MAKE_QUEUE_ENTRY(re_len);
3194 MAKE_QUEUE_ENTRY(re_pad);
3195 MAKE_QUEUE_ENTRY(pgfree);
3196#if (DBVER == 31)
3197 MAKE_QUEUE_ENTRY(start);
3198#endif
3199 MAKE_QUEUE_ENTRY(first_recno);
3200 MAKE_QUEUE_ENTRY(cur_recno);
3201 break;
3202
3203 default:
3204 PyErr_SetString(PyExc_TypeError, "Unknown DB type, unable to stat");
3205 Py_DECREF(d);
3206 d = NULL;
3207 }
3208
3209#undef MAKE_HASH_ENTRY
3210#undef MAKE_BT_ENTRY
3211#undef MAKE_QUEUE_ENTRY
3212
3213 free(sp);
3214 return d;
3215}
3216
Jesus Cea6557aac2010-03-22 14:22:26 +00003217#if (DBVER >= 43)
3218static PyObject*
3219DB_stat_print(DBObject* self, PyObject* args, PyObject *kwargs)
3220{
3221 int err;
3222 int flags=0;
3223 static char* kwnames[] = { "flags", NULL };
3224
3225 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:stat_print",
3226 kwnames, &flags))
3227 {
3228 return NULL;
3229 }
3230 CHECK_DB_NOT_CLOSED(self);
3231 MYDB_BEGIN_ALLOW_THREADS;
3232 err = self->db->stat_print(self->db, flags);
3233 MYDB_END_ALLOW_THREADS;
3234 RETURN_IF_ERR();
3235 RETURN_NONE();
3236}
3237#endif
3238
3239
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003240static PyObject*
3241DB_sync(DBObject* self, PyObject* args)
3242{
3243 int err;
3244 int flags = 0;
3245
3246 if (!PyArg_ParseTuple(args,"|i:sync", &flags ))
3247 return NULL;
3248 CHECK_DB_NOT_CLOSED(self);
3249
3250 MYDB_BEGIN_ALLOW_THREADS;
3251 err = self->db->sync(self->db, flags);
3252 MYDB_END_ALLOW_THREADS;
3253 RETURN_IF_ERR();
3254 RETURN_NONE();
3255}
3256
3257
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003258static PyObject*
3259DB_truncate(DBObject* self, PyObject* args, PyObject* kwargs)
3260{
3261 int err, flags=0;
3262 u_int32_t count=0;
3263 PyObject* txnobj = NULL;
3264 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003265 static char* kwnames[] = { "txn", "flags", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003266
3267 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Oi:cursor", kwnames,
3268 &txnobj, &flags))
3269 return NULL;
3270 CHECK_DB_NOT_CLOSED(self);
3271 if (!checkTxnObj(txnobj, &txn))
3272 return NULL;
3273
3274 MYDB_BEGIN_ALLOW_THREADS;
3275 err = self->db->truncate(self->db, txn, &count, flags);
3276 MYDB_END_ALLOW_THREADS;
3277 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00003278 return NUMBER_FromLong(count);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003279}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003280
3281
3282static PyObject*
3283DB_upgrade(DBObject* self, PyObject* args)
3284{
3285 int err, flags=0;
3286 char *filename;
3287
3288 if (!PyArg_ParseTuple(args,"s|i:upgrade", &filename, &flags))
3289 return NULL;
3290 CHECK_DB_NOT_CLOSED(self);
3291
3292 MYDB_BEGIN_ALLOW_THREADS;
3293 err = self->db->upgrade(self->db, filename, flags);
3294 MYDB_END_ALLOW_THREADS;
3295 RETURN_IF_ERR();
3296 RETURN_NONE();
3297}
3298
3299
3300static PyObject*
3301DB_verify(DBObject* self, PyObject* args, PyObject* kwargs)
3302{
3303 int err, flags=0;
3304 char* fileName;
3305 char* dbName=NULL;
3306 char* outFileName=NULL;
3307 FILE* outFile=NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003308 static char* kwnames[] = { "filename", "dbname", "outfile", "flags",
Jeremy Hyltonaf68c872005-12-10 18:50:16 +00003309 NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003310
3311 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|zzi:verify", kwnames,
3312 &fileName, &dbName, &outFileName, &flags))
3313 return NULL;
3314
3315 CHECK_DB_NOT_CLOSED(self);
3316 if (outFileName)
3317 outFile = fopen(outFileName, "w");
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003318 /* XXX(nnorwitz): it should probably be an exception if outFile
3319 can't be opened. */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003320
Jesus Ceaef9764f2008-05-13 18:45:46 +00003321 { /* DB.verify acts as a DB handle destructor (like close) */
3322 PyObject *error;
3323
Jesus Cea5cd5f122008-09-23 18:54:08 +00003324 error=DB_close_internal(self, 0, 1);
Jesus Cea6557aac2010-03-22 14:22:26 +00003325 if (error) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00003326 return error;
3327 }
3328 }
Gregory P. Smith41631e82003-09-21 00:08:14 +00003329
Jesus Cea5cd5f122008-09-23 18:54:08 +00003330 MYDB_BEGIN_ALLOW_THREADS;
3331 err = self->db->verify(self->db, fileName, dbName, outFile, flags);
3332 MYDB_END_ALLOW_THREADS;
3333
3334 self->db = NULL; /* Implicit close; related objects already released */
3335
3336 if (outFile)
3337 fclose(outFile);
3338
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003339 RETURN_IF_ERR();
3340 RETURN_NONE();
3341}
3342
3343
3344static PyObject*
3345DB_set_get_returns_none(DBObject* self, PyObject* args)
3346{
3347 int flags=0;
Gregory P. Smith455d46f2003-07-09 04:45:59 +00003348 int oldValue=0;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003349
3350 if (!PyArg_ParseTuple(args,"i:set_get_returns_none", &flags))
3351 return NULL;
3352 CHECK_DB_NOT_CLOSED(self);
3353
Gregory P. Smith455d46f2003-07-09 04:45:59 +00003354 if (self->moduleFlags.getReturnsNone)
3355 ++oldValue;
3356 if (self->moduleFlags.cursorSetReturnsNone)
3357 ++oldValue;
3358 self->moduleFlags.getReturnsNone = (flags >= 1);
3359 self->moduleFlags.cursorSetReturnsNone = (flags >= 2);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00003360 return NUMBER_FromLong(oldValue);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003361}
3362
Barry Warsaw9a0d7792002-12-30 20:53:52 +00003363static PyObject*
3364DB_set_encrypt(DBObject* self, PyObject* args, PyObject* kwargs)
3365{
3366 int err;
3367 u_int32_t flags=0;
3368 char *passwd = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003369 static char* kwnames[] = { "passwd", "flags", NULL };
Barry Warsaw9a0d7792002-12-30 20:53:52 +00003370
3371 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|i:set_encrypt", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003372 &passwd, &flags)) {
3373 return NULL;
Barry Warsaw9a0d7792002-12-30 20:53:52 +00003374 }
3375
3376 MYDB_BEGIN_ALLOW_THREADS;
3377 err = self->db->set_encrypt(self->db, passwd, flags);
3378 MYDB_END_ALLOW_THREADS;
3379
3380 RETURN_IF_ERR();
3381 RETURN_NONE();
3382}
Jesus Cea6557aac2010-03-22 14:22:26 +00003383
3384#if (DBVER >= 42)
3385static PyObject*
3386DB_get_encrypt_flags(DBObject* self)
3387{
3388 int err;
3389 u_int32_t flags;
3390
3391 MYDB_BEGIN_ALLOW_THREADS;
3392 err = self->db->get_encrypt_flags(self->db, &flags);
3393 MYDB_END_ALLOW_THREADS;
3394
3395 RETURN_IF_ERR();
3396
3397 return NUMBER_FromLong(flags);
3398}
3399#endif
3400
Barry Warsaw9a0d7792002-12-30 20:53:52 +00003401
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003402
3403/*-------------------------------------------------------------- */
3404/* Mapping and Dictionary-like access routines */
3405
Martin v. Löwis70ee3cc2006-06-12 04:26:31 +00003406Py_ssize_t DB_length(PyObject* _self)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003407{
3408 int err;
Gregory P. Smith3c228b12006-06-05 23:59:37 +00003409 Py_ssize_t size = 0;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003410 void* sp;
Martin v. Löwis70ee3cc2006-06-12 04:26:31 +00003411 DBObject* self = (DBObject*)_self;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003412
3413 if (self->db == NULL) {
Thomas Woutersb3153832006-03-08 01:47:19 +00003414 PyObject *t = Py_BuildValue("(is)", 0, "DB object has been closed");
Jesus Ceac5a11fa2008-07-23 11:38:42 +00003415 if (t) {
3416 PyErr_SetObject(DBError, t);
3417 Py_DECREF(t);
3418 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003419 return -1;
3420 }
3421
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003422 MYDB_BEGIN_ALLOW_THREADS;
Gregory P. Smith8b7e9172004-12-13 09:51:23 +00003423#if (DBVER >= 43)
Jesus Cea6557aac2010-03-22 14:22:26 +00003424 err = self->db->stat(self->db, /*txnid*/ NULL, &sp, 0);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003425#else
Jesus Cea6557aac2010-03-22 14:22:26 +00003426 err = self->db->stat(self->db, &sp, 0);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003427#endif
Jesus Cea6557aac2010-03-22 14:22:26 +00003428 MYDB_END_ALLOW_THREADS;
Gregory P. Smith3c228b12006-06-05 23:59:37 +00003429
3430 /* All the stat structures have matching fields upto the ndata field,
3431 so we can use any of them for the type cast */
3432 size = ((DB_BTREE_STAT*)sp)->bt_ndata;
3433
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003434 if (err)
3435 return -1;
3436
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003437 free(sp);
3438 return size;
3439}
3440
3441
3442PyObject* DB_subscript(DBObject* self, PyObject* keyobj)
3443{
3444 int err;
3445 PyObject* retval;
3446 DBT key;
3447 DBT data;
3448
3449 CHECK_DB_NOT_CLOSED(self);
3450 if (!make_key_dbt(self, keyobj, &key, NULL))
3451 return NULL;
3452
3453 CLEAR_DBT(data);
3454 if (CHECK_DBFLAG(self, DB_THREAD)) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00003455 /* Tell Berkeley DB to malloc the return value (thread safe) */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003456 data.flags = DB_DBT_MALLOC;
3457 }
3458 MYDB_BEGIN_ALLOW_THREADS;
3459 err = self->db->get(self->db, NULL, &key, &data, 0);
3460 MYDB_END_ALLOW_THREADS;
3461 if (err == DB_NOTFOUND || err == DB_KEYEMPTY) {
3462 PyErr_SetObject(PyExc_KeyError, keyobj);
3463 retval = NULL;
3464 }
3465 else if (makeDBError(err)) {
3466 retval = NULL;
3467 }
3468 else {
Jesus Ceaef9764f2008-05-13 18:45:46 +00003469 retval = Build_PyString(data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003470 FREE_DBT(data);
3471 }
3472
3473 FREE_DBT(key);
3474 return retval;
3475}
3476
3477
3478static int
3479DB_ass_sub(DBObject* self, PyObject* keyobj, PyObject* dataobj)
3480{
3481 DBT key, data;
3482 int retval;
3483 int flags = 0;
3484
3485 if (self->db == NULL) {
Thomas Woutersb3153832006-03-08 01:47:19 +00003486 PyObject *t = Py_BuildValue("(is)", 0, "DB object has been closed");
Jesus Ceac5a11fa2008-07-23 11:38:42 +00003487 if (t) {
3488 PyErr_SetObject(DBError, t);
3489 Py_DECREF(t);
3490 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003491 return -1;
3492 }
3493
3494 if (!make_key_dbt(self, keyobj, &key, NULL))
3495 return -1;
3496
3497 if (dataobj != NULL) {
3498 if (!make_dbt(dataobj, &data))
3499 retval = -1;
3500 else {
3501 if (self->setflags & (DB_DUP|DB_DUPSORT))
Barry Warsaw9a0d7792002-12-30 20:53:52 +00003502 /* dictionaries shouldn't have duplicate keys */
3503 flags = DB_NOOVERWRITE;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003504 retval = _DB_put(self, NULL, &key, &data, flags);
3505
3506 if ((retval == -1) && (self->setflags & (DB_DUP|DB_DUPSORT))) {
Barry Warsaw9a0d7792002-12-30 20:53:52 +00003507 /* try deleting any old record that matches and then PUT it
3508 * again... */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003509 _DB_delete(self, NULL, &key, 0);
3510 PyErr_Clear();
3511 retval = _DB_put(self, NULL, &key, &data, flags);
3512 }
3513 }
3514 }
3515 else {
3516 /* dataobj == NULL, so delete the key */
3517 retval = _DB_delete(self, NULL, &key, 0);
3518 }
3519 FREE_DBT(key);
3520 return retval;
3521}
3522
3523
3524static PyObject*
Jesus Cea6557aac2010-03-22 14:22:26 +00003525_DB_has_key(DBObject* self, PyObject* keyobj, PyObject* txnobj)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003526{
3527 int err;
Jesus Cea6557aac2010-03-22 14:22:26 +00003528 DBT key;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003529 DB_TXN *txn = NULL;
Jesus Cea4907d272008-08-31 14:00:51 +00003530
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003531 CHECK_DB_NOT_CLOSED(self);
3532 if (!make_key_dbt(self, keyobj, &key, NULL))
3533 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00003534 if (!checkTxnObj(txnobj, &txn)) {
3535 FREE_DBT(key);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003536 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00003537 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003538
Jesus Cea6557aac2010-03-22 14:22:26 +00003539#if (DBVER < 46)
Gregory P. Smith8b7e9172004-12-13 09:51:23 +00003540 /* This causes DB_BUFFER_SMALL to be returned when the db has the key because
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003541 it has a record but can't allocate a buffer for the data. This saves
3542 having to deal with data we won't be using.
3543 */
Jesus Cea6557aac2010-03-22 14:22:26 +00003544 {
3545 DBT data ;
3546 CLEAR_DBT(data);
3547 data.flags = DB_DBT_USERMEM;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003548
Jesus Cea6557aac2010-03-22 14:22:26 +00003549 MYDB_BEGIN_ALLOW_THREADS;
3550 err = self->db->get(self->db, txn, &key, &data, 0);
3551 MYDB_END_ALLOW_THREADS;
3552 }
3553#else
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003554 MYDB_BEGIN_ALLOW_THREADS;
Jesus Cea6557aac2010-03-22 14:22:26 +00003555 err = self->db->exists(self->db, txn, &key, 0);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003556 MYDB_END_ALLOW_THREADS;
Jesus Cea6557aac2010-03-22 14:22:26 +00003557#endif
3558
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003559 FREE_DBT(key);
Gregory P. Smithe9477062005-06-04 06:46:59 +00003560
Jesus Cea6557aac2010-03-22 14:22:26 +00003561 /*
3562 ** DB_BUFFER_SMALL is only used if we use "get".
3563 ** We can drop it when we only use "exists",
3564 ** when we drop suport for Berkeley DB < 4.6.
3565 */
Gregory P. Smithe9477062005-06-04 06:46:59 +00003566 if (err == DB_BUFFER_SMALL || err == 0) {
Jesus Cea6557aac2010-03-22 14:22:26 +00003567 Py_INCREF(Py_True);
3568 return Py_True;
Gregory P. Smithe9477062005-06-04 06:46:59 +00003569 } else if (err == DB_NOTFOUND || err == DB_KEYEMPTY) {
Jesus Cea6557aac2010-03-22 14:22:26 +00003570 Py_INCREF(Py_False);
3571 return Py_False;
Gregory P. Smithe9477062005-06-04 06:46:59 +00003572 }
3573
3574 makeDBError(err);
3575 return NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003576}
3577
Jesus Cea6557aac2010-03-22 14:22:26 +00003578static PyObject*
3579DB_has_key(DBObject* self, PyObject* args, PyObject* kwargs)
3580{
3581 PyObject* keyobj;
3582 PyObject* txnobj = NULL;
3583 static char* kwnames[] = {"key","txn", NULL};
3584
3585 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O:has_key", kwnames,
3586 &keyobj, &txnobj))
3587 return NULL;
3588
3589 return _DB_has_key(self, keyobj, txnobj);
3590}
3591
3592
3593static int DB_contains(DBObject* self, PyObject* keyobj)
3594{
3595 PyObject* result;
3596 int result2 = 0;
3597
3598 result = _DB_has_key(self, keyobj, NULL) ;
3599 if (result == NULL) {
3600 return -1; /* Propague exception */
3601 }
3602 if (result != Py_False) {
3603 result2 = 1;
3604 }
3605
3606 Py_DECREF(result);
3607 return result2;
3608}
3609
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003610
3611#define _KEYS_LIST 1
3612#define _VALUES_LIST 2
3613#define _ITEMS_LIST 3
3614
3615static PyObject*
3616_DB_make_list(DBObject* self, DB_TXN* txn, int type)
3617{
3618 int err, dbtype;
3619 DBT key;
3620 DBT data;
3621 DBC *cursor;
3622 PyObject* list;
3623 PyObject* item = NULL;
3624
3625 CHECK_DB_NOT_CLOSED(self);
3626 CLEAR_DBT(key);
3627 CLEAR_DBT(data);
3628
3629 dbtype = _DB_get_type(self);
3630 if (dbtype == -1)
3631 return NULL;
3632
3633 list = PyList_New(0);
Thomas Woutersb3153832006-03-08 01:47:19 +00003634 if (list == NULL)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003635 return NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003636
3637 /* get a cursor */
3638 MYDB_BEGIN_ALLOW_THREADS;
Gregory P. Smith442c9fc2004-09-04 01:36:59 +00003639 err = self->db->cursor(self->db, txn, &cursor, 0);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003640 MYDB_END_ALLOW_THREADS;
Thomas Woutersb3153832006-03-08 01:47:19 +00003641 if (makeDBError(err)) {
3642 Py_DECREF(list);
3643 return NULL;
3644 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003645
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003646 while (1) { /* use the cursor to traverse the DB, collecting items */
3647 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00003648 err = _DBC_get(cursor, &key, &data, DB_NEXT);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003649 MYDB_END_ALLOW_THREADS;
3650
3651 if (err) {
3652 /* for any error, break out of the loop */
3653 break;
3654 }
3655
3656 switch (type) {
3657 case _KEYS_LIST:
3658 switch(dbtype) {
3659 case DB_BTREE:
3660 case DB_HASH:
3661 default:
Jesus Ceaef9764f2008-05-13 18:45:46 +00003662 item = Build_PyString(key.data, key.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003663 break;
3664 case DB_RECNO:
3665 case DB_QUEUE:
Jesus Ceac5a11fa2008-07-23 11:38:42 +00003666 item = NUMBER_FromLong(*((db_recno_t*)key.data));
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003667 break;
3668 }
3669 break;
3670
3671 case _VALUES_LIST:
Jesus Ceaef9764f2008-05-13 18:45:46 +00003672 item = Build_PyString(data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003673 break;
3674
3675 case _ITEMS_LIST:
3676 switch(dbtype) {
3677 case DB_BTREE:
3678 case DB_HASH:
3679 default:
Jesus Ceaef9764f2008-05-13 18:45:46 +00003680 item = BuildValue_SS(key.data, key.size, data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003681 break;
3682 case DB_RECNO:
3683 case DB_QUEUE:
Jesus Ceaef9764f2008-05-13 18:45:46 +00003684 item = BuildValue_IS(*((db_recno_t*)key.data), data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003685 break;
3686 }
3687 break;
Thomas Woutersb3153832006-03-08 01:47:19 +00003688 default:
3689 PyErr_Format(PyExc_ValueError, "Unknown key type 0x%x", type);
3690 item = NULL;
3691 break;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003692 }
3693 if (item == NULL) {
3694 Py_DECREF(list);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003695 list = NULL;
3696 goto done;
3697 }
Jesus Ceac5a11fa2008-07-23 11:38:42 +00003698 if (PyList_Append(list, item)) {
3699 Py_DECREF(list);
3700 Py_DECREF(item);
3701 list = NULL;
3702 goto done;
3703 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003704 Py_DECREF(item);
3705 }
3706
Gregory P. Smithe9477062005-06-04 06:46:59 +00003707 /* DB_NOTFOUND || DB_KEYEMPTY is okay, it means we got to the end */
3708 if (err != DB_NOTFOUND && err != DB_KEYEMPTY && makeDBError(err)) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003709 Py_DECREF(list);
3710 list = NULL;
3711 }
3712
3713 done:
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003714 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00003715 _DBC_close(cursor);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003716 MYDB_END_ALLOW_THREADS;
3717 return list;
3718}
3719
3720
3721static PyObject*
3722DB_keys(DBObject* self, PyObject* args)
3723{
3724 PyObject* txnobj = NULL;
3725 DB_TXN *txn = NULL;
3726
Georg Brandl96a8c392006-05-29 21:04:52 +00003727 if (!PyArg_UnpackTuple(args, "keys", 0, 1, &txnobj))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003728 return NULL;
3729 if (!checkTxnObj(txnobj, &txn))
3730 return NULL;
3731 return _DB_make_list(self, txn, _KEYS_LIST);
3732}
3733
3734
3735static PyObject*
3736DB_items(DBObject* self, PyObject* args)
3737{
3738 PyObject* txnobj = NULL;
3739 DB_TXN *txn = NULL;
3740
Georg Brandl96a8c392006-05-29 21:04:52 +00003741 if (!PyArg_UnpackTuple(args, "items", 0, 1, &txnobj))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003742 return NULL;
3743 if (!checkTxnObj(txnobj, &txn))
3744 return NULL;
3745 return _DB_make_list(self, txn, _ITEMS_LIST);
3746}
3747
3748
3749static PyObject*
3750DB_values(DBObject* self, PyObject* args)
3751{
3752 PyObject* txnobj = NULL;
3753 DB_TXN *txn = NULL;
3754
Georg Brandl96a8c392006-05-29 21:04:52 +00003755 if (!PyArg_UnpackTuple(args, "values", 0, 1, &txnobj))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003756 return NULL;
3757 if (!checkTxnObj(txnobj, &txn))
3758 return NULL;
3759 return _DB_make_list(self, txn, _VALUES_LIST);
3760}
3761
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003762/* --------------------------------------------------------------------- */
Jesus Cea6557aac2010-03-22 14:22:26 +00003763/* DBLogCursor methods */
3764
3765
3766static PyObject*
3767DBLogCursor_close_internal(DBLogCursorObject* self)
3768{
3769 int err = 0;
3770
3771 if (self->logc != NULL) {
3772 EXTRACT_FROM_DOUBLE_LINKED_LIST(self);
3773
3774 MYDB_BEGIN_ALLOW_THREADS;
3775 err = self->logc->close(self->logc, 0);
3776 MYDB_END_ALLOW_THREADS;
3777 self->logc = NULL;
3778 }
3779 RETURN_IF_ERR();
3780 RETURN_NONE();
3781}
3782
3783static PyObject*
3784DBLogCursor_close(DBLogCursorObject* self)
3785{
3786 return DBLogCursor_close_internal(self);
3787}
3788
3789
3790static PyObject*
3791_DBLogCursor_get(DBLogCursorObject* self, int flag, DB_LSN *lsn2)
3792{
3793 int err;
3794 DBT data;
3795 DB_LSN lsn = {0, 0};
3796 PyObject *dummy, *retval;
3797
3798 CLEAR_DBT(data);
3799 data.flags = DB_DBT_MALLOC; /* Berkeley DB must do the malloc */
3800
3801 CHECK_LOGCURSOR_NOT_CLOSED(self);
3802
3803 if (lsn2)
3804 lsn = *lsn2;
3805
3806 MYDB_BEGIN_ALLOW_THREADS;
3807 err = self->logc->get(self->logc, &lsn, &data, flag);
3808 MYDB_END_ALLOW_THREADS;
3809
3810 if (err == DB_NOTFOUND) {
3811 Py_INCREF(Py_None);
3812 retval = Py_None;
3813 }
3814 else if (makeDBError(err)) {
3815 retval = NULL;
3816 }
3817 else {
3818 retval = dummy = BuildValue_S(data.data, data.size);
3819 if (dummy) {
3820 retval = Py_BuildValue("(ii)O", lsn.file, lsn.offset, dummy);
3821 Py_DECREF(dummy);
3822 }
3823 }
3824
3825 FREE_DBT(data);
3826 return retval;
3827}
3828
3829static PyObject*
3830DBLogCursor_current(DBLogCursorObject* self)
3831{
3832 return _DBLogCursor_get(self, DB_CURRENT, NULL);
3833}
3834
3835static PyObject*
3836DBLogCursor_first(DBLogCursorObject* self)
3837{
3838 return _DBLogCursor_get(self, DB_FIRST, NULL);
3839}
3840
3841static PyObject*
3842DBLogCursor_last(DBLogCursorObject* self)
3843{
3844 return _DBLogCursor_get(self, DB_LAST, NULL);
3845}
3846
3847static PyObject*
3848DBLogCursor_next(DBLogCursorObject* self)
3849{
3850 return _DBLogCursor_get(self, DB_NEXT, NULL);
3851}
3852
3853static PyObject*
3854DBLogCursor_prev(DBLogCursorObject* self)
3855{
3856 return _DBLogCursor_get(self, DB_PREV, NULL);
3857}
3858
3859static PyObject*
3860DBLogCursor_set(DBLogCursorObject* self, PyObject* args)
3861{
3862 DB_LSN lsn;
3863
3864 if (!PyArg_ParseTuple(args, "(ii):set", &lsn.file, &lsn.offset))
3865 return NULL;
3866
3867 return _DBLogCursor_get(self, DB_SET, &lsn);
3868}
3869
3870
3871
3872/* --------------------------------------------------------------------- */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003873/* DBCursor methods */
3874
3875
3876static PyObject*
Jesus Ceaef9764f2008-05-13 18:45:46 +00003877DBC_close_internal(DBCursorObject* self)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003878{
3879 int err = 0;
3880
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003881 if (self->dbc != NULL) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00003882 EXTRACT_FROM_DOUBLE_LINKED_LIST(self);
3883 if (self->txn) {
3884 EXTRACT_FROM_DOUBLE_LINKED_LIST_TXN(self);
3885 self->txn=NULL;
3886 }
3887
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003888 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00003889 err = _DBC_close(self->dbc);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003890 MYDB_END_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00003891 self->dbc = NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003892 }
3893 RETURN_IF_ERR();
3894 RETURN_NONE();
3895}
3896
Jesus Ceaef9764f2008-05-13 18:45:46 +00003897static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00003898DBC_close(DBCursorObject* self)
Jesus Ceaef9764f2008-05-13 18:45:46 +00003899{
Jesus Ceaef9764f2008-05-13 18:45:46 +00003900 return DBC_close_internal(self);
3901}
3902
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003903
3904static PyObject*
3905DBC_count(DBCursorObject* self, PyObject* args)
3906{
3907 int err = 0;
3908 db_recno_t count;
3909 int flags = 0;
3910
3911 if (!PyArg_ParseTuple(args, "|i:count", &flags))
3912 return NULL;
3913
3914 CHECK_CURSOR_NOT_CLOSED(self);
3915
3916 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00003917 err = _DBC_count(self->dbc, &count, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003918 MYDB_END_ALLOW_THREADS;
3919 RETURN_IF_ERR();
3920
Jesus Ceac5a11fa2008-07-23 11:38:42 +00003921 return NUMBER_FromLong(count);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003922}
3923
3924
3925static PyObject*
3926DBC_current(DBCursorObject* self, PyObject* args, PyObject *kwargs)
3927{
3928 return _DBCursor_get(self,DB_CURRENT,args,kwargs,"|iii:current");
3929}
3930
3931
3932static PyObject*
3933DBC_delete(DBCursorObject* self, PyObject* args)
3934{
3935 int err, flags=0;
3936
3937 if (!PyArg_ParseTuple(args, "|i:delete", &flags))
3938 return NULL;
3939
3940 CHECK_CURSOR_NOT_CLOSED(self);
3941
3942 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00003943 err = _DBC_del(self->dbc, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003944 MYDB_END_ALLOW_THREADS;
3945 RETURN_IF_ERR();
3946
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003947 RETURN_NONE();
3948}
3949
3950
3951static PyObject*
3952DBC_dup(DBCursorObject* self, PyObject* args)
3953{
3954 int err, flags =0;
3955 DBC* dbc = NULL;
3956
3957 if (!PyArg_ParseTuple(args, "|i:dup", &flags))
3958 return NULL;
3959
3960 CHECK_CURSOR_NOT_CLOSED(self);
3961
3962 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00003963 err = _DBC_dup(self->dbc, &dbc, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003964 MYDB_END_ALLOW_THREADS;
3965 RETURN_IF_ERR();
3966
Jesus Ceaef9764f2008-05-13 18:45:46 +00003967 return (PyObject*) newDBCursorObject(dbc, self->txn, self->mydb);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003968}
3969
3970static PyObject*
3971DBC_first(DBCursorObject* self, PyObject* args, PyObject* kwargs)
3972{
3973 return _DBCursor_get(self,DB_FIRST,args,kwargs,"|iii:first");
3974}
3975
3976
3977static PyObject*
3978DBC_get(DBCursorObject* self, PyObject* args, PyObject *kwargs)
3979{
Martin v. Löwisb2c7aff2002-11-23 11:26:07 +00003980 int err, flags=0;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003981 PyObject* keyobj = NULL;
3982 PyObject* dataobj = NULL;
3983 PyObject* retval = NULL;
3984 int dlen = -1;
3985 int doff = -1;
3986 DBT key, data;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003987 static char* kwnames[] = { "key","data", "flags", "dlen", "doff",
Jeremy Hyltonaf68c872005-12-10 18:50:16 +00003988 NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003989
3990 CLEAR_DBT(key);
3991 CLEAR_DBT(data);
3992 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|ii:get", &kwnames[2],
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003993 &flags, &dlen, &doff))
Barry Warsaw9a0d7792002-12-30 20:53:52 +00003994 {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003995 PyErr_Clear();
Barry Warsaw9a0d7792002-12-30 20:53:52 +00003996 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Oi|ii:get",
Jesus Cea4907d272008-08-31 14:00:51 +00003997 &kwnames[1],
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003998 &keyobj, &flags, &dlen, &doff))
Barry Warsaw9a0d7792002-12-30 20:53:52 +00003999 {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004000 PyErr_Clear();
Barry Warsaw9a0d7792002-12-30 20:53:52 +00004001 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OOi|ii:get",
4002 kwnames, &keyobj, &dataobj,
4003 &flags, &dlen, &doff))
4004 {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004005 return NULL;
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004006 }
4007 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004008 }
4009
4010 CHECK_CURSOR_NOT_CLOSED(self);
4011
4012 if (keyobj && !make_key_dbt(self->mydb, keyobj, &key, NULL))
4013 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004014 if ( (dataobj && !make_dbt(dataobj, &data)) ||
4015 (!add_partial_dbt(&data, dlen, doff)) )
4016 {
Jesus Ceaef9764f2008-05-13 18:45:46 +00004017 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004018 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004019 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004020
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004021 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004022 err = _DBC_get(self->dbc, &key, &data, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004023 MYDB_END_ALLOW_THREADS;
4024
Gregory P. Smithe9477062005-06-04 06:46:59 +00004025 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004026 && self->mydb->moduleFlags.getReturnsNone) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004027 Py_INCREF(Py_None);
4028 retval = Py_None;
4029 }
4030 else if (makeDBError(err)) {
4031 retval = NULL;
4032 }
4033 else {
4034 switch (_DB_get_type(self->mydb)) {
4035 case -1:
4036 retval = NULL;
4037 break;
4038 case DB_BTREE:
4039 case DB_HASH:
4040 default:
Jesus Ceaef9764f2008-05-13 18:45:46 +00004041 retval = BuildValue_SS(key.data, key.size, data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004042 break;
4043 case DB_RECNO:
4044 case DB_QUEUE:
Jesus Ceaef9764f2008-05-13 18:45:46 +00004045 retval = BuildValue_IS(*((db_recno_t*)key.data), data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004046 break;
4047 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004048 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00004049 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004050 return retval;
4051}
4052
Gregory P. Smith19699a92004-06-28 04:06:49 +00004053static PyObject*
4054DBC_pget(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4055{
4056 int err, flags=0;
4057 PyObject* keyobj = NULL;
4058 PyObject* dataobj = NULL;
4059 PyObject* retval = NULL;
4060 int dlen = -1;
4061 int doff = -1;
4062 DBT key, pkey, data;
Gregory P. Smith372b5832006-06-05 18:48:21 +00004063 static char* kwnames_keyOnly[] = { "key", "flags", "dlen", "doff", NULL };
4064 static char* kwnames[] = { "key", "data", "flags", "dlen", "doff", NULL };
Gregory P. Smith19699a92004-06-28 04:06:49 +00004065
4066 CLEAR_DBT(key);
4067 CLEAR_DBT(data);
4068 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|ii:pget", &kwnames[2],
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004069 &flags, &dlen, &doff))
Gregory P. Smith19699a92004-06-28 04:06:49 +00004070 {
4071 PyErr_Clear();
4072 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Oi|ii:pget",
Jesus Cea6557aac2010-03-22 14:22:26 +00004073 kwnames_keyOnly,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004074 &keyobj, &flags, &dlen, &doff))
Gregory P. Smith19699a92004-06-28 04:06:49 +00004075 {
4076 PyErr_Clear();
4077 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OOi|ii:pget",
4078 kwnames, &keyobj, &dataobj,
4079 &flags, &dlen, &doff))
4080 {
4081 return NULL;
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004082 }
4083 }
Gregory P. Smith19699a92004-06-28 04:06:49 +00004084 }
4085
4086 CHECK_CURSOR_NOT_CLOSED(self);
4087
4088 if (keyobj && !make_key_dbt(self->mydb, keyobj, &key, NULL))
4089 return NULL;
4090 if ( (dataobj && !make_dbt(dataobj, &data)) ||
4091 (!add_partial_dbt(&data, dlen, doff)) ) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00004092 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Gregory P. Smith19699a92004-06-28 04:06:49 +00004093 return NULL;
4094 }
4095
Gregory P. Smith19699a92004-06-28 04:06:49 +00004096 CLEAR_DBT(pkey);
4097 pkey.flags = DB_DBT_MALLOC;
4098
4099 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004100 err = _DBC_pget(self->dbc, &key, &pkey, &data, flags);
Gregory P. Smith19699a92004-06-28 04:06:49 +00004101 MYDB_END_ALLOW_THREADS;
4102
Gregory P. Smithe9477062005-06-04 06:46:59 +00004103 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004104 && self->mydb->moduleFlags.getReturnsNone) {
Gregory P. Smith19699a92004-06-28 04:06:49 +00004105 Py_INCREF(Py_None);
4106 retval = Py_None;
4107 }
4108 else if (makeDBError(err)) {
4109 retval = NULL;
4110 }
4111 else {
4112 PyObject *pkeyObj;
4113 PyObject *dataObj;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004114 dataObj = Build_PyString(data.data, data.size);
Gregory P. Smith19699a92004-06-28 04:06:49 +00004115
4116 if (self->mydb->primaryDBType == DB_RECNO ||
4117 self->mydb->primaryDBType == DB_QUEUE)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00004118 pkeyObj = NUMBER_FromLong(*(int *)pkey.data);
Gregory P. Smith19699a92004-06-28 04:06:49 +00004119 else
Jesus Ceaef9764f2008-05-13 18:45:46 +00004120 pkeyObj = Build_PyString(pkey.data, pkey.size);
Gregory P. Smith19699a92004-06-28 04:06:49 +00004121
Gregory P. Smith4e414d82006-01-24 19:55:02 +00004122 if (key.data && key.size) /* return key, pkey and data */
Gregory P. Smith19699a92004-06-28 04:06:49 +00004123 {
4124 PyObject *keyObj;
4125 int type = _DB_get_type(self->mydb);
4126 if (type == DB_RECNO || type == DB_QUEUE)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00004127 keyObj = NUMBER_FromLong(*(int *)key.data);
Gregory P. Smith19699a92004-06-28 04:06:49 +00004128 else
Jesus Ceaef9764f2008-05-13 18:45:46 +00004129 keyObj = Build_PyString(key.data, key.size);
Gregory P. Smithfd049a62006-01-30 00:22:08 +00004130#if (PY_VERSION_HEX >= 0x02040000)
Gregory P. Smith4e414d82006-01-24 19:55:02 +00004131 retval = PyTuple_Pack(3, keyObj, pkeyObj, dataObj);
Gregory P. Smithfd049a62006-01-30 00:22:08 +00004132#else
4133 retval = Py_BuildValue("OOO", keyObj, pkeyObj, dataObj);
4134#endif
Thomas Woutersb3153832006-03-08 01:47:19 +00004135 Py_DECREF(keyObj);
Jesus Ceaef9764f2008-05-13 18:45:46 +00004136 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Gregory P. Smith19699a92004-06-28 04:06:49 +00004137 }
4138 else /* return just the pkey and data */
4139 {
Gregory P. Smithfd049a62006-01-30 00:22:08 +00004140#if (PY_VERSION_HEX >= 0x02040000)
Gregory P. Smith4e414d82006-01-24 19:55:02 +00004141 retval = PyTuple_Pack(2, pkeyObj, dataObj);
Gregory P. Smithfd049a62006-01-30 00:22:08 +00004142#else
4143 retval = Py_BuildValue("OO", pkeyObj, dataObj);
4144#endif
Gregory P. Smith19699a92004-06-28 04:06:49 +00004145 }
Thomas Woutersb3153832006-03-08 01:47:19 +00004146 Py_DECREF(dataObj);
4147 Py_DECREF(pkeyObj);
Gregory P. Smith19699a92004-06-28 04:06:49 +00004148 FREE_DBT(pkey);
Gregory P. Smith19699a92004-06-28 04:06:49 +00004149 }
4150 /* the only time REALLOC should be set is if we used an integer
4151 * key that make_key_dbt malloc'd for us. always free these. */
Jesus Ceaef9764f2008-05-13 18:45:46 +00004152 if (key.flags & DB_DBT_REALLOC) { /* 'make_key_dbt' could do a 'malloc' */
Gregory P. Smith19699a92004-06-28 04:06:49 +00004153 FREE_DBT(key);
4154 }
4155 return retval;
4156}
4157
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004158
4159static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00004160DBC_get_recno(DBCursorObject* self)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004161{
4162 int err;
4163 db_recno_t recno;
4164 DBT key;
4165 DBT data;
4166
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004167 CHECK_CURSOR_NOT_CLOSED(self);
4168
4169 CLEAR_DBT(key);
4170 CLEAR_DBT(data);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004171
4172 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004173 err = _DBC_get(self->dbc, &key, &data, DB_GET_RECNO);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004174 MYDB_END_ALLOW_THREADS;
4175 RETURN_IF_ERR();
4176
4177 recno = *((db_recno_t*)data.data);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00004178 return NUMBER_FromLong(recno);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004179}
4180
4181
4182static PyObject*
4183DBC_last(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4184{
4185 return _DBCursor_get(self,DB_LAST,args,kwargs,"|iii:last");
4186}
4187
4188
4189static PyObject*
4190DBC_next(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4191{
4192 return _DBCursor_get(self,DB_NEXT,args,kwargs,"|iii:next");
4193}
4194
4195
4196static PyObject*
4197DBC_prev(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4198{
4199 return _DBCursor_get(self,DB_PREV,args,kwargs,"|iii:prev");
4200}
4201
4202
4203static PyObject*
4204DBC_put(DBCursorObject* self, PyObject* args, PyObject* kwargs)
4205{
4206 int err, flags = 0;
4207 PyObject* keyobj, *dataobj;
4208 DBT key, data;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00004209 static char* kwnames[] = { "key", "data", "flags", "dlen", "doff",
Jeremy Hyltonaf68c872005-12-10 18:50:16 +00004210 NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004211 int dlen = -1;
4212 int doff = -1;
4213
4214 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|iii:put", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004215 &keyobj, &dataobj, &flags, &dlen, &doff))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004216 return NULL;
4217
4218 CHECK_CURSOR_NOT_CLOSED(self);
4219
4220 if (!make_key_dbt(self->mydb, keyobj, &key, NULL))
4221 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004222 if (!make_dbt(dataobj, &data) ||
4223 !add_partial_dbt(&data, dlen, doff) )
4224 {
Jesus Ceaef9764f2008-05-13 18:45:46 +00004225 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004226 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004227 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004228
4229 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004230 err = _DBC_put(self->dbc, &key, &data, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004231 MYDB_END_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004232 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004233 RETURN_IF_ERR();
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004234 RETURN_NONE();
4235}
4236
4237
4238static PyObject*
4239DBC_set(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4240{
4241 int err, flags = 0;
4242 DBT key, data;
4243 PyObject* retval, *keyobj;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00004244 static char* kwnames[] = { "key", "flags", "dlen", "doff", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004245 int dlen = -1;
4246 int doff = -1;
4247
4248 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|iii:set", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004249 &keyobj, &flags, &dlen, &doff))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004250 return NULL;
4251
4252 CHECK_CURSOR_NOT_CLOSED(self);
4253
4254 if (!make_key_dbt(self->mydb, keyobj, &key, NULL))
4255 return NULL;
4256
4257 CLEAR_DBT(data);
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004258 if (!add_partial_dbt(&data, dlen, doff)) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00004259 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004260 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004261 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004262
4263 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004264 err = _DBC_get(self->dbc, &key, &data, flags|DB_SET);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004265 MYDB_END_ALLOW_THREADS;
Gregory P. Smithe9477062005-06-04 06:46:59 +00004266 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004267 && self->mydb->moduleFlags.cursorSetReturnsNone) {
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004268 Py_INCREF(Py_None);
4269 retval = Py_None;
4270 }
4271 else if (makeDBError(err)) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004272 retval = NULL;
4273 }
4274 else {
4275 switch (_DB_get_type(self->mydb)) {
4276 case -1:
4277 retval = NULL;
4278 break;
4279 case DB_BTREE:
4280 case DB_HASH:
4281 default:
Jesus Ceaef9764f2008-05-13 18:45:46 +00004282 retval = BuildValue_SS(key.data, key.size, data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004283 break;
4284 case DB_RECNO:
4285 case DB_QUEUE:
Jesus Ceaef9764f2008-05-13 18:45:46 +00004286 retval = BuildValue_IS(*((db_recno_t*)key.data), data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004287 break;
4288 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00004289 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004290 }
Gregory P. Smith19699a92004-06-28 04:06:49 +00004291 /* the only time REALLOC should be set is if we used an integer
4292 * key that make_key_dbt malloc'd for us. always free these. */
4293 if (key.flags & DB_DBT_REALLOC) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00004294 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Gregory P. Smith19699a92004-06-28 04:06:49 +00004295 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004296
4297 return retval;
4298}
4299
4300
4301static PyObject*
4302DBC_set_range(DBCursorObject* self, PyObject* args, PyObject* kwargs)
4303{
4304 int err, flags = 0;
4305 DBT key, data;
4306 PyObject* retval, *keyobj;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00004307 static char* kwnames[] = { "key", "flags", "dlen", "doff", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004308 int dlen = -1;
4309 int doff = -1;
4310
4311 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|iii:set_range", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004312 &keyobj, &flags, &dlen, &doff))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004313 return NULL;
4314
4315 CHECK_CURSOR_NOT_CLOSED(self);
4316
4317 if (!make_key_dbt(self->mydb, keyobj, &key, NULL))
4318 return NULL;
4319
4320 CLEAR_DBT(data);
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004321 if (!add_partial_dbt(&data, dlen, doff)) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00004322 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004323 return NULL;
4324 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004325 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004326 err = _DBC_get(self->dbc, &key, &data, flags|DB_SET_RANGE);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004327 MYDB_END_ALLOW_THREADS;
Gregory P. Smithe9477062005-06-04 06:46:59 +00004328 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004329 && self->mydb->moduleFlags.cursorSetReturnsNone) {
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004330 Py_INCREF(Py_None);
4331 retval = Py_None;
4332 }
4333 else if (makeDBError(err)) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004334 retval = NULL;
4335 }
4336 else {
4337 switch (_DB_get_type(self->mydb)) {
4338 case -1:
4339 retval = NULL;
4340 break;
4341 case DB_BTREE:
4342 case DB_HASH:
4343 default:
Jesus Ceaef9764f2008-05-13 18:45:46 +00004344 retval = BuildValue_SS(key.data, key.size, data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004345 break;
4346 case DB_RECNO:
4347 case DB_QUEUE:
Jesus Ceaef9764f2008-05-13 18:45:46 +00004348 retval = BuildValue_IS(*((db_recno_t*)key.data), data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004349 break;
4350 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00004351 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004352 }
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004353 /* the only time REALLOC should be set is if we used an integer
Gregory P. Smith19699a92004-06-28 04:06:49 +00004354 * key that make_key_dbt malloc'd for us. always free these. */
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004355 if (key.flags & DB_DBT_REALLOC) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00004356 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004357 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004358
4359 return retval;
4360}
4361
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004362static PyObject*
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004363_DBC_get_set_both(DBCursorObject* self, PyObject* keyobj, PyObject* dataobj,
4364 int flags, unsigned int returnsNone)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004365{
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004366 int err;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004367 DBT key, data;
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004368 PyObject* retval;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004369
Gregory P. Smith7441e652003-11-03 21:35:31 +00004370 /* the caller did this: CHECK_CURSOR_NOT_CLOSED(self); */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004371 if (!make_key_dbt(self->mydb, keyobj, &key, NULL))
4372 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004373 if (!make_dbt(dataobj, &data)) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00004374 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004375 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004376 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004377
4378 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004379 err = _DBC_get(self->dbc, &key, &data, flags|DB_GET_BOTH);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004380 MYDB_END_ALLOW_THREADS;
Gregory P. Smithe9477062005-06-04 06:46:59 +00004381 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY) && returnsNone) {
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004382 Py_INCREF(Py_None);
4383 retval = Py_None;
4384 }
4385 else if (makeDBError(err)) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004386 retval = NULL;
4387 }
4388 else {
4389 switch (_DB_get_type(self->mydb)) {
4390 case -1:
4391 retval = NULL;
4392 break;
4393 case DB_BTREE:
4394 case DB_HASH:
4395 default:
Jesus Ceaef9764f2008-05-13 18:45:46 +00004396 retval = BuildValue_SS(key.data, key.size, data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004397 break;
4398 case DB_RECNO:
4399 case DB_QUEUE:
Jesus Ceaef9764f2008-05-13 18:45:46 +00004400 retval = BuildValue_IS(*((db_recno_t*)key.data), data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004401 break;
4402 }
4403 }
4404
Jesus Ceaef9764f2008-05-13 18:45:46 +00004405 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004406 return retval;
4407}
4408
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004409static PyObject*
4410DBC_get_both(DBCursorObject* self, PyObject* args)
4411{
4412 int flags=0;
4413 PyObject *keyobj, *dataobj;
4414
4415 if (!PyArg_ParseTuple(args, "OO|i:get_both", &keyobj, &dataobj, &flags))
4416 return NULL;
4417
Gregory P. Smith7441e652003-11-03 21:35:31 +00004418 /* if the cursor is closed, self->mydb may be invalid */
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004419 CHECK_CURSOR_NOT_CLOSED(self);
4420
4421 return _DBC_get_set_both(self, keyobj, dataobj, flags,
4422 self->mydb->moduleFlags.getReturnsNone);
4423}
4424
Gregory P. Smithbe0db8b2003-10-01 06:48:51 +00004425/* Return size of entry */
4426static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00004427DBC_get_current_size(DBCursorObject* self)
Gregory P. Smithbe0db8b2003-10-01 06:48:51 +00004428{
4429 int err, flags=DB_CURRENT;
4430 PyObject* retval = NULL;
4431 DBT key, data;
4432
Gregory P. Smithbe0db8b2003-10-01 06:48:51 +00004433 CHECK_CURSOR_NOT_CLOSED(self);
4434 CLEAR_DBT(key);
4435 CLEAR_DBT(data);
4436
Gregory P. Smith8b7e9172004-12-13 09:51:23 +00004437 /* We don't allocate any memory, forcing a DB_BUFFER_SMALL error and thus
Gregory P. Smithbe0db8b2003-10-01 06:48:51 +00004438 getting the record size. */
4439 data.flags = DB_DBT_USERMEM;
4440 data.ulen = 0;
4441 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004442 err = _DBC_get(self->dbc, &key, &data, flags);
Gregory P. Smithbe0db8b2003-10-01 06:48:51 +00004443 MYDB_END_ALLOW_THREADS;
Gregory P. Smith8b7e9172004-12-13 09:51:23 +00004444 if (err == DB_BUFFER_SMALL || !err) {
4445 /* DB_BUFFER_SMALL means positive size, !err means zero length value */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00004446 retval = NUMBER_FromLong((long)data.size);
Gregory P. Smithbe0db8b2003-10-01 06:48:51 +00004447 err = 0;
4448 }
4449
Gregory P. Smithbe0db8b2003-10-01 06:48:51 +00004450 RETURN_IF_ERR();
4451 return retval;
4452}
4453
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004454static PyObject*
4455DBC_set_both(DBCursorObject* self, PyObject* args)
4456{
4457 int flags=0;
4458 PyObject *keyobj, *dataobj;
4459
4460 if (!PyArg_ParseTuple(args, "OO|i:set_both", &keyobj, &dataobj, &flags))
4461 return NULL;
4462
Gregory P. Smith7441e652003-11-03 21:35:31 +00004463 /* if the cursor is closed, self->mydb may be invalid */
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004464 CHECK_CURSOR_NOT_CLOSED(self);
4465
4466 return _DBC_get_set_both(self, keyobj, dataobj, flags,
4467 self->mydb->moduleFlags.cursorSetReturnsNone);
4468}
4469
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004470
4471static PyObject*
4472DBC_set_recno(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4473{
4474 int err, irecno, flags=0;
4475 db_recno_t recno;
4476 DBT key, data;
4477 PyObject* retval;
4478 int dlen = -1;
4479 int doff = -1;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00004480 static char* kwnames[] = { "recno","flags", "dlen", "doff", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004481
4482 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|iii:set_recno", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004483 &irecno, &flags, &dlen, &doff))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004484 return NULL;
4485
4486 CHECK_CURSOR_NOT_CLOSED(self);
4487
4488 CLEAR_DBT(key);
4489 recno = (db_recno_t) irecno;
Barry Warsaw9a0d7792002-12-30 20:53:52 +00004490 /* use allocated space so DB will be able to realloc room for the real
4491 * key */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004492 key.data = malloc(sizeof(db_recno_t));
4493 if (key.data == NULL) {
4494 PyErr_SetString(PyExc_MemoryError, "Key memory allocation failed");
4495 return NULL;
4496 }
4497 key.size = sizeof(db_recno_t);
4498 key.ulen = key.size;
4499 memcpy(key.data, &recno, sizeof(db_recno_t));
4500 key.flags = DB_DBT_REALLOC;
4501
4502 CLEAR_DBT(data);
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004503 if (!add_partial_dbt(&data, dlen, doff)) {
4504 FREE_DBT(key);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004505 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004506 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004507
4508 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004509 err = _DBC_get(self->dbc, &key, &data, flags|DB_SET_RECNO);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004510 MYDB_END_ALLOW_THREADS;
Gregory P. Smithe9477062005-06-04 06:46:59 +00004511 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004512 && self->mydb->moduleFlags.cursorSetReturnsNone) {
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004513 Py_INCREF(Py_None);
4514 retval = Py_None;
4515 }
4516 else if (makeDBError(err)) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004517 retval = NULL;
4518 }
4519 else { /* Can only be used for BTrees, so no need to return int key */
Jesus Ceaef9764f2008-05-13 18:45:46 +00004520 retval = BuildValue_SS(key.data, key.size, data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004521 }
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004522 FREE_DBT(key);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004523
4524 return retval;
4525}
4526
4527
4528static PyObject*
4529DBC_consume(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4530{
4531 return _DBCursor_get(self,DB_CONSUME,args,kwargs,"|iii:consume");
4532}
4533
4534
4535static PyObject*
4536DBC_next_dup(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4537{
4538 return _DBCursor_get(self,DB_NEXT_DUP,args,kwargs,"|iii:next_dup");
4539}
4540
4541
4542static PyObject*
4543DBC_next_nodup(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4544{
4545 return _DBCursor_get(self,DB_NEXT_NODUP,args,kwargs,"|iii:next_nodup");
4546}
4547
Jesus Cea6557aac2010-03-22 14:22:26 +00004548#if (DBVER >= 46)
4549static PyObject*
4550DBC_prev_dup(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4551{
4552 return _DBCursor_get(self,DB_PREV_DUP,args,kwargs,"|iii:prev_dup");
4553}
4554#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004555
4556static PyObject*
4557DBC_prev_nodup(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4558{
4559 return _DBCursor_get(self,DB_PREV_NODUP,args,kwargs,"|iii:prev_nodup");
4560}
4561
4562
4563static PyObject*
4564DBC_join_item(DBCursorObject* self, PyObject* args)
4565{
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004566 int err, flags=0;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004567 DBT key, data;
4568 PyObject* retval;
4569
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004570 if (!PyArg_ParseTuple(args, "|i:join_item", &flags))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004571 return NULL;
4572
4573 CHECK_CURSOR_NOT_CLOSED(self);
4574
4575 CLEAR_DBT(key);
4576 CLEAR_DBT(data);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004577
4578 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004579 err = _DBC_get(self->dbc, &key, &data, flags | DB_JOIN_ITEM);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004580 MYDB_END_ALLOW_THREADS;
Gregory P. Smithe9477062005-06-04 06:46:59 +00004581 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004582 && self->mydb->moduleFlags.getReturnsNone) {
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004583 Py_INCREF(Py_None);
4584 retval = Py_None;
4585 }
4586 else if (makeDBError(err)) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004587 retval = NULL;
4588 }
4589 else {
Jesus Ceaef9764f2008-05-13 18:45:46 +00004590 retval = BuildValue_S(key.data, key.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004591 }
4592
4593 return retval;
4594}
4595
4596
Jesus Cea6557aac2010-03-22 14:22:26 +00004597#if (DBVER >= 46)
4598static PyObject*
4599DBC_set_priority(DBCursorObject* self, PyObject* args, PyObject* kwargs)
4600{
4601 int err, priority;
4602 static char* kwnames[] = { "priority", NULL };
4603
4604 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i:set_priority", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004605 &priority))
Jesus Cea6557aac2010-03-22 14:22:26 +00004606 return NULL;
4607
4608 CHECK_CURSOR_NOT_CLOSED(self);
4609
4610 MYDB_BEGIN_ALLOW_THREADS;
4611 err = self->dbc->set_priority(self->dbc, priority);
4612 MYDB_END_ALLOW_THREADS;
4613 RETURN_IF_ERR();
4614 RETURN_NONE();
4615}
4616
4617
4618static PyObject*
4619DBC_get_priority(DBCursorObject* self)
4620{
4621 int err;
4622 DB_CACHE_PRIORITY priority;
4623
4624 CHECK_CURSOR_NOT_CLOSED(self);
4625
4626 MYDB_BEGIN_ALLOW_THREADS;
4627 err = self->dbc->get_priority(self->dbc, &priority);
4628 MYDB_END_ALLOW_THREADS;
4629 RETURN_IF_ERR();
4630 return NUMBER_FromLong(priority);
4631}
4632#endif
4633
4634
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004635
4636/* --------------------------------------------------------------------- */
4637/* DBEnv methods */
4638
4639
4640static PyObject*
Jesus Ceaef9764f2008-05-13 18:45:46 +00004641DBEnv_close_internal(DBEnvObject* self, int flags)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004642{
Jesus Ceaef9764f2008-05-13 18:45:46 +00004643 PyObject *dummy;
4644 int err;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004645
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004646 if (!self->closed) { /* Don't close more than once */
Jesus Ceaef9764f2008-05-13 18:45:46 +00004647 while(self->children_txns) {
Jesus Cea6557aac2010-03-22 14:22:26 +00004648 dummy = DBTxn_abort_discard_internal(self->children_txns, 0);
4649 Py_XDECREF(dummy);
Jesus Ceaef9764f2008-05-13 18:45:46 +00004650 }
4651 while(self->children_dbs) {
Jesus Cea6557aac2010-03-22 14:22:26 +00004652 dummy = DB_close_internal(self->children_dbs, 0, 0);
4653 Py_XDECREF(dummy);
4654 }
4655 while(self->children_logcursors) {
4656 dummy = DBLogCursor_close_internal(self->children_logcursors);
4657 Py_XDECREF(dummy);
Jesus Ceaef9764f2008-05-13 18:45:46 +00004658 }
Jesus Ceaac25fab2008-09-03 17:50:32 +00004659 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00004660
Jesus Ceaac25fab2008-09-03 17:50:32 +00004661 self->closed = 1;
4662 if (self->db_env) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004663 MYDB_BEGIN_ALLOW_THREADS;
4664 err = self->db_env->close(self->db_env, flags);
4665 MYDB_END_ALLOW_THREADS;
4666 /* after calling DBEnv->close, regardless of error, this DBEnv
Jesus Ceaef9764f2008-05-13 18:45:46 +00004667 * may not be accessed again (Berkeley DB docs). */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004668 self->db_env = NULL;
4669 RETURN_IF_ERR();
4670 }
4671 RETURN_NONE();
4672}
4673
Jesus Ceaef9764f2008-05-13 18:45:46 +00004674static PyObject*
4675DBEnv_close(DBEnvObject* self, PyObject* args)
4676{
4677 int flags = 0;
4678
4679 if (!PyArg_ParseTuple(args, "|i:close", &flags))
4680 return NULL;
Jesus Cea5cd5f122008-09-23 18:54:08 +00004681 return DBEnv_close_internal(self, flags);
Jesus Ceaef9764f2008-05-13 18:45:46 +00004682}
4683
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004684
4685static PyObject*
4686DBEnv_open(DBEnvObject* self, PyObject* args)
4687{
4688 int err, flags=0, mode=0660;
4689 char *db_home;
4690
4691 if (!PyArg_ParseTuple(args, "z|ii:open", &db_home, &flags, &mode))
4692 return NULL;
4693
4694 CHECK_ENV_NOT_CLOSED(self);
4695
4696 MYDB_BEGIN_ALLOW_THREADS;
4697 err = self->db_env->open(self->db_env, db_home, flags, mode);
4698 MYDB_END_ALLOW_THREADS;
4699 RETURN_IF_ERR();
4700 self->closed = 0;
4701 self->flags = flags;
4702 RETURN_NONE();
4703}
4704
4705
4706static PyObject*
Jesus Cea6557aac2010-03-22 14:22:26 +00004707DBEnv_memp_stat(DBEnvObject* self, PyObject* args, PyObject *kwargs)
4708{
4709 int err;
4710 DB_MPOOL_STAT *gsp;
4711 DB_MPOOL_FSTAT **fsp, **fsp2;
4712 PyObject* d = NULL, *d2, *d3, *r;
4713 u_int32_t flags = 0;
4714 static char* kwnames[] = { "flags", NULL };
4715
4716 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:memp_stat",
4717 kwnames, &flags))
4718 return NULL;
4719
4720 CHECK_ENV_NOT_CLOSED(self);
4721
4722 MYDB_BEGIN_ALLOW_THREADS;
4723 err = self->db_env->memp_stat(self->db_env, &gsp, &fsp, flags);
4724 MYDB_END_ALLOW_THREADS;
4725 RETURN_IF_ERR();
4726
4727 /* Turn the stat structure into a dictionary */
4728 d = PyDict_New();
4729 if (d == NULL) {
4730 if (gsp)
4731 free(gsp);
4732 return NULL;
4733 }
4734
4735#define MAKE_ENTRY(name) _addIntToDict(d, #name, gsp->st_##name)
4736
4737 MAKE_ENTRY(gbytes);
4738 MAKE_ENTRY(ncache);
4739#if (DBVER >= 46)
4740 MAKE_ENTRY(max_ncache);
4741#endif
4742 MAKE_ENTRY(regsize);
4743#if (DBVER >= 43)
4744 MAKE_ENTRY(mmapsize);
4745 MAKE_ENTRY(maxopenfd);
4746 MAKE_ENTRY(maxwrite);
4747 MAKE_ENTRY(maxwrite_sleep);
4748#endif
4749 MAKE_ENTRY(map);
4750 MAKE_ENTRY(cache_hit);
4751 MAKE_ENTRY(cache_miss);
4752 MAKE_ENTRY(page_create);
4753 MAKE_ENTRY(page_in);
4754 MAKE_ENTRY(page_out);
4755 MAKE_ENTRY(ro_evict);
4756 MAKE_ENTRY(rw_evict);
4757 MAKE_ENTRY(page_trickle);
4758 MAKE_ENTRY(pages);
4759 MAKE_ENTRY(page_clean);
4760 MAKE_ENTRY(page_dirty);
4761 MAKE_ENTRY(hash_buckets);
4762 MAKE_ENTRY(hash_searches);
4763 MAKE_ENTRY(hash_longest);
4764 MAKE_ENTRY(hash_examined);
4765 MAKE_ENTRY(hash_nowait);
4766 MAKE_ENTRY(hash_wait);
4767#if (DBVER >= 45)
4768 MAKE_ENTRY(hash_max_nowait);
4769#endif
4770 MAKE_ENTRY(hash_max_wait);
4771 MAKE_ENTRY(region_wait);
4772 MAKE_ENTRY(region_nowait);
4773#if (DBVER >= 45)
4774 MAKE_ENTRY(mvcc_frozen);
4775 MAKE_ENTRY(mvcc_thawed);
4776 MAKE_ENTRY(mvcc_freed);
4777#endif
4778 MAKE_ENTRY(alloc);
4779 MAKE_ENTRY(alloc_buckets);
4780 MAKE_ENTRY(alloc_max_buckets);
4781 MAKE_ENTRY(alloc_pages);
4782 MAKE_ENTRY(alloc_max_pages);
4783#if (DBVER >= 45)
4784 MAKE_ENTRY(io_wait);
4785#endif
4786#if (DBVER >= 48)
4787 MAKE_ENTRY(sync_interrupted);
4788#endif
4789
4790#undef MAKE_ENTRY
4791 free(gsp);
4792
4793 d2 = PyDict_New();
4794 if (d2 == NULL) {
4795 Py_DECREF(d);
4796 if (fsp)
4797 free(fsp);
4798 return NULL;
4799 }
4800#define MAKE_ENTRY(name) _addIntToDict(d3, #name, (*fsp2)->st_##name)
4801 for(fsp2=fsp;*fsp2; fsp2++) {
4802 d3 = PyDict_New();
4803 if (d3 == NULL) {
4804 Py_DECREF(d);
4805 Py_DECREF(d2);
4806 if (fsp)
4807 free(fsp);
4808 return NULL;
4809 }
4810 MAKE_ENTRY(pagesize);
4811 MAKE_ENTRY(cache_hit);
4812 MAKE_ENTRY(cache_miss);
4813 MAKE_ENTRY(map);
4814 MAKE_ENTRY(page_create);
4815 MAKE_ENTRY(page_in);
4816 MAKE_ENTRY(page_out);
4817 if(PyDict_SetItemString(d2, (*fsp2)->file_name, d3)) {
4818 Py_DECREF(d);
4819 Py_DECREF(d2);
4820 Py_DECREF(d3);
4821 if (fsp)
4822 free(fsp);
4823 return NULL;
4824 }
4825 Py_DECREF(d3);
4826 }
4827
4828#undef MAKE_ENTRY
4829 free(fsp);
4830
4831 r = Py_BuildValue("(OO)", d, d2);
4832 Py_DECREF(d);
4833 Py_DECREF(d2);
4834 return r;
4835}
4836
4837#if (DBVER >= 43)
4838static PyObject*
4839DBEnv_memp_stat_print(DBEnvObject* self, PyObject* args, PyObject *kwargs)
4840{
4841 int err;
4842 int flags=0;
4843 static char* kwnames[] = { "flags", NULL };
4844
4845 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:memp_stat_print",
4846 kwnames, &flags))
4847 {
4848 return NULL;
4849 }
4850 CHECK_ENV_NOT_CLOSED(self);
4851 MYDB_BEGIN_ALLOW_THREADS;
4852 err = self->db_env->memp_stat_print(self->db_env, flags);
4853 MYDB_END_ALLOW_THREADS;
4854 RETURN_IF_ERR();
4855 RETURN_NONE();
4856}
4857#endif
4858
4859
4860static PyObject*
4861DBEnv_memp_trickle(DBEnvObject* self, PyObject* args)
4862{
4863 int err, percent, nwrotep;
4864
4865 if (!PyArg_ParseTuple(args, "i:memp_trickle", &percent))
4866 return NULL;
4867 CHECK_ENV_NOT_CLOSED(self);
4868 MYDB_BEGIN_ALLOW_THREADS;
4869 err = self->db_env->memp_trickle(self->db_env, percent, &nwrotep);
4870 MYDB_END_ALLOW_THREADS;
4871 RETURN_IF_ERR();
4872 return NUMBER_FromLong(nwrotep);
4873}
4874
4875static PyObject*
4876DBEnv_memp_sync(DBEnvObject* self, PyObject* args)
4877{
4878 int err;
4879 DB_LSN lsn = {0, 0};
4880 DB_LSN *lsn_p = NULL;
4881
4882 if (!PyArg_ParseTuple(args, "|(ii):memp_sync", &lsn.file, &lsn.offset))
4883 return NULL;
4884 if ((lsn.file!=0) || (lsn.offset!=0)) {
4885 lsn_p = &lsn;
4886 }
4887 CHECK_ENV_NOT_CLOSED(self);
4888 MYDB_BEGIN_ALLOW_THREADS;
4889 err = self->db_env->memp_sync(self->db_env, lsn_p);
4890 MYDB_END_ALLOW_THREADS;
4891 RETURN_IF_ERR();
4892 RETURN_NONE();
4893}
4894
4895static PyObject*
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004896DBEnv_remove(DBEnvObject* self, PyObject* args)
4897{
4898 int err, flags=0;
4899 char *db_home;
4900
4901 if (!PyArg_ParseTuple(args, "s|i:remove", &db_home, &flags))
4902 return NULL;
4903 CHECK_ENV_NOT_CLOSED(self);
4904 MYDB_BEGIN_ALLOW_THREADS;
4905 err = self->db_env->remove(self->db_env, db_home, flags);
4906 MYDB_END_ALLOW_THREADS;
4907 RETURN_IF_ERR();
4908 RETURN_NONE();
4909}
4910
Barry Warsaw9a0d7792002-12-30 20:53:52 +00004911static PyObject*
4912DBEnv_dbremove(DBEnvObject* self, PyObject* args, PyObject* kwargs)
4913{
4914 int err;
4915 u_int32_t flags=0;
4916 char *file = NULL;
4917 char *database = NULL;
4918 PyObject *txnobj = NULL;
4919 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00004920 static char* kwnames[] = { "file", "database", "txn", "flags",
Jeremy Hyltonaf68c872005-12-10 18:50:16 +00004921 NULL };
Barry Warsaw9a0d7792002-12-30 20:53:52 +00004922
Gregory P. Smith641cddf2006-07-28 01:35:25 +00004923 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|zOi:dbremove", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004924 &file, &database, &txnobj, &flags)) {
4925 return NULL;
Barry Warsaw9a0d7792002-12-30 20:53:52 +00004926 }
4927 if (!checkTxnObj(txnobj, &txn)) {
4928 return NULL;
4929 }
4930 CHECK_ENV_NOT_CLOSED(self);
4931 MYDB_BEGIN_ALLOW_THREADS;
4932 err = self->db_env->dbremove(self->db_env, txn, file, database, flags);
4933 MYDB_END_ALLOW_THREADS;
4934 RETURN_IF_ERR();
4935 RETURN_NONE();
4936}
4937
4938static PyObject*
4939DBEnv_dbrename(DBEnvObject* self, PyObject* args, PyObject* kwargs)
4940{
4941 int err;
4942 u_int32_t flags=0;
4943 char *file = NULL;
4944 char *database = NULL;
4945 char *newname = NULL;
4946 PyObject *txnobj = NULL;
4947 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00004948 static char* kwnames[] = { "file", "database", "newname", "txn",
Jeremy Hyltonaf68c872005-12-10 18:50:16 +00004949 "flags", NULL };
Barry Warsaw9a0d7792002-12-30 20:53:52 +00004950
Gregory P. Smith641cddf2006-07-28 01:35:25 +00004951 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "szs|Oi:dbrename", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004952 &file, &database, &newname, &txnobj, &flags)) {
4953 return NULL;
Barry Warsaw9a0d7792002-12-30 20:53:52 +00004954 }
4955 if (!checkTxnObj(txnobj, &txn)) {
4956 return NULL;
4957 }
4958 CHECK_ENV_NOT_CLOSED(self);
4959 MYDB_BEGIN_ALLOW_THREADS;
4960 err = self->db_env->dbrename(self->db_env, txn, file, database, newname,
4961 flags);
4962 MYDB_END_ALLOW_THREADS;
4963 RETURN_IF_ERR();
4964 RETURN_NONE();
4965}
4966
Jesus Cea6557aac2010-03-22 14:22:26 +00004967
4968
Barry Warsaw9a0d7792002-12-30 20:53:52 +00004969static PyObject*
4970DBEnv_set_encrypt(DBEnvObject* self, PyObject* args, PyObject* kwargs)
4971{
4972 int err;
4973 u_int32_t flags=0;
4974 char *passwd = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00004975 static char* kwnames[] = { "passwd", "flags", NULL };
Barry Warsaw9a0d7792002-12-30 20:53:52 +00004976
4977 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|i:set_encrypt", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004978 &passwd, &flags)) {
4979 return NULL;
Barry Warsaw9a0d7792002-12-30 20:53:52 +00004980 }
4981
4982 MYDB_BEGIN_ALLOW_THREADS;
4983 err = self->db_env->set_encrypt(self->db_env, passwd, flags);
4984 MYDB_END_ALLOW_THREADS;
4985
4986 RETURN_IF_ERR();
4987 RETURN_NONE();
4988}
Jesus Cea6557aac2010-03-22 14:22:26 +00004989
4990#if (DBVER >= 42)
4991static PyObject*
4992DBEnv_get_encrypt_flags(DBEnvObject* self)
4993{
4994 int err;
4995 u_int32_t flags;
4996
4997 CHECK_ENV_NOT_CLOSED(self);
4998
4999 MYDB_BEGIN_ALLOW_THREADS;
5000 err = self->db_env->get_encrypt_flags(self->db_env, &flags);
5001 MYDB_END_ALLOW_THREADS;
5002
5003 RETURN_IF_ERR();
5004
5005 return NUMBER_FromLong(flags);
5006}
5007
5008static PyObject*
5009DBEnv_get_timeout(DBEnvObject* self, PyObject* args, PyObject* kwargs)
5010{
5011 int err;
5012 int flag;
5013 u_int32_t timeout;
5014 static char* kwnames[] = {"flag", NULL };
5015
5016 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i:get_timeout", kwnames,
5017 &flag)) {
5018 return NULL;
5019 }
5020 CHECK_ENV_NOT_CLOSED(self);
5021
5022 MYDB_BEGIN_ALLOW_THREADS;
5023 err = self->db_env->get_timeout(self->db_env, &timeout, flag);
5024 MYDB_END_ALLOW_THREADS;
5025 RETURN_IF_ERR();
5026 return NUMBER_FromLong(timeout);
5027}
5028#endif
5029
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005030
Gregory P. Smithfe11d3e2003-03-27 17:23:29 +00005031static PyObject*
5032DBEnv_set_timeout(DBEnvObject* self, PyObject* args, PyObject* kwargs)
5033{
5034 int err;
5035 u_int32_t flags=0;
5036 u_int32_t timeout = 0;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00005037 static char* kwnames[] = { "timeout", "flags", NULL };
Gregory P. Smithfe11d3e2003-03-27 17:23:29 +00005038
5039 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ii:set_timeout", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00005040 &timeout, &flags)) {
5041 return NULL;
Gregory P. Smithfe11d3e2003-03-27 17:23:29 +00005042 }
5043
5044 MYDB_BEGIN_ALLOW_THREADS;
5045 err = self->db_env->set_timeout(self->db_env, (db_timeout_t)timeout, flags);
5046 MYDB_END_ALLOW_THREADS;
5047
5048 RETURN_IF_ERR();
5049 RETURN_NONE();
5050}
Gregory P. Smithfe11d3e2003-03-27 17:23:29 +00005051
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005052static PyObject*
Gregory P. Smith6676f6e2003-08-28 21:50:30 +00005053DBEnv_set_shm_key(DBEnvObject* self, PyObject* args)
5054{
5055 int err;
5056 long shm_key = 0;
5057
5058 if (!PyArg_ParseTuple(args, "l:set_shm_key", &shm_key))
5059 return NULL;
5060 CHECK_ENV_NOT_CLOSED(self);
5061
5062 err = self->db_env->set_shm_key(self->db_env, shm_key);
5063 RETURN_IF_ERR();
5064 RETURN_NONE();
5065}
5066
Jesus Cea6557aac2010-03-22 14:22:26 +00005067#if (DBVER >= 42)
5068static PyObject*
5069DBEnv_get_shm_key(DBEnvObject* self)
5070{
5071 int err;
5072 long shm_key;
5073
5074 CHECK_ENV_NOT_CLOSED(self);
5075
5076 MYDB_BEGIN_ALLOW_THREADS;
5077 err = self->db_env->get_shm_key(self->db_env, &shm_key);
5078 MYDB_END_ALLOW_THREADS;
5079
5080 RETURN_IF_ERR();
5081
5082 return NUMBER_FromLong(shm_key);
5083}
5084#endif
5085
5086#if (DBVER >= 46)
5087static PyObject*
5088DBEnv_set_cache_max(DBEnvObject* self, PyObject* args)
5089{
5090 int err, gbytes, bytes;
5091
5092 if (!PyArg_ParseTuple(args, "ii:set_cache_max",
5093 &gbytes, &bytes))
5094 return NULL;
5095 CHECK_ENV_NOT_CLOSED(self);
5096
5097 MYDB_BEGIN_ALLOW_THREADS;
5098 err = self->db_env->set_cache_max(self->db_env, gbytes, bytes);
5099 MYDB_END_ALLOW_THREADS;
5100 RETURN_IF_ERR();
5101 RETURN_NONE();
5102}
5103
5104static PyObject*
5105DBEnv_get_cache_max(DBEnvObject* self)
5106{
5107 int err;
5108 u_int32_t gbytes, bytes;
5109
5110 CHECK_ENV_NOT_CLOSED(self);
5111
5112 MYDB_BEGIN_ALLOW_THREADS;
5113 err = self->db_env->get_cache_max(self->db_env, &gbytes, &bytes);
5114 MYDB_END_ALLOW_THREADS;
5115
5116 RETURN_IF_ERR();
5117
5118 return Py_BuildValue("(ii)", gbytes, bytes);
5119}
5120#endif
5121
5122#if (DBVER >= 46)
5123static PyObject*
5124DBEnv_set_thread_count(DBEnvObject* self, PyObject* args)
5125{
5126 int err;
5127 u_int32_t count;
5128
5129 if (!PyArg_ParseTuple(args, "i:set_thread_count", &count))
5130 return NULL;
5131 CHECK_ENV_NOT_CLOSED(self);
5132
5133 MYDB_BEGIN_ALLOW_THREADS;
5134 err = self->db_env->set_thread_count(self->db_env, count);
5135 MYDB_END_ALLOW_THREADS;
5136 RETURN_IF_ERR();
5137 RETURN_NONE();
5138}
5139
5140static PyObject*
5141DBEnv_get_thread_count(DBEnvObject* self)
5142{
5143 int err;
5144 u_int32_t count;
5145
5146 CHECK_ENV_NOT_CLOSED(self);
5147
5148 MYDB_BEGIN_ALLOW_THREADS;
5149 err = self->db_env->get_thread_count(self->db_env, &count);
5150 MYDB_END_ALLOW_THREADS;
5151 RETURN_IF_ERR();
5152 return NUMBER_FromLong(count);
5153}
5154#endif
5155
Gregory P. Smith6676f6e2003-08-28 21:50:30 +00005156static PyObject*
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005157DBEnv_set_cachesize(DBEnvObject* self, PyObject* args)
5158{
5159 int err, gbytes=0, bytes=0, ncache=0;
5160
5161 if (!PyArg_ParseTuple(args, "ii|i:set_cachesize",
5162 &gbytes, &bytes, &ncache))
5163 return NULL;
5164 CHECK_ENV_NOT_CLOSED(self);
5165
5166 MYDB_BEGIN_ALLOW_THREADS;
5167 err = self->db_env->set_cachesize(self->db_env, gbytes, bytes, ncache);
5168 MYDB_END_ALLOW_THREADS;
5169 RETURN_IF_ERR();
5170 RETURN_NONE();
5171}
5172
Jesus Cea6557aac2010-03-22 14:22:26 +00005173#if (DBVER >= 42)
5174static PyObject*
5175DBEnv_get_cachesize(DBEnvObject* self)
5176{
5177 int err;
5178 u_int32_t gbytes, bytes;
5179 int ncache;
5180
5181 CHECK_ENV_NOT_CLOSED(self);
5182
5183 MYDB_BEGIN_ALLOW_THREADS;
5184 err = self->db_env->get_cachesize(self->db_env, &gbytes, &bytes, &ncache);
5185 MYDB_END_ALLOW_THREADS;
5186
5187 RETURN_IF_ERR();
5188
5189 return Py_BuildValue("(iii)", gbytes, bytes, ncache);
5190}
5191#endif
5192
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005193
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005194static PyObject*
5195DBEnv_set_flags(DBEnvObject* self, PyObject* args)
5196{
5197 int err, flags=0, onoff=0;
5198
5199 if (!PyArg_ParseTuple(args, "ii:set_flags",
5200 &flags, &onoff))
5201 return NULL;
5202 CHECK_ENV_NOT_CLOSED(self);
5203
5204 MYDB_BEGIN_ALLOW_THREADS;
5205 err = self->db_env->set_flags(self->db_env, flags, onoff);
5206 MYDB_END_ALLOW_THREADS;
5207 RETURN_IF_ERR();
5208 RETURN_NONE();
5209}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005210
Jesus Cea6557aac2010-03-22 14:22:26 +00005211#if (DBVER >= 42)
5212static PyObject*
5213DBEnv_get_flags(DBEnvObject* self)
5214{
5215 int err;
5216 u_int32_t flags;
5217
5218 CHECK_ENV_NOT_CLOSED(self);
5219
5220 MYDB_BEGIN_ALLOW_THREADS;
5221 err = self->db_env->get_flags(self->db_env, &flags);
5222 MYDB_END_ALLOW_THREADS;
5223 RETURN_IF_ERR();
5224 return NUMBER_FromLong(flags);
5225}
5226#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005227
Jesus Ceaca3939c2008-05-22 15:27:38 +00005228#if (DBVER >= 47)
5229static PyObject*
5230DBEnv_log_set_config(DBEnvObject* self, PyObject* args)
5231{
5232 int err, flags, onoff;
5233
5234 if (!PyArg_ParseTuple(args, "ii:log_set_config",
5235 &flags, &onoff))
5236 return NULL;
5237 CHECK_ENV_NOT_CLOSED(self);
5238
5239 MYDB_BEGIN_ALLOW_THREADS;
5240 err = self->db_env->log_set_config(self->db_env, flags, onoff);
5241 MYDB_END_ALLOW_THREADS;
5242 RETURN_IF_ERR();
5243 RETURN_NONE();
5244}
Jesus Cea6557aac2010-03-22 14:22:26 +00005245
5246static PyObject*
5247DBEnv_log_get_config(DBEnvObject* self, PyObject* args)
5248{
5249 int err, flag, onoff;
5250
5251 if (!PyArg_ParseTuple(args, "i:log_get_config", &flag))
5252 return NULL;
5253 CHECK_ENV_NOT_CLOSED(self);
5254
5255 MYDB_BEGIN_ALLOW_THREADS;
5256 err = self->db_env->log_get_config(self->db_env, flag, &onoff);
5257 MYDB_END_ALLOW_THREADS;
5258 RETURN_IF_ERR();
5259 return PyBool_FromLong(onoff);
5260}
Jesus Ceaca3939c2008-05-22 15:27:38 +00005261#endif /* DBVER >= 47 */
5262
Jesus Cea6557aac2010-03-22 14:22:26 +00005263#if (DBVER >= 44)
5264static PyObject*
5265DBEnv_mutex_set_max(DBEnvObject* self, PyObject* args)
5266{
5267 int err;
5268 int value;
5269
5270 if (!PyArg_ParseTuple(args, "i:mutex_set_max", &value))
5271 return NULL;
5272
5273 CHECK_ENV_NOT_CLOSED(self);
5274
5275 MYDB_BEGIN_ALLOW_THREADS;
5276 err = self->db_env->mutex_set_max(self->db_env, value);
5277 MYDB_END_ALLOW_THREADS;
5278
5279 RETURN_IF_ERR();
5280 RETURN_NONE();
5281}
5282
5283static PyObject*
5284DBEnv_mutex_get_max(DBEnvObject* self)
5285{
5286 int err;
5287 u_int32_t value;
5288
5289 CHECK_ENV_NOT_CLOSED(self);
5290
5291 MYDB_BEGIN_ALLOW_THREADS;
5292 err = self->db_env->mutex_get_max(self->db_env, &value);
5293 MYDB_END_ALLOW_THREADS;
5294
5295 RETURN_IF_ERR();
5296
5297 return NUMBER_FromLong(value);
5298}
5299
5300static PyObject*
5301DBEnv_mutex_set_align(DBEnvObject* self, PyObject* args)
5302{
5303 int err;
5304 int align;
5305
5306 if (!PyArg_ParseTuple(args, "i:mutex_set_align", &align))
5307 return NULL;
5308
5309 CHECK_ENV_NOT_CLOSED(self);
5310
5311 MYDB_BEGIN_ALLOW_THREADS;
5312 err = self->db_env->mutex_set_align(self->db_env, align);
5313 MYDB_END_ALLOW_THREADS;
5314
5315 RETURN_IF_ERR();
5316 RETURN_NONE();
5317}
5318
5319static PyObject*
5320DBEnv_mutex_get_align(DBEnvObject* self)
5321{
5322 int err;
5323 u_int32_t align;
5324
5325 CHECK_ENV_NOT_CLOSED(self);
5326
5327 MYDB_BEGIN_ALLOW_THREADS;
5328 err = self->db_env->mutex_get_align(self->db_env, &align);
5329 MYDB_END_ALLOW_THREADS;
5330
5331 RETURN_IF_ERR();
5332
5333 return NUMBER_FromLong(align);
5334}
5335
5336static PyObject*
5337DBEnv_mutex_set_increment(DBEnvObject* self, PyObject* args)
5338{
5339 int err;
5340 int increment;
5341
5342 if (!PyArg_ParseTuple(args, "i:mutex_set_increment", &increment))
5343 return NULL;
5344
5345 CHECK_ENV_NOT_CLOSED(self);
5346
5347 MYDB_BEGIN_ALLOW_THREADS;
5348 err = self->db_env->mutex_set_increment(self->db_env, increment);
5349 MYDB_END_ALLOW_THREADS;
5350
5351 RETURN_IF_ERR();
5352 RETURN_NONE();
5353}
5354
5355static PyObject*
5356DBEnv_mutex_get_increment(DBEnvObject* self)
5357{
5358 int err;
5359 u_int32_t increment;
5360
5361 CHECK_ENV_NOT_CLOSED(self);
5362
5363 MYDB_BEGIN_ALLOW_THREADS;
5364 err = self->db_env->mutex_get_increment(self->db_env, &increment);
5365 MYDB_END_ALLOW_THREADS;
5366
5367 RETURN_IF_ERR();
5368
5369 return NUMBER_FromLong(increment);
5370}
5371
5372static PyObject*
5373DBEnv_mutex_set_tas_spins(DBEnvObject* self, PyObject* args)
5374{
5375 int err;
5376 int tas_spins;
5377
5378 if (!PyArg_ParseTuple(args, "i:mutex_set_tas_spins", &tas_spins))
5379 return NULL;
5380
5381 CHECK_ENV_NOT_CLOSED(self);
5382
5383 MYDB_BEGIN_ALLOW_THREADS;
5384 err = self->db_env->mutex_set_tas_spins(self->db_env, tas_spins);
5385 MYDB_END_ALLOW_THREADS;
5386
5387 RETURN_IF_ERR();
5388 RETURN_NONE();
5389}
5390
5391static PyObject*
5392DBEnv_mutex_get_tas_spins(DBEnvObject* self)
5393{
5394 int err;
5395 u_int32_t tas_spins;
5396
5397 CHECK_ENV_NOT_CLOSED(self);
5398
5399 MYDB_BEGIN_ALLOW_THREADS;
5400 err = self->db_env->mutex_get_tas_spins(self->db_env, &tas_spins);
5401 MYDB_END_ALLOW_THREADS;
5402
5403 RETURN_IF_ERR();
5404
5405 return NUMBER_FromLong(tas_spins);
5406}
5407#endif
Jesus Ceaca3939c2008-05-22 15:27:38 +00005408
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005409static PyObject*
5410DBEnv_set_data_dir(DBEnvObject* self, PyObject* args)
5411{
5412 int err;
5413 char *dir;
5414
5415 if (!PyArg_ParseTuple(args, "s:set_data_dir", &dir))
5416 return NULL;
5417 CHECK_ENV_NOT_CLOSED(self);
5418
5419 MYDB_BEGIN_ALLOW_THREADS;
5420 err = self->db_env->set_data_dir(self->db_env, dir);
5421 MYDB_END_ALLOW_THREADS;
5422 RETURN_IF_ERR();
5423 RETURN_NONE();
5424}
5425
Jesus Cea6557aac2010-03-22 14:22:26 +00005426#if (DBVER >= 42)
5427static PyObject*
5428DBEnv_get_data_dirs(DBEnvObject* self)
5429{
5430 int err;
5431 PyObject *tuple;
5432 PyObject *item;
5433 const char **dirpp;
5434 int size, i;
5435
5436 CHECK_ENV_NOT_CLOSED(self);
5437
5438 MYDB_BEGIN_ALLOW_THREADS;
5439 err = self->db_env->get_data_dirs(self->db_env, &dirpp);
5440 MYDB_END_ALLOW_THREADS;
5441
5442 RETURN_IF_ERR();
5443
5444 /*
5445 ** Calculate size. Python C API
5446 ** actually allows for tuple resizing,
5447 ** but this is simple enough.
5448 */
5449 for (size=0; *(dirpp+size) ; size++);
5450
5451 tuple = PyTuple_New(size);
5452 if (!tuple)
5453 return NULL;
5454
5455 for (i=0; i<size; i++) {
5456 item = PyBytes_FromString (*(dirpp+i));
5457 if (item == NULL) {
5458 Py_DECREF(tuple);
5459 tuple = NULL;
5460 break;
5461 }
5462 PyTuple_SET_ITEM(tuple, i, item);
5463 }
5464 return tuple;
5465}
5466#endif
5467
5468#if (DBVER >= 44)
5469static PyObject*
5470DBEnv_set_lg_filemode(DBEnvObject* self, PyObject* args)
5471{
5472 int err, filemode;
5473
5474 if (!PyArg_ParseTuple(args, "i:set_lg_filemode", &filemode))
5475 return NULL;
5476 CHECK_ENV_NOT_CLOSED(self);
5477
5478 MYDB_BEGIN_ALLOW_THREADS;
5479 err = self->db_env->set_lg_filemode(self->db_env, filemode);
5480 MYDB_END_ALLOW_THREADS;
5481 RETURN_IF_ERR();
5482 RETURN_NONE();
5483}
5484
5485static PyObject*
5486DBEnv_get_lg_filemode(DBEnvObject* self)
5487{
5488 int err, filemode;
5489
5490 CHECK_ENV_NOT_CLOSED(self);
5491
5492 MYDB_BEGIN_ALLOW_THREADS;
5493 err = self->db_env->get_lg_filemode(self->db_env, &filemode);
5494 MYDB_END_ALLOW_THREADS;
5495 RETURN_IF_ERR();
5496 return NUMBER_FromLong(filemode);
5497}
5498#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005499
5500static PyObject*
5501DBEnv_set_lg_bsize(DBEnvObject* self, PyObject* args)
5502{
5503 int err, lg_bsize;
5504
5505 if (!PyArg_ParseTuple(args, "i:set_lg_bsize", &lg_bsize))
5506 return NULL;
5507 CHECK_ENV_NOT_CLOSED(self);
5508
5509 MYDB_BEGIN_ALLOW_THREADS;
5510 err = self->db_env->set_lg_bsize(self->db_env, lg_bsize);
5511 MYDB_END_ALLOW_THREADS;
5512 RETURN_IF_ERR();
5513 RETURN_NONE();
5514}
5515
Jesus Cea6557aac2010-03-22 14:22:26 +00005516#if (DBVER >= 42)
5517static PyObject*
5518DBEnv_get_lg_bsize(DBEnvObject* self)
5519{
5520 int err;
5521 u_int32_t lg_bsize;
5522
5523 CHECK_ENV_NOT_CLOSED(self);
5524
5525 MYDB_BEGIN_ALLOW_THREADS;
5526 err = self->db_env->get_lg_bsize(self->db_env, &lg_bsize);
5527 MYDB_END_ALLOW_THREADS;
5528 RETURN_IF_ERR();
5529 return NUMBER_FromLong(lg_bsize);
5530}
5531#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005532
5533static PyObject*
5534DBEnv_set_lg_dir(DBEnvObject* self, PyObject* args)
5535{
5536 int err;
5537 char *dir;
5538
5539 if (!PyArg_ParseTuple(args, "s:set_lg_dir", &dir))
5540 return NULL;
5541 CHECK_ENV_NOT_CLOSED(self);
5542
5543 MYDB_BEGIN_ALLOW_THREADS;
5544 err = self->db_env->set_lg_dir(self->db_env, dir);
5545 MYDB_END_ALLOW_THREADS;
5546 RETURN_IF_ERR();
5547 RETURN_NONE();
5548}
5549
Jesus Cea6557aac2010-03-22 14:22:26 +00005550#if (DBVER >= 42)
5551static PyObject*
5552DBEnv_get_lg_dir(DBEnvObject* self)
5553{
5554 int err;
5555 const char *dirp;
5556
5557 CHECK_ENV_NOT_CLOSED(self);
5558
5559 MYDB_BEGIN_ALLOW_THREADS;
5560 err = self->db_env->get_lg_dir(self->db_env, &dirp);
5561 MYDB_END_ALLOW_THREADS;
5562 RETURN_IF_ERR();
5563 return PyBytes_FromString(dirp);
5564}
5565#endif
5566
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005567static PyObject*
5568DBEnv_set_lg_max(DBEnvObject* self, PyObject* args)
5569{
5570 int err, lg_max;
5571
5572 if (!PyArg_ParseTuple(args, "i:set_lg_max", &lg_max))
5573 return NULL;
5574 CHECK_ENV_NOT_CLOSED(self);
5575
5576 MYDB_BEGIN_ALLOW_THREADS;
5577 err = self->db_env->set_lg_max(self->db_env, lg_max);
5578 MYDB_END_ALLOW_THREADS;
5579 RETURN_IF_ERR();
5580 RETURN_NONE();
5581}
5582
Jesus Ceaef9764f2008-05-13 18:45:46 +00005583#if (DBVER >= 42)
5584static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00005585DBEnv_get_lg_max(DBEnvObject* self)
Jesus Ceaef9764f2008-05-13 18:45:46 +00005586{
5587 int err;
5588 u_int32_t lg_max;
5589
Jesus Ceaef9764f2008-05-13 18:45:46 +00005590 CHECK_ENV_NOT_CLOSED(self);
5591
5592 MYDB_BEGIN_ALLOW_THREADS;
5593 err = self->db_env->get_lg_max(self->db_env, &lg_max);
5594 MYDB_END_ALLOW_THREADS;
5595 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00005596 return NUMBER_FromLong(lg_max);
Jesus Ceaef9764f2008-05-13 18:45:46 +00005597}
5598#endif
5599
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005600
5601static PyObject*
Gregory P. Smithe9477062005-06-04 06:46:59 +00005602DBEnv_set_lg_regionmax(DBEnvObject* self, PyObject* args)
5603{
5604 int err, lg_max;
5605
5606 if (!PyArg_ParseTuple(args, "i:set_lg_regionmax", &lg_max))
5607 return NULL;
5608 CHECK_ENV_NOT_CLOSED(self);
5609
5610 MYDB_BEGIN_ALLOW_THREADS;
5611 err = self->db_env->set_lg_regionmax(self->db_env, lg_max);
5612 MYDB_END_ALLOW_THREADS;
5613 RETURN_IF_ERR();
5614 RETURN_NONE();
5615}
5616
Jesus Cea6557aac2010-03-22 14:22:26 +00005617#if (DBVER >= 42)
5618static PyObject*
5619DBEnv_get_lg_regionmax(DBEnvObject* self)
5620{
5621 int err;
5622 u_int32_t lg_regionmax;
5623
5624 CHECK_ENV_NOT_CLOSED(self);
5625
5626 MYDB_BEGIN_ALLOW_THREADS;
5627 err = self->db_env->get_lg_regionmax(self->db_env, &lg_regionmax);
5628 MYDB_END_ALLOW_THREADS;
5629 RETURN_IF_ERR();
5630 return NUMBER_FromLong(lg_regionmax);
5631}
5632#endif
5633
5634#if (DBVER >= 47)
5635static PyObject*
5636DBEnv_set_lk_partitions(DBEnvObject* self, PyObject* args)
5637{
5638 int err, lk_partitions;
5639
5640 if (!PyArg_ParseTuple(args, "i:set_lk_partitions", &lk_partitions))
5641 return NULL;
5642 CHECK_ENV_NOT_CLOSED(self);
5643
5644 MYDB_BEGIN_ALLOW_THREADS;
5645 err = self->db_env->set_lk_partitions(self->db_env, lk_partitions);
5646 MYDB_END_ALLOW_THREADS;
5647 RETURN_IF_ERR();
5648 RETURN_NONE();
5649}
5650
5651static PyObject*
5652DBEnv_get_lk_partitions(DBEnvObject* self)
5653{
5654 int err;
5655 u_int32_t lk_partitions;
5656
5657 CHECK_ENV_NOT_CLOSED(self);
5658
5659 MYDB_BEGIN_ALLOW_THREADS;
5660 err = self->db_env->get_lk_partitions(self->db_env, &lk_partitions);
5661 MYDB_END_ALLOW_THREADS;
5662 RETURN_IF_ERR();
5663 return NUMBER_FromLong(lk_partitions);
5664}
5665#endif
Gregory P. Smithe9477062005-06-04 06:46:59 +00005666
5667static PyObject*
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005668DBEnv_set_lk_detect(DBEnvObject* self, PyObject* args)
5669{
5670 int err, lk_detect;
5671
5672 if (!PyArg_ParseTuple(args, "i:set_lk_detect", &lk_detect))
5673 return NULL;
5674 CHECK_ENV_NOT_CLOSED(self);
5675
5676 MYDB_BEGIN_ALLOW_THREADS;
5677 err = self->db_env->set_lk_detect(self->db_env, lk_detect);
5678 MYDB_END_ALLOW_THREADS;
5679 RETURN_IF_ERR();
5680 RETURN_NONE();
5681}
5682
Jesus Cea6557aac2010-03-22 14:22:26 +00005683#if (DBVER >= 42)
5684static PyObject*
5685DBEnv_get_lk_detect(DBEnvObject* self)
5686{
5687 int err;
5688 u_int32_t lk_detect;
5689
5690 CHECK_ENV_NOT_CLOSED(self);
5691
5692 MYDB_BEGIN_ALLOW_THREADS;
5693 err = self->db_env->get_lk_detect(self->db_env, &lk_detect);
5694 MYDB_END_ALLOW_THREADS;
5695 RETURN_IF_ERR();
5696 return NUMBER_FromLong(lk_detect);
5697}
5698#endif
5699
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005700
Gregory P. Smith8b96a352007-01-05 01:59:42 +00005701#if (DBVER < 45)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005702static PyObject*
5703DBEnv_set_lk_max(DBEnvObject* self, PyObject* args)
5704{
5705 int err, max;
5706
5707 if (!PyArg_ParseTuple(args, "i:set_lk_max", &max))
5708 return NULL;
5709 CHECK_ENV_NOT_CLOSED(self);
5710
5711 MYDB_BEGIN_ALLOW_THREADS;
5712 err = self->db_env->set_lk_max(self->db_env, max);
5713 MYDB_END_ALLOW_THREADS;
5714 RETURN_IF_ERR();
5715 RETURN_NONE();
5716}
Gregory P. Smith8b96a352007-01-05 01:59:42 +00005717#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005718
5719
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005720
5721static PyObject*
5722DBEnv_set_lk_max_locks(DBEnvObject* self, PyObject* args)
5723{
5724 int err, max;
5725
5726 if (!PyArg_ParseTuple(args, "i:set_lk_max_locks", &max))
5727 return NULL;
5728 CHECK_ENV_NOT_CLOSED(self);
5729
5730 MYDB_BEGIN_ALLOW_THREADS;
5731 err = self->db_env->set_lk_max_locks(self->db_env, max);
5732 MYDB_END_ALLOW_THREADS;
5733 RETURN_IF_ERR();
5734 RETURN_NONE();
5735}
5736
Jesus Cea6557aac2010-03-22 14:22:26 +00005737#if (DBVER >= 42)
5738static PyObject*
5739DBEnv_get_lk_max_locks(DBEnvObject* self)
5740{
5741 int err;
5742 u_int32_t lk_max;
5743
5744 CHECK_ENV_NOT_CLOSED(self);
5745
5746 MYDB_BEGIN_ALLOW_THREADS;
5747 err = self->db_env->get_lk_max_locks(self->db_env, &lk_max);
5748 MYDB_END_ALLOW_THREADS;
5749 RETURN_IF_ERR();
5750 return NUMBER_FromLong(lk_max);
5751}
5752#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005753
5754static PyObject*
5755DBEnv_set_lk_max_lockers(DBEnvObject* self, PyObject* args)
5756{
5757 int err, max;
5758
5759 if (!PyArg_ParseTuple(args, "i:set_lk_max_lockers", &max))
5760 return NULL;
5761 CHECK_ENV_NOT_CLOSED(self);
5762
5763 MYDB_BEGIN_ALLOW_THREADS;
5764 err = self->db_env->set_lk_max_lockers(self->db_env, max);
5765 MYDB_END_ALLOW_THREADS;
5766 RETURN_IF_ERR();
5767 RETURN_NONE();
5768}
5769
Jesus Cea6557aac2010-03-22 14:22:26 +00005770#if (DBVER >= 42)
5771static PyObject*
5772DBEnv_get_lk_max_lockers(DBEnvObject* self)
5773{
5774 int err;
5775 u_int32_t lk_max;
5776
5777 CHECK_ENV_NOT_CLOSED(self);
5778
5779 MYDB_BEGIN_ALLOW_THREADS;
5780 err = self->db_env->get_lk_max_lockers(self->db_env, &lk_max);
5781 MYDB_END_ALLOW_THREADS;
5782 RETURN_IF_ERR();
5783 return NUMBER_FromLong(lk_max);
5784}
5785#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005786
5787static PyObject*
5788DBEnv_set_lk_max_objects(DBEnvObject* self, PyObject* args)
5789{
5790 int err, max;
5791
5792 if (!PyArg_ParseTuple(args, "i:set_lk_max_objects", &max))
5793 return NULL;
5794 CHECK_ENV_NOT_CLOSED(self);
5795
5796 MYDB_BEGIN_ALLOW_THREADS;
5797 err = self->db_env->set_lk_max_objects(self->db_env, max);
5798 MYDB_END_ALLOW_THREADS;
5799 RETURN_IF_ERR();
5800 RETURN_NONE();
5801}
5802
Jesus Cea6557aac2010-03-22 14:22:26 +00005803#if (DBVER >= 42)
5804static PyObject*
5805DBEnv_get_lk_max_objects(DBEnvObject* self)
5806{
5807 int err;
5808 u_int32_t lk_max;
5809
5810 CHECK_ENV_NOT_CLOSED(self);
5811
5812 MYDB_BEGIN_ALLOW_THREADS;
5813 err = self->db_env->get_lk_max_objects(self->db_env, &lk_max);
5814 MYDB_END_ALLOW_THREADS;
5815 RETURN_IF_ERR();
5816 return NUMBER_FromLong(lk_max);
5817}
5818#endif
5819
5820#if (DBVER >= 42)
5821static PyObject*
5822DBEnv_get_mp_mmapsize(DBEnvObject* self)
5823{
5824 int err;
5825 size_t mmapsize;
5826
5827 CHECK_ENV_NOT_CLOSED(self);
5828
5829 MYDB_BEGIN_ALLOW_THREADS;
5830 err = self->db_env->get_mp_mmapsize(self->db_env, &mmapsize);
5831 MYDB_END_ALLOW_THREADS;
5832 RETURN_IF_ERR();
5833 return NUMBER_FromLong(mmapsize);
5834}
5835#endif
5836
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005837
5838static PyObject*
5839DBEnv_set_mp_mmapsize(DBEnvObject* self, PyObject* args)
5840{
5841 int err, mp_mmapsize;
5842
5843 if (!PyArg_ParseTuple(args, "i:set_mp_mmapsize", &mp_mmapsize))
5844 return NULL;
5845 CHECK_ENV_NOT_CLOSED(self);
5846
5847 MYDB_BEGIN_ALLOW_THREADS;
5848 err = self->db_env->set_mp_mmapsize(self->db_env, mp_mmapsize);
5849 MYDB_END_ALLOW_THREADS;
5850 RETURN_IF_ERR();
5851 RETURN_NONE();
5852}
5853
5854
5855static PyObject*
5856DBEnv_set_tmp_dir(DBEnvObject* self, PyObject* args)
5857{
5858 int err;
5859 char *dir;
5860
5861 if (!PyArg_ParseTuple(args, "s:set_tmp_dir", &dir))
5862 return NULL;
5863 CHECK_ENV_NOT_CLOSED(self);
5864
5865 MYDB_BEGIN_ALLOW_THREADS;
5866 err = self->db_env->set_tmp_dir(self->db_env, dir);
5867 MYDB_END_ALLOW_THREADS;
5868 RETURN_IF_ERR();
5869 RETURN_NONE();
5870}
5871
5872
Jesus Cea6557aac2010-03-22 14:22:26 +00005873#if (DBVER >= 42)
5874static PyObject*
5875DBEnv_get_tmp_dir(DBEnvObject* self)
5876{
5877 int err;
5878 const char *dirpp;
5879
5880 CHECK_ENV_NOT_CLOSED(self);
5881
5882 MYDB_BEGIN_ALLOW_THREADS;
5883 err = self->db_env->get_tmp_dir(self->db_env, &dirpp);
5884 MYDB_END_ALLOW_THREADS;
5885
5886 RETURN_IF_ERR();
5887
5888 return PyBytes_FromString(dirpp);
5889}
5890#endif
5891
5892
Jesus Ceaef9764f2008-05-13 18:45:46 +00005893static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00005894DBEnv_txn_recover(DBEnvObject* self)
Jesus Ceaef9764f2008-05-13 18:45:46 +00005895{
5896 int flags = DB_FIRST;
5897 int err, i;
5898 PyObject *list, *tuple, *gid;
5899 DBTxnObject *txn;
5900#define PREPLIST_LEN 16
5901 DB_PREPLIST preplist[PREPLIST_LEN];
Matthias Klose54cc5392010-03-15 12:46:18 +00005902#if (DBVER < 48)
Jesus Ceaef9764f2008-05-13 18:45:46 +00005903 long retp;
Matthias Klose54cc5392010-03-15 12:46:18 +00005904#else
5905 u_int32_t retp;
5906#endif
Jesus Ceaef9764f2008-05-13 18:45:46 +00005907
Jesus Ceaef9764f2008-05-13 18:45:46 +00005908 CHECK_ENV_NOT_CLOSED(self);
5909
5910 list=PyList_New(0);
5911 if (!list)
5912 return NULL;
5913 while (!0) {
5914 MYDB_BEGIN_ALLOW_THREADS
5915 err=self->db_env->txn_recover(self->db_env,
5916 preplist, PREPLIST_LEN, &retp, flags);
5917#undef PREPLIST_LEN
5918 MYDB_END_ALLOW_THREADS
5919 if (err) {
5920 Py_DECREF(list);
5921 RETURN_IF_ERR();
5922 }
5923 if (!retp) break;
5924 flags=DB_NEXT; /* Prepare for next loop pass */
5925 for (i=0; i<retp; i++) {
Christian Heimes593daf52008-05-26 12:51:38 +00005926 gid=PyBytes_FromStringAndSize((char *)(preplist[i].gid),
Matthias Klose54cc5392010-03-15 12:46:18 +00005927 DB_GID_SIZE);
Jesus Ceaef9764f2008-05-13 18:45:46 +00005928 if (!gid) {
5929 Py_DECREF(list);
5930 return NULL;
5931 }
Jesus Cea6557aac2010-03-22 14:22:26 +00005932 txn=newDBTxnObject(self, NULL, preplist[i].txn, 0);
Jesus Ceaef9764f2008-05-13 18:45:46 +00005933 if (!txn) {
5934 Py_DECREF(list);
5935 Py_DECREF(gid);
5936 return NULL;
5937 }
5938 txn->flag_prepare=1; /* Recover state */
5939 tuple=PyTuple_New(2);
5940 if (!tuple) {
5941 Py_DECREF(list);
5942 Py_DECREF(gid);
5943 Py_DECREF(txn);
5944 return NULL;
5945 }
5946 if (PyTuple_SetItem(tuple, 0, gid)) {
5947 Py_DECREF(list);
5948 Py_DECREF(gid);
5949 Py_DECREF(txn);
5950 Py_DECREF(tuple);
5951 return NULL;
5952 }
5953 if (PyTuple_SetItem(tuple, 1, (PyObject *)txn)) {
5954 Py_DECREF(list);
5955 Py_DECREF(txn);
5956 Py_DECREF(tuple); /* This delete the "gid" also */
5957 return NULL;
5958 }
5959 if (PyList_Append(list, tuple)) {
5960 Py_DECREF(list);
5961 Py_DECREF(tuple);/* This delete the "gid" and the "txn" also */
5962 return NULL;
5963 }
5964 Py_DECREF(tuple);
5965 }
5966 }
5967 return list;
5968}
Jesus Ceaef9764f2008-05-13 18:45:46 +00005969
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005970static PyObject*
5971DBEnv_txn_begin(DBEnvObject* self, PyObject* args, PyObject* kwargs)
5972{
5973 int flags = 0;
5974 PyObject* txnobj = NULL;
5975 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00005976 static char* kwnames[] = { "parent", "flags", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005977
5978 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Oi:txn_begin", kwnames,
5979 &txnobj, &flags))
5980 return NULL;
5981
5982 if (!checkTxnObj(txnobj, &txn))
5983 return NULL;
5984 CHECK_ENV_NOT_CLOSED(self);
5985
Jesus Ceaef9764f2008-05-13 18:45:46 +00005986 return (PyObject*)newDBTxnObject(self, (DBTxnObject *)txnobj, NULL, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005987}
5988
5989
5990static PyObject*
5991DBEnv_txn_checkpoint(DBEnvObject* self, PyObject* args)
5992{
5993 int err, kbyte=0, min=0, flags=0;
5994
5995 if (!PyArg_ParseTuple(args, "|iii:txn_checkpoint", &kbyte, &min, &flags))
5996 return NULL;
5997 CHECK_ENV_NOT_CLOSED(self);
5998
5999 MYDB_BEGIN_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006000 err = self->db_env->txn_checkpoint(self->db_env, kbyte, min, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006001 MYDB_END_ALLOW_THREADS;
6002 RETURN_IF_ERR();
6003 RETURN_NONE();
6004}
6005
6006
Jesus Cea6557aac2010-03-22 14:22:26 +00006007#if (DBVER >= 42)
6008static PyObject*
6009DBEnv_get_tx_max(DBEnvObject* self)
6010{
6011 int err;
6012 u_int32_t max;
6013
6014 CHECK_ENV_NOT_CLOSED(self);
6015
6016 MYDB_BEGIN_ALLOW_THREADS;
6017 err = self->db_env->get_tx_max(self->db_env, &max);
6018 MYDB_END_ALLOW_THREADS;
6019 RETURN_IF_ERR();
6020 return PyLong_FromUnsignedLong(max);
6021}
6022#endif
6023
6024
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006025static PyObject*
6026DBEnv_set_tx_max(DBEnvObject* self, PyObject* args)
6027{
6028 int err, max;
6029
6030 if (!PyArg_ParseTuple(args, "i:set_tx_max", &max))
6031 return NULL;
6032 CHECK_ENV_NOT_CLOSED(self);
6033
Jesus Cea6557aac2010-03-22 14:22:26 +00006034 MYDB_BEGIN_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006035 err = self->db_env->set_tx_max(self->db_env, max);
Jesus Cea6557aac2010-03-22 14:22:26 +00006036 MYDB_END_ALLOW_THREADS;
Gregory P. Smith8a474042006-01-27 07:05:40 +00006037 RETURN_IF_ERR();
6038 RETURN_NONE();
6039}
6040
6041
Jesus Cea6557aac2010-03-22 14:22:26 +00006042#if (DBVER >= 42)
6043static PyObject*
6044DBEnv_get_tx_timestamp(DBEnvObject* self)
6045{
6046 int err;
6047 time_t timestamp;
6048
6049 CHECK_ENV_NOT_CLOSED(self);
6050
6051 MYDB_BEGIN_ALLOW_THREADS;
6052 err = self->db_env->get_tx_timestamp(self->db_env, &timestamp);
6053 MYDB_END_ALLOW_THREADS;
6054 RETURN_IF_ERR();
6055 return NUMBER_FromLong(timestamp);
6056}
6057#endif
6058
Gregory P. Smith8a474042006-01-27 07:05:40 +00006059static PyObject*
6060DBEnv_set_tx_timestamp(DBEnvObject* self, PyObject* args)
6061{
6062 int err;
Thomas Wouters9d63cca2006-03-01 01:01:55 +00006063 long stamp;
6064 time_t timestamp;
Gregory P. Smith8a474042006-01-27 07:05:40 +00006065
Thomas Wouters9d63cca2006-03-01 01:01:55 +00006066 if (!PyArg_ParseTuple(args, "l:set_tx_timestamp", &stamp))
Gregory P. Smith8a474042006-01-27 07:05:40 +00006067 return NULL;
6068 CHECK_ENV_NOT_CLOSED(self);
Thomas Wouters9d63cca2006-03-01 01:01:55 +00006069 timestamp = (time_t)stamp;
Jesus Cea6557aac2010-03-22 14:22:26 +00006070 MYDB_BEGIN_ALLOW_THREADS;
Thomas Wouters9d63cca2006-03-01 01:01:55 +00006071 err = self->db_env->set_tx_timestamp(self->db_env, &timestamp);
Jesus Cea6557aac2010-03-22 14:22:26 +00006072 MYDB_END_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006073 RETURN_IF_ERR();
6074 RETURN_NONE();
6075}
6076
6077
6078static PyObject*
6079DBEnv_lock_detect(DBEnvObject* self, PyObject* args)
6080{
6081 int err, atype, flags=0;
6082 int aborted = 0;
6083
6084 if (!PyArg_ParseTuple(args, "i|i:lock_detect", &atype, &flags))
6085 return NULL;
6086 CHECK_ENV_NOT_CLOSED(self);
6087
6088 MYDB_BEGIN_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006089 err = self->db_env->lock_detect(self->db_env, flags, atype, &aborted);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006090 MYDB_END_ALLOW_THREADS;
6091 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00006092 return NUMBER_FromLong(aborted);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006093}
6094
6095
6096static PyObject*
6097DBEnv_lock_get(DBEnvObject* self, PyObject* args)
6098{
6099 int flags=0;
6100 int locker, lock_mode;
6101 DBT obj;
6102 PyObject* objobj;
6103
6104 if (!PyArg_ParseTuple(args, "iOi|i:lock_get", &locker, &objobj, &lock_mode, &flags))
6105 return NULL;
6106
6107
6108 if (!make_dbt(objobj, &obj))
6109 return NULL;
6110
6111 return (PyObject*)newDBLockObject(self, locker, &obj, lock_mode, flags);
6112}
6113
6114
6115static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00006116DBEnv_lock_id(DBEnvObject* self)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006117{
6118 int err;
6119 u_int32_t theID;
6120
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006121 CHECK_ENV_NOT_CLOSED(self);
6122 MYDB_BEGIN_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006123 err = self->db_env->lock_id(self->db_env, &theID);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006124 MYDB_END_ALLOW_THREADS;
6125 RETURN_IF_ERR();
6126
Jesus Ceac5a11fa2008-07-23 11:38:42 +00006127 return NUMBER_FromLong((long)theID);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006128}
6129
Gregory P. Smithac11e022007-11-05 02:56:31 +00006130static PyObject*
6131DBEnv_lock_id_free(DBEnvObject* self, PyObject* args)
6132{
6133 int err;
6134 u_int32_t theID;
6135
6136 if (!PyArg_ParseTuple(args, "I:lock_id_free", &theID))
6137 return NULL;
6138
6139 CHECK_ENV_NOT_CLOSED(self);
6140 MYDB_BEGIN_ALLOW_THREADS;
6141 err = self->db_env->lock_id_free(self->db_env, theID);
6142 MYDB_END_ALLOW_THREADS;
6143 RETURN_IF_ERR();
6144 RETURN_NONE();
6145}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006146
6147static PyObject*
6148DBEnv_lock_put(DBEnvObject* self, PyObject* args)
6149{
6150 int err;
6151 DBLockObject* dblockobj;
6152
6153 if (!PyArg_ParseTuple(args, "O!:lock_put", &DBLock_Type, &dblockobj))
6154 return NULL;
6155
6156 CHECK_ENV_NOT_CLOSED(self);
6157 MYDB_BEGIN_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006158 err = self->db_env->lock_put(self->db_env, &dblockobj->lock);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006159 MYDB_END_ALLOW_THREADS;
6160 RETURN_IF_ERR();
6161 RETURN_NONE();
6162}
6163
Gregory P. Smithdb8a8072006-06-05 01:56:15 +00006164#if (DBVER >= 44)
6165static PyObject*
Jesus Cea6557aac2010-03-22 14:22:26 +00006166DBEnv_fileid_reset(DBEnvObject* self, PyObject* args, PyObject* kwargs)
6167{
6168 int err;
6169 char *file;
6170 u_int32_t flags = 0;
6171 static char* kwnames[] = { "file", "flags", NULL};
6172
6173 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "z|i:fileid_reset", kwnames,
6174 &file, &flags))
6175 return NULL;
6176 CHECK_ENV_NOT_CLOSED(self);
6177
6178 MYDB_BEGIN_ALLOW_THREADS;
6179 err = self->db_env->fileid_reset(self->db_env, file, flags);
6180 MYDB_END_ALLOW_THREADS;
6181 RETURN_IF_ERR();
6182 RETURN_NONE();
6183}
6184
6185static PyObject*
Gregory P. Smithdb8a8072006-06-05 01:56:15 +00006186DBEnv_lsn_reset(DBEnvObject* self, PyObject* args, PyObject* kwargs)
6187{
6188 int err;
6189 char *file;
6190 u_int32_t flags = 0;
6191 static char* kwnames[] = { "file", "flags", NULL};
6192
6193 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "z|i:lsn_reset", kwnames,
6194 &file, &flags))
6195 return NULL;
6196 CHECK_ENV_NOT_CLOSED(self);
6197
6198 MYDB_BEGIN_ALLOW_THREADS;
6199 err = self->db_env->lsn_reset(self->db_env, file, flags);
6200 MYDB_END_ALLOW_THREADS;
6201 RETURN_IF_ERR();
6202 RETURN_NONE();
6203}
6204#endif /* DBVER >= 4.4 */
6205
Jesus Cea6557aac2010-03-22 14:22:26 +00006206
6207#if (DBVER >= 43)
6208static PyObject*
6209DBEnv_stat_print(DBEnvObject* self, PyObject* args, PyObject *kwargs)
6210{
6211 int err;
6212 int flags=0;
6213 static char* kwnames[] = { "flags", NULL };
6214
6215 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:stat_print",
6216 kwnames, &flags))
6217 {
6218 return NULL;
6219 }
6220 CHECK_ENV_NOT_CLOSED(self);
6221 MYDB_BEGIN_ALLOW_THREADS;
6222 err = self->db_env->stat_print(self->db_env, flags);
6223 MYDB_END_ALLOW_THREADS;
6224 RETURN_IF_ERR();
6225 RETURN_NONE();
6226}
6227#endif
6228
6229
Gregory P. Smith76a82e82006-06-05 01:39:52 +00006230static PyObject*
6231DBEnv_log_stat(DBEnvObject* self, PyObject* args)
6232{
6233 int err;
6234 DB_LOG_STAT* statp = NULL;
6235 PyObject* d = NULL;
6236 u_int32_t flags = 0;
6237
6238 if (!PyArg_ParseTuple(args, "|i:log_stat", &flags))
6239 return NULL;
6240 CHECK_ENV_NOT_CLOSED(self);
6241
6242 MYDB_BEGIN_ALLOW_THREADS;
6243 err = self->db_env->log_stat(self->db_env, &statp, flags);
6244 MYDB_END_ALLOW_THREADS;
6245 RETURN_IF_ERR();
6246
6247 /* Turn the stat structure into a dictionary */
6248 d = PyDict_New();
6249 if (d == NULL) {
6250 if (statp)
6251 free(statp);
6252 return NULL;
6253 }
6254
6255#define MAKE_ENTRY(name) _addIntToDict(d, #name, statp->st_##name)
6256
6257 MAKE_ENTRY(magic);
6258 MAKE_ENTRY(version);
6259 MAKE_ENTRY(mode);
6260 MAKE_ENTRY(lg_bsize);
6261#if (DBVER >= 44)
6262 MAKE_ENTRY(lg_size);
6263 MAKE_ENTRY(record);
6264#endif
Gregory P. Smith76a82e82006-06-05 01:39:52 +00006265 MAKE_ENTRY(w_mbytes);
6266 MAKE_ENTRY(w_bytes);
6267 MAKE_ENTRY(wc_mbytes);
6268 MAKE_ENTRY(wc_bytes);
6269 MAKE_ENTRY(wcount);
6270 MAKE_ENTRY(wcount_fill);
6271#if (DBVER >= 44)
6272 MAKE_ENTRY(rcount);
6273#endif
6274 MAKE_ENTRY(scount);
6275 MAKE_ENTRY(cur_file);
6276 MAKE_ENTRY(cur_offset);
6277 MAKE_ENTRY(disk_file);
6278 MAKE_ENTRY(disk_offset);
6279 MAKE_ENTRY(maxcommitperflush);
6280 MAKE_ENTRY(mincommitperflush);
6281 MAKE_ENTRY(regsize);
6282 MAKE_ENTRY(region_wait);
6283 MAKE_ENTRY(region_nowait);
6284
6285#undef MAKE_ENTRY
6286 free(statp);
6287 return d;
6288} /* DBEnv_log_stat */
Gregory P. Smith76a82e82006-06-05 01:39:52 +00006289
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006290
Jesus Cea6557aac2010-03-22 14:22:26 +00006291#if (DBVER >= 43)
6292static PyObject*
6293DBEnv_log_stat_print(DBEnvObject* self, PyObject* args, PyObject *kwargs)
6294{
6295 int err;
6296 int flags=0;
6297 static char* kwnames[] = { "flags", NULL };
6298
6299 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:log_stat_print",
6300 kwnames, &flags))
6301 {
6302 return NULL;
6303 }
6304 CHECK_ENV_NOT_CLOSED(self);
6305 MYDB_BEGIN_ALLOW_THREADS;
6306 err = self->db_env->log_stat_print(self->db_env, flags);
6307 MYDB_END_ALLOW_THREADS;
6308 RETURN_IF_ERR();
6309 RETURN_NONE();
6310}
6311#endif
6312
6313
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006314static PyObject*
6315DBEnv_lock_stat(DBEnvObject* self, PyObject* args)
6316{
6317 int err;
6318 DB_LOCK_STAT* sp;
6319 PyObject* d = NULL;
Martin v. Löwisb2c7aff2002-11-23 11:26:07 +00006320 u_int32_t flags = 0;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006321
6322 if (!PyArg_ParseTuple(args, "|i:lock_stat", &flags))
6323 return NULL;
6324 CHECK_ENV_NOT_CLOSED(self);
6325
6326 MYDB_BEGIN_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006327 err = self->db_env->lock_stat(self->db_env, &sp, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006328 MYDB_END_ALLOW_THREADS;
6329 RETURN_IF_ERR();
6330
6331 /* Turn the stat structure into a dictionary */
6332 d = PyDict_New();
6333 if (d == NULL) {
6334 free(sp);
6335 return NULL;
6336 }
6337
6338#define MAKE_ENTRY(name) _addIntToDict(d, #name, sp->st_##name)
6339
Jesus Ceaef9764f2008-05-13 18:45:46 +00006340 MAKE_ENTRY(id);
6341 MAKE_ENTRY(cur_maxid);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006342 MAKE_ENTRY(nmodes);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006343 MAKE_ENTRY(maxlocks);
6344 MAKE_ENTRY(maxlockers);
6345 MAKE_ENTRY(maxobjects);
6346 MAKE_ENTRY(nlocks);
6347 MAKE_ENTRY(maxnlocks);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006348 MAKE_ENTRY(nlockers);
6349 MAKE_ENTRY(maxnlockers);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006350 MAKE_ENTRY(nobjects);
6351 MAKE_ENTRY(maxnobjects);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006352 MAKE_ENTRY(nrequests);
6353 MAKE_ENTRY(nreleases);
Jesus Ceaef9764f2008-05-13 18:45:46 +00006354#if (DBVER >= 44)
6355 MAKE_ENTRY(nupgrade);
6356 MAKE_ENTRY(ndowngrade);
6357#endif
Gregory P. Smith29602d22006-01-24 09:46:48 +00006358#if (DBVER < 44)
6359 MAKE_ENTRY(nnowaits); /* these were renamed in 4.4 */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006360 MAKE_ENTRY(nconflicts);
Gregory P. Smith29602d22006-01-24 09:46:48 +00006361#else
6362 MAKE_ENTRY(lock_nowait);
6363 MAKE_ENTRY(lock_wait);
6364#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006365 MAKE_ENTRY(ndeadlocks);
Jesus Ceaef9764f2008-05-13 18:45:46 +00006366 MAKE_ENTRY(locktimeout);
6367 MAKE_ENTRY(txntimeout);
Jesus Ceaef9764f2008-05-13 18:45:46 +00006368 MAKE_ENTRY(nlocktimeouts);
6369 MAKE_ENTRY(ntxntimeouts);
Jesus Ceaef9764f2008-05-13 18:45:46 +00006370#if (DBVER >= 46)
6371 MAKE_ENTRY(objs_wait);
6372 MAKE_ENTRY(objs_nowait);
6373 MAKE_ENTRY(lockers_wait);
6374 MAKE_ENTRY(lockers_nowait);
Jesus Ceaca3939c2008-05-22 15:27:38 +00006375#if (DBVER >= 47)
6376 MAKE_ENTRY(lock_wait);
6377 MAKE_ENTRY(lock_nowait);
6378#else
Jesus Ceaef9764f2008-05-13 18:45:46 +00006379 MAKE_ENTRY(locks_wait);
6380 MAKE_ENTRY(locks_nowait);
Jesus Ceaca3939c2008-05-22 15:27:38 +00006381#endif
Jesus Ceaef9764f2008-05-13 18:45:46 +00006382 MAKE_ENTRY(hash_len);
6383#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006384 MAKE_ENTRY(regsize);
6385 MAKE_ENTRY(region_wait);
6386 MAKE_ENTRY(region_nowait);
6387
6388#undef MAKE_ENTRY
6389 free(sp);
6390 return d;
6391}
6392
Jesus Cea6557aac2010-03-22 14:22:26 +00006393#if (DBVER >= 43)
6394static PyObject*
6395DBEnv_lock_stat_print(DBEnvObject* self, PyObject* args, PyObject *kwargs)
6396{
6397 int err;
6398 int flags=0;
6399 static char* kwnames[] = { "flags", NULL };
6400
6401 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:lock_stat_print",
6402 kwnames, &flags))
6403 {
6404 return NULL;
6405 }
6406 CHECK_ENV_NOT_CLOSED(self);
6407 MYDB_BEGIN_ALLOW_THREADS;
6408 err = self->db_env->lock_stat_print(self->db_env, flags);
6409 MYDB_END_ALLOW_THREADS;
6410 RETURN_IF_ERR();
6411 RETURN_NONE();
6412}
6413#endif
6414
6415
6416static PyObject*
6417DBEnv_log_cursor(DBEnvObject* self)
6418{
6419 int err;
6420 DB_LOGC* dblogc;
6421
6422 CHECK_ENV_NOT_CLOSED(self);
6423
6424 MYDB_BEGIN_ALLOW_THREADS;
6425 err = self->db_env->log_cursor(self->db_env, &dblogc, 0);
6426 MYDB_END_ALLOW_THREADS;
6427 RETURN_IF_ERR();
6428 return (PyObject*) newDBLogCursorObject(dblogc, self);
6429}
6430
6431
Jesus Ceaef9764f2008-05-13 18:45:46 +00006432static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00006433DBEnv_log_flush(DBEnvObject* self)
Jesus Ceaef9764f2008-05-13 18:45:46 +00006434{
6435 int err;
6436
Jesus Ceaef9764f2008-05-13 18:45:46 +00006437 CHECK_ENV_NOT_CLOSED(self);
6438
6439 MYDB_BEGIN_ALLOW_THREADS
6440 err = self->db_env->log_flush(self->db_env, NULL);
6441 MYDB_END_ALLOW_THREADS
6442
6443 RETURN_IF_ERR();
6444 RETURN_NONE();
6445}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006446
6447static PyObject*
Jesus Cea6557aac2010-03-22 14:22:26 +00006448DBEnv_log_file(DBEnvObject* self, PyObject* args)
6449{
6450 int err;
6451 DB_LSN lsn = {0, 0};
6452 int size = 20;
6453 char *name = NULL;
6454 PyObject *retval;
6455
6456 if (!PyArg_ParseTuple(args, "(ii):log_file", &lsn.file, &lsn.offset))
6457 return NULL;
6458
6459 CHECK_ENV_NOT_CLOSED(self);
6460
6461 do {
6462 name = malloc(size);
6463 if (!name) {
6464 PyErr_NoMemory();
6465 return NULL;
6466 }
6467 MYDB_BEGIN_ALLOW_THREADS;
6468 err = self->db_env->log_file(self->db_env, &lsn, name, size);
6469 MYDB_END_ALLOW_THREADS;
6470 if (err == EINVAL) {
6471 free(name);
6472 size *= 2;
6473 } else if (err) {
6474 free(name);
6475 RETURN_IF_ERR();
6476 assert(0); /* Unreachable... supposely */
6477 return NULL;
6478 }
6479/*
6480** If the final buffer we try is too small, we will
6481** get this exception:
6482** DBInvalidArgError:
6483** (22, 'Invalid argument -- DB_ENV->log_file: name buffer is too short')
6484*/
6485 } while ((err == EINVAL) && (size<(1<<17)));
6486
6487 RETURN_IF_ERR(); /* Maybe the size is not the problem */
6488
6489 retval = Py_BuildValue("s", name);
6490 free(name);
6491 return retval;
6492}
6493
6494
6495#if (DBVER >= 44)
6496static PyObject*
6497DBEnv_log_printf(DBEnvObject* self, PyObject* args, PyObject *kwargs)
6498{
6499 int err;
6500 char *string;
6501 PyObject *txnobj = NULL;
6502 DB_TXN *txn = NULL;
6503 static char* kwnames[] = {"string", "txn", NULL };
6504
6505 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|O:log_printf", kwnames,
6506 &string, &txnobj))
6507 return NULL;
6508
6509 CHECK_ENV_NOT_CLOSED(self);
6510
6511 if (!checkTxnObj(txnobj, &txn))
6512 return NULL;
6513
6514 /*
6515 ** Do not use the format string directly, to avoid attacks.
6516 */
6517 MYDB_BEGIN_ALLOW_THREADS;
6518 err = self->db_env->log_printf(self->db_env, txn, "%s", string);
6519 MYDB_END_ALLOW_THREADS;
6520
6521 RETURN_IF_ERR();
6522 RETURN_NONE();
6523}
6524#endif
6525
6526
6527static PyObject*
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006528DBEnv_log_archive(DBEnvObject* self, PyObject* args)
6529{
6530 int flags=0;
6531 int err;
Gregory P. Smith3dd20022006-06-05 00:31:01 +00006532 char **log_list = NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006533 PyObject* list;
6534 PyObject* item = NULL;
6535
6536 if (!PyArg_ParseTuple(args, "|i:log_archive", &flags))
6537 return NULL;
6538
6539 CHECK_ENV_NOT_CLOSED(self);
6540 MYDB_BEGIN_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006541 err = self->db_env->log_archive(self->db_env, &log_list, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006542 MYDB_END_ALLOW_THREADS;
6543 RETURN_IF_ERR();
6544
Gregory P. Smithbad47452006-06-05 00:33:35 +00006545 list = PyList_New(0);
6546 if (list == NULL) {
6547 if (log_list)
6548 free(log_list);
6549 return NULL;
6550 }
6551
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006552 if (log_list) {
Gregory P. Smith3dd20022006-06-05 00:31:01 +00006553 char **log_list_start;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006554 for (log_list_start = log_list; *log_list != NULL; ++log_list) {
Christian Heimes593daf52008-05-26 12:51:38 +00006555 item = PyBytes_FromString (*log_list);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006556 if (item == NULL) {
6557 Py_DECREF(list);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006558 list = NULL;
6559 break;
6560 }
Jesus Ceac5a11fa2008-07-23 11:38:42 +00006561 if (PyList_Append(list, item)) {
6562 Py_DECREF(list);
6563 list = NULL;
6564 Py_DECREF(item);
6565 break;
6566 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006567 Py_DECREF(item);
6568 }
6569 free(log_list_start);
6570 }
6571 return list;
6572}
6573
6574
Jesus Cea6557aac2010-03-22 14:22:26 +00006575#if (DBVER >= 44)
6576static PyObject*
6577DBEnv_mutex_stat(DBEnvObject* self, PyObject* args)
6578{
6579 int err;
6580 DB_MUTEX_STAT* statp = NULL;
6581 PyObject* d = NULL;
6582 u_int32_t flags = 0;
6583
6584 if (!PyArg_ParseTuple(args, "|i:mutex_stat", &flags))
6585 return NULL;
6586 CHECK_ENV_NOT_CLOSED(self);
6587
6588 MYDB_BEGIN_ALLOW_THREADS;
6589 err = self->db_env->mutex_stat(self->db_env, &statp, flags);
6590 MYDB_END_ALLOW_THREADS;
6591 RETURN_IF_ERR();
6592
6593 /* Turn the stat structure into a dictionary */
6594 d = PyDict_New();
6595 if (d == NULL) {
6596 if (statp)
6597 free(statp);
6598 return NULL;
6599 }
6600
6601#define MAKE_ENTRY(name) _addIntToDict(d, #name, statp->st_##name)
6602
6603 MAKE_ENTRY(mutex_align);
6604 MAKE_ENTRY(mutex_tas_spins);
6605 MAKE_ENTRY(mutex_cnt);
6606 MAKE_ENTRY(mutex_free);
6607 MAKE_ENTRY(mutex_inuse);
6608 MAKE_ENTRY(mutex_inuse_max);
6609 MAKE_ENTRY(regsize);
6610 MAKE_ENTRY(region_wait);
6611 MAKE_ENTRY(region_nowait);
6612
6613#undef MAKE_ENTRY
6614 free(statp);
6615 return d;
6616}
6617#endif
6618
6619
6620#if (DBVER >= 44)
6621static PyObject*
6622DBEnv_mutex_stat_print(DBEnvObject* self, PyObject* args, PyObject *kwargs)
6623{
6624 int err;
6625 int flags=0;
6626 static char* kwnames[] = { "flags", NULL };
6627
6628 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:mutex_stat_print",
6629 kwnames, &flags))
6630 {
6631 return NULL;
6632 }
6633 CHECK_ENV_NOT_CLOSED(self);
6634 MYDB_BEGIN_ALLOW_THREADS;
6635 err = self->db_env->mutex_stat_print(self->db_env, flags);
6636 MYDB_END_ALLOW_THREADS;
6637 RETURN_IF_ERR();
6638 RETURN_NONE();
6639}
6640#endif
6641
6642
6643#if (DBVER >= 43)
6644static PyObject*
6645DBEnv_txn_stat_print(DBEnvObject* self, PyObject* args, PyObject *kwargs)
6646{
6647 int err;
6648 int flags=0;
6649 static char* kwnames[] = { "flags", NULL };
6650
6651 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:stat_print",
6652 kwnames, &flags))
6653 {
6654 return NULL;
6655 }
6656
6657 CHECK_ENV_NOT_CLOSED(self);
6658
6659 MYDB_BEGIN_ALLOW_THREADS;
6660 err = self->db_env->txn_stat_print(self->db_env, flags);
6661 MYDB_END_ALLOW_THREADS;
6662 RETURN_IF_ERR();
6663 RETURN_NONE();
6664}
6665#endif
6666
6667
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006668static PyObject*
6669DBEnv_txn_stat(DBEnvObject* self, PyObject* args)
6670{
6671 int err;
6672 DB_TXN_STAT* sp;
6673 PyObject* d = NULL;
Martin v. Löwisb2c7aff2002-11-23 11:26:07 +00006674 u_int32_t flags=0;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006675
6676 if (!PyArg_ParseTuple(args, "|i:txn_stat", &flags))
6677 return NULL;
6678 CHECK_ENV_NOT_CLOSED(self);
6679
6680 MYDB_BEGIN_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006681 err = self->db_env->txn_stat(self->db_env, &sp, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006682 MYDB_END_ALLOW_THREADS;
6683 RETURN_IF_ERR();
6684
6685 /* Turn the stat structure into a dictionary */
6686 d = PyDict_New();
6687 if (d == NULL) {
6688 free(sp);
6689 return NULL;
6690 }
6691
Jesus Ceaef9764f2008-05-13 18:45:46 +00006692#define MAKE_ENTRY(name) _addIntToDict(d, #name, sp->st_##name)
6693#define MAKE_TIME_T_ENTRY(name) _addTimeTToDict(d, #name, sp->st_##name)
6694#define MAKE_DB_LSN_ENTRY(name) _addDB_lsnToDict(d, #name, sp->st_##name)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006695
Jesus Ceaef9764f2008-05-13 18:45:46 +00006696 MAKE_DB_LSN_ENTRY(last_ckp);
Kristján Valur Jónssonbd77c032007-04-26 15:24:54 +00006697 MAKE_TIME_T_ENTRY(time_ckp);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006698 MAKE_ENTRY(last_txnid);
6699 MAKE_ENTRY(maxtxns);
6700 MAKE_ENTRY(nactive);
6701 MAKE_ENTRY(maxnactive);
Jesus Ceaef9764f2008-05-13 18:45:46 +00006702#if (DBVER >= 45)
6703 MAKE_ENTRY(nsnapshot);
6704 MAKE_ENTRY(maxnsnapshot);
6705#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006706 MAKE_ENTRY(nbegins);
6707 MAKE_ENTRY(naborts);
6708 MAKE_ENTRY(ncommits);
Jesus Ceaef9764f2008-05-13 18:45:46 +00006709 MAKE_ENTRY(nrestores);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006710 MAKE_ENTRY(regsize);
6711 MAKE_ENTRY(region_wait);
6712 MAKE_ENTRY(region_nowait);
6713
Jesus Ceaef9764f2008-05-13 18:45:46 +00006714#undef MAKE_DB_LSN_ENTRY
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006715#undef MAKE_ENTRY
Kristján Valur Jónssonbd77c032007-04-26 15:24:54 +00006716#undef MAKE_TIME_T_ENTRY
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006717 free(sp);
6718 return d;
6719}
6720
6721
6722static PyObject*
6723DBEnv_set_get_returns_none(DBEnvObject* self, PyObject* args)
6724{
6725 int flags=0;
Gregory P. Smith455d46f2003-07-09 04:45:59 +00006726 int oldValue=0;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006727
6728 if (!PyArg_ParseTuple(args,"i:set_get_returns_none", &flags))
6729 return NULL;
6730 CHECK_ENV_NOT_CLOSED(self);
6731
Gregory P. Smith455d46f2003-07-09 04:45:59 +00006732 if (self->moduleFlags.getReturnsNone)
6733 ++oldValue;
6734 if (self->moduleFlags.cursorSetReturnsNone)
6735 ++oldValue;
6736 self->moduleFlags.getReturnsNone = (flags >= 1);
6737 self->moduleFlags.cursorSetReturnsNone = (flags >= 2);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00006738 return NUMBER_FromLong(oldValue);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006739}
6740
Jesus Ceac5a11fa2008-07-23 11:38:42 +00006741static PyObject*
6742DBEnv_get_private(DBEnvObject* self)
6743{
6744 /* We can give out the private field even if dbenv is closed */
Jesus Cea4907d272008-08-31 14:00:51 +00006745 Py_INCREF(self->private_obj);
6746 return self->private_obj;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00006747}
6748
6749static PyObject*
Jesus Cea4907d272008-08-31 14:00:51 +00006750DBEnv_set_private(DBEnvObject* self, PyObject* private_obj)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00006751{
6752 /* We can set the private field even if dbenv is closed */
Jesus Cea4907d272008-08-31 14:00:51 +00006753 Py_DECREF(self->private_obj);
6754 Py_INCREF(private_obj);
6755 self->private_obj = private_obj;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00006756 RETURN_NONE();
6757}
6758
6759
Matthias Klose54cc5392010-03-15 12:46:18 +00006760#if (DBVER < 48)
Jesus Ceaef9764f2008-05-13 18:45:46 +00006761static PyObject*
Jesus Ceaca3939c2008-05-22 15:27:38 +00006762DBEnv_set_rpc_server(DBEnvObject* self, PyObject* args, PyObject* kwargs)
6763{
6764 int err;
6765 char *host;
6766 long cl_timeout=0, sv_timeout=0;
6767
6768 static char* kwnames[] = { "host", "cl_timeout", "sv_timeout", NULL};
6769
6770 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|ll:set_rpc_server", kwnames,
6771 &host, &cl_timeout, &sv_timeout))
6772 return NULL;
6773 CHECK_ENV_NOT_CLOSED(self);
6774
6775 MYDB_BEGIN_ALLOW_THREADS;
6776 err = self->db_env->set_rpc_server(self->db_env, NULL, host, cl_timeout,
6777 sv_timeout, 0);
6778 MYDB_END_ALLOW_THREADS;
6779 RETURN_IF_ERR();
6780 RETURN_NONE();
6781}
Matthias Klose54cc5392010-03-15 12:46:18 +00006782#endif
Jesus Ceaca3939c2008-05-22 15:27:38 +00006783
Jesus Cea6557aac2010-03-22 14:22:26 +00006784#if (DBVER >= 43)
6785static PyObject*
6786DBEnv_set_mp_max_openfd(DBEnvObject* self, PyObject* args)
6787{
6788 int err;
6789 int maxopenfd;
6790
6791 if (!PyArg_ParseTuple(args, "i:set_mp_max_openfd", &maxopenfd)) {
6792 return NULL;
6793 }
6794 CHECK_ENV_NOT_CLOSED(self);
6795 MYDB_BEGIN_ALLOW_THREADS;
6796 err = self->db_env->set_mp_max_openfd(self->db_env, maxopenfd);
6797 MYDB_END_ALLOW_THREADS;
6798 RETURN_IF_ERR();
6799 RETURN_NONE();
6800}
6801
6802static PyObject*
6803DBEnv_get_mp_max_openfd(DBEnvObject* self)
6804{
6805 int err;
6806 int maxopenfd;
6807
6808 CHECK_ENV_NOT_CLOSED(self);
6809
6810 MYDB_BEGIN_ALLOW_THREADS;
6811 err = self->db_env->get_mp_max_openfd(self->db_env, &maxopenfd);
6812 MYDB_END_ALLOW_THREADS;
6813 RETURN_IF_ERR();
6814 return NUMBER_FromLong(maxopenfd);
6815}
6816
6817
6818static PyObject*
6819DBEnv_set_mp_max_write(DBEnvObject* self, PyObject* args)
6820{
6821 int err;
6822 int maxwrite, maxwrite_sleep;
6823
6824 if (!PyArg_ParseTuple(args, "ii:set_mp_max_write", &maxwrite,
6825 &maxwrite_sleep)) {
6826 return NULL;
6827 }
6828 CHECK_ENV_NOT_CLOSED(self);
6829 MYDB_BEGIN_ALLOW_THREADS;
6830 err = self->db_env->set_mp_max_write(self->db_env, maxwrite,
6831 maxwrite_sleep);
6832 MYDB_END_ALLOW_THREADS;
6833 RETURN_IF_ERR();
6834 RETURN_NONE();
6835}
6836
6837static PyObject*
6838DBEnv_get_mp_max_write(DBEnvObject* self)
6839{
6840 int err;
6841 int maxwrite;
6842#if (DBVER >= 46)
6843 db_timeout_t maxwrite_sleep;
6844#else
6845 int maxwrite_sleep;
6846#endif
6847
6848 CHECK_ENV_NOT_CLOSED(self);
6849
6850 MYDB_BEGIN_ALLOW_THREADS;
6851 err = self->db_env->get_mp_max_write(self->db_env, &maxwrite,
6852 &maxwrite_sleep);
6853 MYDB_END_ALLOW_THREADS;
6854 RETURN_IF_ERR();
6855
6856 return Py_BuildValue("(ii)", maxwrite, (int)maxwrite_sleep);
6857}
6858#endif
6859
6860
Jesus Ceaca3939c2008-05-22 15:27:38 +00006861static PyObject*
Jesus Ceaef9764f2008-05-13 18:45:46 +00006862DBEnv_set_verbose(DBEnvObject* self, PyObject* args)
6863{
6864 int err;
6865 int which, onoff;
6866
6867 if (!PyArg_ParseTuple(args, "ii:set_verbose", &which, &onoff)) {
6868 return NULL;
6869 }
6870 CHECK_ENV_NOT_CLOSED(self);
6871 MYDB_BEGIN_ALLOW_THREADS;
6872 err = self->db_env->set_verbose(self->db_env, which, onoff);
6873 MYDB_END_ALLOW_THREADS;
6874 RETURN_IF_ERR();
6875 RETURN_NONE();
6876}
6877
6878#if (DBVER >= 42)
6879static PyObject*
6880DBEnv_get_verbose(DBEnvObject* self, PyObject* args)
6881{
6882 int err;
6883 int which;
6884 int verbose;
6885
6886 if (!PyArg_ParseTuple(args, "i:get_verbose", &which)) {
6887 return NULL;
6888 }
6889 CHECK_ENV_NOT_CLOSED(self);
6890 MYDB_BEGIN_ALLOW_THREADS;
6891 err = self->db_env->get_verbose(self->db_env, which, &verbose);
6892 MYDB_END_ALLOW_THREADS;
6893 RETURN_IF_ERR();
6894 return PyBool_FromLong(verbose);
6895}
6896#endif
Jesus Ceaef9764f2008-05-13 18:45:46 +00006897
6898#if (DBVER >= 45)
6899static void
6900_dbenv_event_notifyCallback(DB_ENV* db_env, u_int32_t event, void *event_info)
6901{
6902 DBEnvObject *dbenv;
6903 PyObject* callback;
6904 PyObject* args;
6905 PyObject* result = NULL;
6906
6907 MYDB_BEGIN_BLOCK_THREADS;
6908 dbenv = (DBEnvObject *)db_env->app_private;
6909 callback = dbenv->event_notifyCallback;
6910 if (callback) {
6911 if (event == DB_EVENT_REP_NEWMASTER) {
6912 args = Py_BuildValue("(Oii)", dbenv, event, *((int *)event_info));
6913 } else {
6914 args = Py_BuildValue("(OiO)", dbenv, event, Py_None);
6915 }
6916 if (args) {
6917 result = PyEval_CallObject(callback, args);
6918 }
6919 if ((!args) || (!result)) {
6920 PyErr_Print();
6921 }
6922 Py_XDECREF(args);
6923 Py_XDECREF(result);
6924 }
6925 MYDB_END_BLOCK_THREADS;
6926}
6927#endif
6928
6929#if (DBVER >= 45)
6930static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00006931DBEnv_set_event_notify(DBEnvObject* self, PyObject* notifyFunc)
Jesus Ceaef9764f2008-05-13 18:45:46 +00006932{
6933 int err;
Jesus Ceaef9764f2008-05-13 18:45:46 +00006934
6935 CHECK_ENV_NOT_CLOSED(self);
6936
6937 if (!PyCallable_Check(notifyFunc)) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00006938 makeTypeError("Callable", notifyFunc);
6939 return NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00006940 }
6941
6942 Py_XDECREF(self->event_notifyCallback);
6943 Py_INCREF(notifyFunc);
6944 self->event_notifyCallback = notifyFunc;
6945
Jesus Ceac5a11fa2008-07-23 11:38:42 +00006946 /* This is to workaround a problem with un-initialized threads (see
6947 comment in DB_associate) */
6948#ifdef WITH_THREAD
6949 PyEval_InitThreads();
6950#endif
6951
Jesus Ceaef9764f2008-05-13 18:45:46 +00006952 MYDB_BEGIN_ALLOW_THREADS;
6953 err = self->db_env->set_event_notify(self->db_env, _dbenv_event_notifyCallback);
6954 MYDB_END_ALLOW_THREADS;
6955
6956 if (err) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00006957 Py_DECREF(notifyFunc);
6958 self->event_notifyCallback = NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00006959 }
6960
6961 RETURN_IF_ERR();
6962 RETURN_NONE();
6963}
6964#endif
6965
6966
6967/* --------------------------------------------------------------------- */
6968/* REPLICATION METHODS: Base Replication */
6969
Jesus Ceac5a11fa2008-07-23 11:38:42 +00006970
6971static PyObject*
6972DBEnv_rep_process_message(DBEnvObject* self, PyObject* args)
6973{
6974 int err;
6975 PyObject *control_py, *rec_py;
6976 DBT control, rec;
6977 int envid;
6978#if (DBVER >= 42)
6979 DB_LSN lsn;
6980#endif
6981
6982 if (!PyArg_ParseTuple(args, "OOi:rep_process_message", &control_py,
6983 &rec_py, &envid))
6984 return NULL;
6985 CHECK_ENV_NOT_CLOSED(self);
6986
6987 if (!make_dbt(control_py, &control))
6988 return NULL;
6989 if (!make_dbt(rec_py, &rec))
6990 return NULL;
6991
6992 MYDB_BEGIN_ALLOW_THREADS;
6993#if (DBVER >= 46)
6994 err = self->db_env->rep_process_message(self->db_env, &control, &rec,
6995 envid, &lsn);
6996#else
6997#if (DBVER >= 42)
6998 err = self->db_env->rep_process_message(self->db_env, &control, &rec,
6999 &envid, &lsn);
7000#else
7001 err = self->db_env->rep_process_message(self->db_env, &control, &rec,
7002 &envid);
7003#endif
7004#endif
7005 MYDB_END_ALLOW_THREADS;
7006 switch (err) {
7007 case DB_REP_NEWMASTER :
7008 return Py_BuildValue("(iO)", envid, Py_None);
7009 break;
7010
7011 case DB_REP_DUPMASTER :
7012 case DB_REP_HOLDELECTION :
7013#if (DBVER >= 44)
7014 case DB_REP_IGNORE :
7015 case DB_REP_JOIN_FAILURE :
7016#endif
7017 return Py_BuildValue("(iO)", err, Py_None);
7018 break;
7019 case DB_REP_NEWSITE :
Jesus Cea4907d272008-08-31 14:00:51 +00007020 {
7021 PyObject *tmp, *r;
7022
7023 if (!(tmp = PyBytes_FromStringAndSize(rec.data, rec.size))) {
7024 return NULL;
7025 }
7026
7027 r = Py_BuildValue("(iO)", err, tmp);
7028 Py_DECREF(tmp);
7029 return r;
7030 break;
7031 }
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007032#if (DBVER >= 42)
7033 case DB_REP_NOTPERM :
7034 case DB_REP_ISPERM :
7035 return Py_BuildValue("(i(ll))", err, lsn.file, lsn.offset);
7036 break;
7037#endif
7038 }
7039 RETURN_IF_ERR();
7040 return Py_BuildValue("(OO)", Py_None, Py_None);
7041}
7042
7043static int
7044_DBEnv_rep_transportCallback(DB_ENV* db_env, const DBT* control, const DBT* rec,
7045 const DB_LSN *lsn, int envid, u_int32_t flags)
7046{
7047 DBEnvObject *dbenv;
7048 PyObject* rep_transport;
7049 PyObject* args;
Jesus Cea4907d272008-08-31 14:00:51 +00007050 PyObject *a, *b;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007051 PyObject* result = NULL;
7052 int ret=0;
7053
7054 MYDB_BEGIN_BLOCK_THREADS;
7055 dbenv = (DBEnvObject *)db_env->app_private;
7056 rep_transport = dbenv->rep_transport;
7057
Jesus Cea4907d272008-08-31 14:00:51 +00007058 /*
7059 ** The errors in 'a' or 'b' are detected in "Py_BuildValue".
7060 */
7061 a = PyBytes_FromStringAndSize(control->data, control->size);
7062 b = PyBytes_FromStringAndSize(rec->data, rec->size);
7063
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007064 args = Py_BuildValue(
7065#if (PY_VERSION_HEX >= 0x02040000)
Jesus Cea4907d272008-08-31 14:00:51 +00007066 "(OOO(ll)iI)",
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007067#else
Jesus Cea4907d272008-08-31 14:00:51 +00007068 "(OOO(ll)ii)",
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007069#endif
7070 dbenv,
Jesus Cea4907d272008-08-31 14:00:51 +00007071 a, b,
7072 lsn->file, lsn->offset, envid, flags);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007073 if (args) {
7074 result = PyEval_CallObject(rep_transport, args);
7075 }
7076
7077 if ((!args) || (!result)) {
7078 PyErr_Print();
7079 ret = -1;
7080 }
Jesus Cea4907d272008-08-31 14:00:51 +00007081 Py_XDECREF(a);
7082 Py_XDECREF(b);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007083 Py_XDECREF(args);
7084 Py_XDECREF(result);
7085 MYDB_END_BLOCK_THREADS;
7086 return ret;
7087}
7088
7089#if (DBVER <= 41)
7090static int
7091_DBEnv_rep_transportCallbackOLD(DB_ENV* db_env, const DBT* control, const DBT* rec,
7092 int envid, u_int32_t flags)
7093{
7094 DB_LSN lsn;
7095
7096 lsn.file = -1; /* Dummy values */
7097 lsn.offset = -1;
7098 return _DBEnv_rep_transportCallback(db_env, control, rec, &lsn, envid,
7099 flags);
7100}
7101#endif
7102
7103static PyObject*
7104DBEnv_rep_set_transport(DBEnvObject* self, PyObject* args)
7105{
7106 int err;
7107 int envid;
7108 PyObject *rep_transport;
7109
7110 if (!PyArg_ParseTuple(args, "iO:rep_set_transport", &envid, &rep_transport))
7111 return NULL;
7112 CHECK_ENV_NOT_CLOSED(self);
7113 if (!PyCallable_Check(rep_transport)) {
7114 makeTypeError("Callable", rep_transport);
7115 return NULL;
7116 }
7117
7118 MYDB_BEGIN_ALLOW_THREADS;
7119#if (DBVER >=45)
7120 err = self->db_env->rep_set_transport(self->db_env, envid,
7121 &_DBEnv_rep_transportCallback);
7122#else
7123#if (DBVER >= 42)
7124 err = self->db_env->set_rep_transport(self->db_env, envid,
7125 &_DBEnv_rep_transportCallback);
7126#else
7127 err = self->db_env->set_rep_transport(self->db_env, envid,
7128 &_DBEnv_rep_transportCallbackOLD);
7129#endif
7130#endif
7131 MYDB_END_ALLOW_THREADS;
7132 RETURN_IF_ERR();
7133
7134 Py_DECREF(self->rep_transport);
7135 Py_INCREF(rep_transport);
7136 self->rep_transport = rep_transport;
7137 RETURN_NONE();
7138}
7139
7140#if (DBVER >= 47)
7141static PyObject*
7142DBEnv_rep_set_request(DBEnvObject* self, PyObject* args)
7143{
7144 int err;
7145 unsigned int minimum, maximum;
7146
7147 if (!PyArg_ParseTuple(args,"II:rep_set_request", &minimum, &maximum))
7148 return NULL;
7149 CHECK_ENV_NOT_CLOSED(self);
7150
7151 MYDB_BEGIN_ALLOW_THREADS;
7152 err = self->db_env->rep_set_request(self->db_env, minimum, maximum);
7153 MYDB_END_ALLOW_THREADS;
7154 RETURN_IF_ERR();
7155 RETURN_NONE();
7156}
7157
7158static PyObject*
7159DBEnv_rep_get_request(DBEnvObject* self)
7160{
7161 int err;
7162 u_int32_t minimum, maximum;
7163
7164 CHECK_ENV_NOT_CLOSED(self);
7165 MYDB_BEGIN_ALLOW_THREADS;
7166 err = self->db_env->rep_get_request(self->db_env, &minimum, &maximum);
7167 MYDB_END_ALLOW_THREADS;
7168 RETURN_IF_ERR();
7169#if (PY_VERSION_HEX >= 0x02040000)
7170 return Py_BuildValue("II", minimum, maximum);
7171#else
7172 return Py_BuildValue("ii", minimum, maximum);
7173#endif
7174}
7175#endif
7176
7177#if (DBVER >= 45)
7178static PyObject*
7179DBEnv_rep_set_limit(DBEnvObject* self, PyObject* args)
7180{
7181 int err;
7182 int limit;
7183
7184 if (!PyArg_ParseTuple(args,"i:rep_set_limit", &limit))
7185 return NULL;
7186 CHECK_ENV_NOT_CLOSED(self);
7187
7188 MYDB_BEGIN_ALLOW_THREADS;
7189 err = self->db_env->rep_set_limit(self->db_env, 0, limit);
7190 MYDB_END_ALLOW_THREADS;
7191 RETURN_IF_ERR();
7192 RETURN_NONE();
7193}
7194
7195static PyObject*
7196DBEnv_rep_get_limit(DBEnvObject* self)
7197{
7198 int err;
7199 u_int32_t gbytes, bytes;
7200
7201 CHECK_ENV_NOT_CLOSED(self);
7202 MYDB_BEGIN_ALLOW_THREADS;
7203 err = self->db_env->rep_get_limit(self->db_env, &gbytes, &bytes);
7204 MYDB_END_ALLOW_THREADS;
7205 RETURN_IF_ERR();
7206 return NUMBER_FromLong(bytes);
7207}
7208#endif
7209
7210#if (DBVER >= 44)
7211static PyObject*
7212DBEnv_rep_set_config(DBEnvObject* self, PyObject* args)
7213{
7214 int err;
7215 int which;
7216 int onoff;
7217
7218 if (!PyArg_ParseTuple(args,"ii:rep_set_config", &which, &onoff))
7219 return NULL;
7220 CHECK_ENV_NOT_CLOSED(self);
7221
7222 MYDB_BEGIN_ALLOW_THREADS;
7223 err = self->db_env->rep_set_config(self->db_env, which, onoff);
7224 MYDB_END_ALLOW_THREADS;
7225 RETURN_IF_ERR();
7226 RETURN_NONE();
7227}
7228
7229static PyObject*
7230DBEnv_rep_get_config(DBEnvObject* self, PyObject* args)
7231{
7232 int err;
7233 int which;
7234 int onoff;
7235
7236 if (!PyArg_ParseTuple(args, "i:rep_get_config", &which)) {
7237 return NULL;
7238 }
7239 CHECK_ENV_NOT_CLOSED(self);
7240 MYDB_BEGIN_ALLOW_THREADS;
7241 err = self->db_env->rep_get_config(self->db_env, which, &onoff);
7242 MYDB_END_ALLOW_THREADS;
7243 RETURN_IF_ERR();
7244 return PyBool_FromLong(onoff);
7245}
7246#endif
7247
7248#if (DBVER >= 46)
7249static PyObject*
7250DBEnv_rep_elect(DBEnvObject* self, PyObject* args)
7251{
7252 int err;
7253 u_int32_t nsites, nvotes;
7254
7255 if (!PyArg_ParseTuple(args, "II:rep_elect", &nsites, &nvotes)) {
7256 return NULL;
7257 }
7258 CHECK_ENV_NOT_CLOSED(self);
7259 MYDB_BEGIN_ALLOW_THREADS;
7260 err = self->db_env->rep_elect(self->db_env, nvotes, nvotes, 0);
7261 MYDB_END_ALLOW_THREADS;
7262 RETURN_IF_ERR();
7263 RETURN_NONE();
7264}
7265#endif
7266
7267static PyObject*
7268DBEnv_rep_start(DBEnvObject* self, PyObject* args, PyObject* kwargs)
7269{
7270 int err;
7271 PyObject *cdata_py = Py_None;
7272 DBT cdata;
7273 int flags;
7274 static char* kwnames[] = {"flags","cdata", NULL};
7275
7276 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
7277 "i|O:rep_start", kwnames, &flags, &cdata_py))
7278 {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00007279 return NULL;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007280 }
7281 CHECK_ENV_NOT_CLOSED(self);
7282
7283 if (!make_dbt(cdata_py, &cdata))
7284 return NULL;
7285
7286 MYDB_BEGIN_ALLOW_THREADS;
7287 err = self->db_env->rep_start(self->db_env, cdata.size ? &cdata : NULL,
7288 flags);
7289 MYDB_END_ALLOW_THREADS;
7290 RETURN_IF_ERR();
7291 RETURN_NONE();
7292}
7293
7294#if (DBVER >= 44)
7295static PyObject*
7296DBEnv_rep_sync(DBEnvObject* self)
7297{
7298 int err;
7299
7300 CHECK_ENV_NOT_CLOSED(self);
7301 MYDB_BEGIN_ALLOW_THREADS;
7302 err = self->db_env->rep_sync(self->db_env, 0);
7303 MYDB_END_ALLOW_THREADS;
7304 RETURN_IF_ERR();
7305 RETURN_NONE();
7306}
7307#endif
7308
7309
Jesus Ceaef9764f2008-05-13 18:45:46 +00007310#if (DBVER >= 45)
7311static PyObject*
7312DBEnv_rep_set_nsites(DBEnvObject* self, PyObject* args)
7313{
7314 int err;
7315 int nsites;
7316
7317 if (!PyArg_ParseTuple(args, "i:rep_set_nsites", &nsites)) {
7318 return NULL;
7319 }
7320 CHECK_ENV_NOT_CLOSED(self);
7321 MYDB_BEGIN_ALLOW_THREADS;
7322 err = self->db_env->rep_set_nsites(self->db_env, nsites);
7323 MYDB_END_ALLOW_THREADS;
7324 RETURN_IF_ERR();
7325 RETURN_NONE();
7326}
7327
7328static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007329DBEnv_rep_get_nsites(DBEnvObject* self)
Jesus Ceaef9764f2008-05-13 18:45:46 +00007330{
7331 int err;
Jesus Ceaca3939c2008-05-22 15:27:38 +00007332#if (DBVER >= 47)
7333 u_int32_t nsites;
7334#else
Jesus Ceaef9764f2008-05-13 18:45:46 +00007335 int nsites;
Jesus Ceaca3939c2008-05-22 15:27:38 +00007336#endif
Jesus Ceaef9764f2008-05-13 18:45:46 +00007337
Jesus Ceaef9764f2008-05-13 18:45:46 +00007338 CHECK_ENV_NOT_CLOSED(self);
7339 MYDB_BEGIN_ALLOW_THREADS;
7340 err = self->db_env->rep_get_nsites(self->db_env, &nsites);
7341 MYDB_END_ALLOW_THREADS;
7342 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007343 return NUMBER_FromLong(nsites);
Jesus Ceaef9764f2008-05-13 18:45:46 +00007344}
7345
7346static PyObject*
7347DBEnv_rep_set_priority(DBEnvObject* self, PyObject* args)
7348{
7349 int err;
7350 int priority;
7351
7352 if (!PyArg_ParseTuple(args, "i:rep_set_priority", &priority)) {
7353 return NULL;
7354 }
7355 CHECK_ENV_NOT_CLOSED(self);
7356 MYDB_BEGIN_ALLOW_THREADS;
7357 err = self->db_env->rep_set_priority(self->db_env, priority);
7358 MYDB_END_ALLOW_THREADS;
7359 RETURN_IF_ERR();
7360 RETURN_NONE();
7361}
7362
7363static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007364DBEnv_rep_get_priority(DBEnvObject* self)
Jesus Ceaef9764f2008-05-13 18:45:46 +00007365{
7366 int err;
Jesus Ceaca3939c2008-05-22 15:27:38 +00007367#if (DBVER >= 47)
7368 u_int32_t priority;
7369#else
Jesus Ceaef9764f2008-05-13 18:45:46 +00007370 int priority;
Jesus Ceaca3939c2008-05-22 15:27:38 +00007371#endif
Jesus Ceaef9764f2008-05-13 18:45:46 +00007372
Jesus Ceaef9764f2008-05-13 18:45:46 +00007373 CHECK_ENV_NOT_CLOSED(self);
7374 MYDB_BEGIN_ALLOW_THREADS;
7375 err = self->db_env->rep_get_priority(self->db_env, &priority);
7376 MYDB_END_ALLOW_THREADS;
7377 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007378 return NUMBER_FromLong(priority);
Jesus Ceaef9764f2008-05-13 18:45:46 +00007379}
7380
7381static PyObject*
7382DBEnv_rep_set_timeout(DBEnvObject* self, PyObject* args)
7383{
7384 int err;
7385 int which, timeout;
7386
7387 if (!PyArg_ParseTuple(args, "ii:rep_set_timeout", &which, &timeout)) {
7388 return NULL;
7389 }
7390 CHECK_ENV_NOT_CLOSED(self);
7391 MYDB_BEGIN_ALLOW_THREADS;
7392 err = self->db_env->rep_set_timeout(self->db_env, which, timeout);
7393 MYDB_END_ALLOW_THREADS;
7394 RETURN_IF_ERR();
7395 RETURN_NONE();
7396}
7397
7398static PyObject*
7399DBEnv_rep_get_timeout(DBEnvObject* self, PyObject* args)
7400{
7401 int err;
7402 int which;
7403 u_int32_t timeout;
7404
7405 if (!PyArg_ParseTuple(args, "i:rep_get_timeout", &which)) {
7406 return NULL;
7407 }
7408 CHECK_ENV_NOT_CLOSED(self);
7409 MYDB_BEGIN_ALLOW_THREADS;
7410 err = self->db_env->rep_get_timeout(self->db_env, which, &timeout);
7411 MYDB_END_ALLOW_THREADS;
7412 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007413 return NUMBER_FromLong(timeout);
Jesus Ceaef9764f2008-05-13 18:45:46 +00007414}
7415#endif
7416
Jesus Cea6557aac2010-03-22 14:22:26 +00007417
7418#if (DBVER >= 47)
7419static PyObject*
7420DBEnv_rep_set_clockskew(DBEnvObject* self, PyObject* args)
7421{
7422 int err;
7423 unsigned int fast, slow;
7424
7425#if (PY_VERSION_HEX >= 0x02040000)
7426 if (!PyArg_ParseTuple(args,"II:rep_set_clockskew", &fast, &slow))
7427 return NULL;
7428#else
7429 if (!PyArg_ParseTuple(args,"ii:rep_set_clockskew", &fast, &slow))
7430 return NULL;
7431#endif
7432
7433 CHECK_ENV_NOT_CLOSED(self);
7434
7435 MYDB_BEGIN_ALLOW_THREADS;
7436 err = self->db_env->rep_set_clockskew(self->db_env, fast, slow);
7437 MYDB_END_ALLOW_THREADS;
7438 RETURN_IF_ERR();
7439 RETURN_NONE();
7440}
7441
7442static PyObject*
7443DBEnv_rep_get_clockskew(DBEnvObject* self)
7444{
7445 int err;
7446 unsigned int fast, slow;
7447
7448 CHECK_ENV_NOT_CLOSED(self);
7449 MYDB_BEGIN_ALLOW_THREADS;
7450 err = self->db_env->rep_get_clockskew(self->db_env, &fast, &slow);
7451 MYDB_END_ALLOW_THREADS;
7452 RETURN_IF_ERR();
7453#if (PY_VERSION_HEX >= 0x02040000)
7454 return Py_BuildValue("(II)", fast, slow);
7455#else
7456 return Py_BuildValue("(ii)", fast, slow);
7457#endif
7458}
7459#endif
7460
7461#if (DBVER >= 43)
7462static PyObject*
7463DBEnv_rep_stat_print(DBEnvObject* self, PyObject* args, PyObject *kwargs)
7464{
7465 int err;
7466 int flags=0;
7467 static char* kwnames[] = { "flags", NULL };
7468
7469 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:rep_stat_print",
7470 kwnames, &flags))
7471 {
7472 return NULL;
7473 }
7474 CHECK_ENV_NOT_CLOSED(self);
7475 MYDB_BEGIN_ALLOW_THREADS;
7476 err = self->db_env->rep_stat_print(self->db_env, flags);
7477 MYDB_END_ALLOW_THREADS;
7478 RETURN_IF_ERR();
7479 RETURN_NONE();
7480}
7481#endif
7482
7483static PyObject*
7484DBEnv_rep_stat(DBEnvObject* self, PyObject* args, PyObject *kwargs)
7485{
7486 int err;
7487 int flags=0;
7488 DB_REP_STAT *statp;
7489 PyObject *stats;
7490 static char* kwnames[] = { "flags", NULL };
7491
7492 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:rep_stat",
7493 kwnames, &flags))
7494 {
7495 return NULL;
7496 }
7497 CHECK_ENV_NOT_CLOSED(self);
7498 MYDB_BEGIN_ALLOW_THREADS;
7499 err = self->db_env->rep_stat(self->db_env, &statp, flags);
7500 MYDB_END_ALLOW_THREADS;
7501 RETURN_IF_ERR();
7502
7503 stats=PyDict_New();
7504 if (stats == NULL) {
7505 free(statp);
7506 return NULL;
7507 }
7508
7509#define MAKE_ENTRY(name) _addIntToDict(stats, #name, statp->st_##name)
7510#define MAKE_DB_LSN_ENTRY(name) _addDB_lsnToDict(stats , #name, statp->st_##name)
7511
7512#if (DBVER >= 44)
7513 MAKE_ENTRY(bulk_fills);
7514 MAKE_ENTRY(bulk_overflows);
7515 MAKE_ENTRY(bulk_records);
7516 MAKE_ENTRY(bulk_transfers);
7517 MAKE_ENTRY(client_rerequests);
7518 MAKE_ENTRY(client_svc_miss);
7519 MAKE_ENTRY(client_svc_req);
7520#endif
7521 MAKE_ENTRY(dupmasters);
7522#if (DBVER >= 43)
7523 MAKE_ENTRY(egen);
7524 MAKE_ENTRY(election_nvotes);
7525 MAKE_ENTRY(startup_complete);
7526 MAKE_ENTRY(pg_duplicated);
7527 MAKE_ENTRY(pg_records);
7528 MAKE_ENTRY(pg_requested);
7529 MAKE_ENTRY(next_pg);
7530 MAKE_ENTRY(waiting_pg);
7531#endif
7532 MAKE_ENTRY(election_cur_winner);
7533 MAKE_ENTRY(election_gen);
7534 MAKE_DB_LSN_ENTRY(election_lsn);
7535 MAKE_ENTRY(election_nsites);
7536 MAKE_ENTRY(election_priority);
7537#if (DBVER >= 44)
7538 MAKE_ENTRY(election_sec);
7539 MAKE_ENTRY(election_usec);
7540#endif
7541 MAKE_ENTRY(election_status);
7542 MAKE_ENTRY(election_tiebreaker);
7543 MAKE_ENTRY(election_votes);
7544 MAKE_ENTRY(elections);
7545 MAKE_ENTRY(elections_won);
7546 MAKE_ENTRY(env_id);
7547 MAKE_ENTRY(env_priority);
7548 MAKE_ENTRY(gen);
7549 MAKE_ENTRY(log_duplicated);
7550 MAKE_ENTRY(log_queued);
7551 MAKE_ENTRY(log_queued_max);
7552 MAKE_ENTRY(log_queued_total);
7553 MAKE_ENTRY(log_records);
7554 MAKE_ENTRY(log_requested);
7555 MAKE_ENTRY(master);
7556 MAKE_ENTRY(master_changes);
7557#if (DBVER >= 47)
7558 MAKE_ENTRY(max_lease_sec);
7559 MAKE_ENTRY(max_lease_usec);
7560 MAKE_DB_LSN_ENTRY(max_perm_lsn);
7561#endif
7562 MAKE_ENTRY(msgs_badgen);
7563 MAKE_ENTRY(msgs_processed);
7564 MAKE_ENTRY(msgs_recover);
7565 MAKE_ENTRY(msgs_send_failures);
7566 MAKE_ENTRY(msgs_sent);
7567 MAKE_ENTRY(newsites);
7568 MAKE_DB_LSN_ENTRY(next_lsn);
7569 MAKE_ENTRY(nsites);
7570 MAKE_ENTRY(nthrottles);
7571 MAKE_ENTRY(outdated);
7572#if (DBVER >= 46)
7573 MAKE_ENTRY(startsync_delayed);
7574#endif
7575 MAKE_ENTRY(status);
7576 MAKE_ENTRY(txns_applied);
7577 MAKE_DB_LSN_ENTRY(waiting_lsn);
7578
7579#undef MAKE_DB_LSN_ENTRY
7580#undef MAKE_ENTRY
7581
7582 free(statp);
7583 return stats;
7584}
7585
Jesus Ceaef9764f2008-05-13 18:45:46 +00007586/* --------------------------------------------------------------------- */
7587/* REPLICATION METHODS: Replication Manager */
7588
7589#if (DBVER >= 45)
7590static PyObject*
7591DBEnv_repmgr_start(DBEnvObject* self, PyObject* args, PyObject*
7592 kwargs)
7593{
7594 int err;
7595 int nthreads, flags;
7596 static char* kwnames[] = {"nthreads","flags", NULL};
7597
7598 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
7599 "ii:repmgr_start", kwnames, &nthreads, &flags))
7600 {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00007601 return NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00007602 }
7603 CHECK_ENV_NOT_CLOSED(self);
7604 MYDB_BEGIN_ALLOW_THREADS;
7605 err = self->db_env->repmgr_start(self->db_env, nthreads, flags);
7606 MYDB_END_ALLOW_THREADS;
7607 RETURN_IF_ERR();
7608 RETURN_NONE();
7609}
7610
7611static PyObject*
7612DBEnv_repmgr_set_local_site(DBEnvObject* self, PyObject* args, PyObject*
7613 kwargs)
7614{
7615 int err;
7616 char *host;
7617 int port;
7618 int flags = 0;
7619 static char* kwnames[] = {"host", "port", "flags", NULL};
7620
7621 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
7622 "si|i:repmgr_set_local_site", kwnames, &host, &port, &flags))
7623 {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00007624 return NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00007625 }
7626 CHECK_ENV_NOT_CLOSED(self);
7627 MYDB_BEGIN_ALLOW_THREADS;
7628 err = self->db_env->repmgr_set_local_site(self->db_env, host, port, flags);
7629 MYDB_END_ALLOW_THREADS;
7630 RETURN_IF_ERR();
7631 RETURN_NONE();
7632}
7633
7634static PyObject*
7635DBEnv_repmgr_add_remote_site(DBEnvObject* self, PyObject* args, PyObject*
7636 kwargs)
7637{
7638 int err;
7639 char *host;
7640 int port;
7641 int flags = 0;
7642 int eidp;
7643 static char* kwnames[] = {"host", "port", "flags", NULL};
7644
7645 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
7646 "si|i:repmgr_add_remote_site", kwnames, &host, &port, &flags))
7647 {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00007648 return NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00007649 }
7650 CHECK_ENV_NOT_CLOSED(self);
7651 MYDB_BEGIN_ALLOW_THREADS;
7652 err = self->db_env->repmgr_add_remote_site(self->db_env, host, port, &eidp, flags);
7653 MYDB_END_ALLOW_THREADS;
7654 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007655 return NUMBER_FromLong(eidp);
Jesus Ceaef9764f2008-05-13 18:45:46 +00007656}
7657
7658static PyObject*
7659DBEnv_repmgr_set_ack_policy(DBEnvObject* self, PyObject* args)
7660{
7661 int err;
7662 int ack_policy;
7663
7664 if (!PyArg_ParseTuple(args, "i:repmgr_set_ack_policy", &ack_policy))
7665 {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00007666 return NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00007667 }
7668 CHECK_ENV_NOT_CLOSED(self);
7669 MYDB_BEGIN_ALLOW_THREADS;
7670 err = self->db_env->repmgr_set_ack_policy(self->db_env, ack_policy);
7671 MYDB_END_ALLOW_THREADS;
7672 RETURN_IF_ERR();
7673 RETURN_NONE();
7674}
7675
7676static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007677DBEnv_repmgr_get_ack_policy(DBEnvObject* self)
Jesus Ceaef9764f2008-05-13 18:45:46 +00007678{
7679 int err;
7680 int ack_policy;
7681
Jesus Ceaef9764f2008-05-13 18:45:46 +00007682 CHECK_ENV_NOT_CLOSED(self);
7683 MYDB_BEGIN_ALLOW_THREADS;
7684 err = self->db_env->repmgr_get_ack_policy(self->db_env, &ack_policy);
7685 MYDB_END_ALLOW_THREADS;
7686 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007687 return NUMBER_FromLong(ack_policy);
Jesus Ceaef9764f2008-05-13 18:45:46 +00007688}
7689
7690static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007691DBEnv_repmgr_site_list(DBEnvObject* self)
Jesus Ceaef9764f2008-05-13 18:45:46 +00007692{
7693 int err;
7694 unsigned int countp;
7695 DB_REPMGR_SITE *listp;
7696 PyObject *stats, *key, *tuple;
7697
Jesus Ceaef9764f2008-05-13 18:45:46 +00007698 CHECK_ENV_NOT_CLOSED(self);
7699 MYDB_BEGIN_ALLOW_THREADS;
7700 err = self->db_env->repmgr_site_list(self->db_env, &countp, &listp);
7701 MYDB_END_ALLOW_THREADS;
7702 RETURN_IF_ERR();
7703
7704 stats=PyDict_New();
7705 if (stats == NULL) {
7706 free(listp);
7707 return NULL;
7708 }
7709
7710 for(;countp--;) {
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007711 key=NUMBER_FromLong(listp[countp].eid);
Jesus Ceaef9764f2008-05-13 18:45:46 +00007712 if(!key) {
7713 Py_DECREF(stats);
7714 free(listp);
7715 return NULL;
7716 }
7717#if (PY_VERSION_HEX >= 0x02040000)
7718 tuple=Py_BuildValue("(sII)", listp[countp].host,
7719 listp[countp].port, listp[countp].status);
7720#else
7721 tuple=Py_BuildValue("(sii)", listp[countp].host,
7722 listp[countp].port, listp[countp].status);
7723#endif
7724 if(!tuple) {
7725 Py_DECREF(key);
7726 Py_DECREF(stats);
7727 free(listp);
7728 return NULL;
7729 }
7730 if(PyDict_SetItem(stats, key, tuple)) {
7731 Py_DECREF(key);
7732 Py_DECREF(tuple);
7733 Py_DECREF(stats);
7734 free(listp);
7735 return NULL;
7736 }
Florent Xiclunae7901c52010-03-01 20:45:01 +00007737 Py_DECREF(key);
7738 Py_DECREF(tuple);
Jesus Ceaef9764f2008-05-13 18:45:46 +00007739 }
7740 free(listp);
7741 return stats;
7742}
7743#endif
7744
7745#if (DBVER >= 46)
7746static PyObject*
7747DBEnv_repmgr_stat_print(DBEnvObject* self, PyObject* args, PyObject *kwargs)
7748{
7749 int err;
7750 int flags=0;
7751 static char* kwnames[] = { "flags", NULL };
7752
7753 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:repmgr_stat_print",
7754 kwnames, &flags))
7755 {
7756 return NULL;
7757 }
7758 CHECK_ENV_NOT_CLOSED(self);
7759 MYDB_BEGIN_ALLOW_THREADS;
7760 err = self->db_env->repmgr_stat_print(self->db_env, flags);
7761 MYDB_END_ALLOW_THREADS;
7762 RETURN_IF_ERR();
7763 RETURN_NONE();
7764}
7765
7766static PyObject*
7767DBEnv_repmgr_stat(DBEnvObject* self, PyObject* args, PyObject *kwargs)
7768{
7769 int err;
7770 int flags=0;
7771 DB_REPMGR_STAT *statp;
7772 PyObject *stats;
7773 static char* kwnames[] = { "flags", NULL };
7774
7775 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:repmgr_stat",
7776 kwnames, &flags))
7777 {
7778 return NULL;
7779 }
7780 CHECK_ENV_NOT_CLOSED(self);
7781 MYDB_BEGIN_ALLOW_THREADS;
7782 err = self->db_env->repmgr_stat(self->db_env, &statp, flags);
7783 MYDB_END_ALLOW_THREADS;
7784 RETURN_IF_ERR();
7785
7786 stats=PyDict_New();
7787 if (stats == NULL) {
7788 free(statp);
7789 return NULL;
7790 }
7791
7792#define MAKE_ENTRY(name) _addIntToDict(stats, #name, statp->st_##name)
7793
7794 MAKE_ENTRY(perm_failed);
7795 MAKE_ENTRY(msgs_queued);
7796 MAKE_ENTRY(msgs_dropped);
7797 MAKE_ENTRY(connection_drop);
7798 MAKE_ENTRY(connect_fail);
7799
7800#undef MAKE_ENTRY
7801
7802 free(statp);
7803 return stats;
7804}
7805#endif
7806
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00007807
7808/* --------------------------------------------------------------------- */
7809/* DBTxn methods */
7810
7811
Jesus Ceaef9764f2008-05-13 18:45:46 +00007812static void _close_transaction_cursors(DBTxnObject* txn)
7813{
7814 PyObject *dummy;
7815
7816 while(txn->children_cursors) {
7817 PyErr_Warn(PyExc_RuntimeWarning,
7818 "Must close cursors before resolving a transaction.");
7819 dummy=DBC_close_internal(txn->children_cursors);
7820 Py_XDECREF(dummy);
7821 }
7822}
7823
7824static void _promote_transaction_dbs_and_sequences(DBTxnObject *txn)
7825{
7826 DBObject *db;
7827#if (DBVER >= 43)
7828 DBSequenceObject *dbs;
7829#endif
7830
7831 while (txn->children_dbs) {
7832 db=txn->children_dbs;
7833 EXTRACT_FROM_DOUBLE_LINKED_LIST_TXN(db);
7834 if (txn->parent_txn) {
7835 INSERT_IN_DOUBLE_LINKED_LIST_TXN(txn->parent_txn->children_dbs,db);
7836 db->txn=txn->parent_txn;
7837 } else {
7838 /* The db is already linked to its environment,
7839 ** so nothing to do.
7840 */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00007841 db->txn=NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00007842 }
7843 }
7844
7845#if (DBVER >= 43)
7846 while (txn->children_sequences) {
7847 dbs=txn->children_sequences;
7848 EXTRACT_FROM_DOUBLE_LINKED_LIST_TXN(dbs);
7849 if (txn->parent_txn) {
7850 INSERT_IN_DOUBLE_LINKED_LIST_TXN(txn->parent_txn->children_sequences,dbs);
7851 dbs->txn=txn->parent_txn;
7852 } else {
7853 /* The sequence is already linked to its
7854 ** parent db. Nothing to do.
7855 */
7856 dbs->txn=NULL;
7857 }
7858 }
7859#endif
7860}
7861
7862
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00007863static PyObject*
7864DBTxn_commit(DBTxnObject* self, PyObject* args)
7865{
7866 int flags=0, err;
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00007867 DB_TXN *txn;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00007868
7869 if (!PyArg_ParseTuple(args, "|i:commit", &flags))
7870 return NULL;
7871
Jesus Ceaef9764f2008-05-13 18:45:46 +00007872 _close_transaction_cursors(self);
7873
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00007874 if (!self->txn) {
Thomas Woutersb3153832006-03-08 01:47:19 +00007875 PyObject *t = Py_BuildValue("(is)", 0, "DBTxn must not be used "
Jesus Ceaef9764f2008-05-13 18:45:46 +00007876 "after txn_commit, txn_abort "
7877 "or txn_discard");
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007878 if (t) {
7879 PyErr_SetObject(DBError, t);
7880 Py_DECREF(t);
7881 }
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00007882 return NULL;
7883 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00007884 self->flag_prepare=0;
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00007885 txn = self->txn;
7886 self->txn = NULL; /* this DB_TXN is no longer valid after this call */
Jesus Ceaef9764f2008-05-13 18:45:46 +00007887
7888 EXTRACT_FROM_DOUBLE_LINKED_LIST(self);
7889
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00007890 MYDB_BEGIN_ALLOW_THREADS;
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00007891 err = txn->commit(txn, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00007892 MYDB_END_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00007893
7894 _promote_transaction_dbs_and_sequences(self);
7895
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00007896 RETURN_IF_ERR();
7897 RETURN_NONE();
7898}
7899
7900static PyObject*
7901DBTxn_prepare(DBTxnObject* self, PyObject* args)
7902{
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00007903 int err;
7904 char* gid=NULL;
7905 int gid_size=0;
7906
7907 if (!PyArg_ParseTuple(args, "s#:prepare", &gid, &gid_size))
7908 return NULL;
7909
Matthias Klose54cc5392010-03-15 12:46:18 +00007910 if (gid_size != DB_GID_SIZE) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00007911 PyErr_SetString(PyExc_TypeError,
Matthias Klose54cc5392010-03-15 12:46:18 +00007912 "gid must be DB_GID_SIZE bytes long");
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00007913 return NULL;
7914 }
7915
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00007916 if (!self->txn) {
Thomas Woutersb3153832006-03-08 01:47:19 +00007917 PyObject *t = Py_BuildValue("(is)", 0,"DBTxn must not be used "
Jesus Ceaef9764f2008-05-13 18:45:46 +00007918 "after txn_commit, txn_abort "
7919 "or txn_discard");
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007920 if (t) {
7921 PyErr_SetObject(DBError, t);
7922 Py_DECREF(t);
7923 }
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00007924 return NULL;
7925 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00007926 self->flag_prepare=1; /* Prepare state */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00007927 MYDB_BEGIN_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00007928 err = self->txn->prepare(self->txn, (u_int8_t*)gid);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00007929 MYDB_END_ALLOW_THREADS;
7930 RETURN_IF_ERR();
7931 RETURN_NONE();
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00007932}
7933
7934
7935static PyObject*
Jesus Ceaef9764f2008-05-13 18:45:46 +00007936DBTxn_abort_discard_internal(DBTxnObject* self, int discard)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00007937{
Jesus Ceaef9764f2008-05-13 18:45:46 +00007938 PyObject *dummy;
7939 int err=0;
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00007940 DB_TXN *txn;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00007941
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00007942 if (!self->txn) {
Thomas Woutersb3153832006-03-08 01:47:19 +00007943 PyObject *t = Py_BuildValue("(is)", 0, "DBTxn must not be used "
Jesus Ceaef9764f2008-05-13 18:45:46 +00007944 "after txn_commit, txn_abort "
7945 "or txn_discard");
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007946 if (t) {
7947 PyErr_SetObject(DBError, t);
7948 Py_DECREF(t);
7949 }
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00007950 return NULL;
7951 }
7952 txn = self->txn;
7953 self->txn = NULL; /* this DB_TXN is no longer valid after this call */
Jesus Ceaef9764f2008-05-13 18:45:46 +00007954
7955 _close_transaction_cursors(self);
7956#if (DBVER >= 43)
7957 while (self->children_sequences) {
7958 dummy=DBSequence_close_internal(self->children_sequences,0,0);
7959 Py_XDECREF(dummy);
7960 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00007961#endif
Jesus Ceaef9764f2008-05-13 18:45:46 +00007962 while (self->children_dbs) {
Jesus Cea5cd5f122008-09-23 18:54:08 +00007963 dummy=DB_close_internal(self->children_dbs, 0, 0);
Jesus Ceaef9764f2008-05-13 18:45:46 +00007964 Py_XDECREF(dummy);
7965 }
7966
7967 EXTRACT_FROM_DOUBLE_LINKED_LIST(self);
7968
7969 MYDB_BEGIN_ALLOW_THREADS;
7970 if (discard) {
7971 assert(!self->flag_prepare);
Jesus Ceaef9764f2008-05-13 18:45:46 +00007972 err = txn->discard(txn,0);
Jesus Ceaef9764f2008-05-13 18:45:46 +00007973 } else {
7974 /*
7975 ** If the transaction is in the "prepare" or "recover" state,
7976 ** we better do not implicitly abort it.
7977 */
7978 if (!self->flag_prepare) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00007979 err = txn->abort(txn);
Jesus Ceaef9764f2008-05-13 18:45:46 +00007980 }
7981 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00007982 MYDB_END_ALLOW_THREADS;
7983 RETURN_IF_ERR();
7984 RETURN_NONE();
7985}
7986
Jesus Ceaef9764f2008-05-13 18:45:46 +00007987static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007988DBTxn_abort(DBTxnObject* self)
Jesus Ceaef9764f2008-05-13 18:45:46 +00007989{
Jesus Ceaef9764f2008-05-13 18:45:46 +00007990 self->flag_prepare=0;
7991 _close_transaction_cursors(self);
7992
7993 return DBTxn_abort_discard_internal(self,0);
7994}
7995
7996static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007997DBTxn_discard(DBTxnObject* self)
Jesus Ceaef9764f2008-05-13 18:45:46 +00007998{
Jesus Ceaef9764f2008-05-13 18:45:46 +00007999 self->flag_prepare=0;
8000 _close_transaction_cursors(self);
8001
8002 return DBTxn_abort_discard_internal(self,1);
8003}
8004
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008005
8006static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008007DBTxn_id(DBTxnObject* self)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008008{
8009 int id;
8010
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008011 if (!self->txn) {
Thomas Woutersb3153832006-03-08 01:47:19 +00008012 PyObject *t = Py_BuildValue("(is)", 0, "DBTxn must not be used "
Jesus Ceaef9764f2008-05-13 18:45:46 +00008013 "after txn_commit, txn_abort "
8014 "or txn_discard");
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008015 if (t) {
8016 PyErr_SetObject(DBError, t);
8017 Py_DECREF(t);
8018 }
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008019 return NULL;
8020 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008021 MYDB_BEGIN_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008022 id = self->txn->id(self->txn);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008023 MYDB_END_ALLOW_THREADS;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008024 return NUMBER_FromLong(id);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008025}
8026
Jesus Cea6557aac2010-03-22 14:22:26 +00008027
8028static PyObject*
8029DBTxn_set_timeout(DBTxnObject* self, PyObject* args, PyObject* kwargs)
8030{
8031 int err;
8032 u_int32_t flags=0;
8033 u_int32_t timeout = 0;
8034 static char* kwnames[] = { "timeout", "flags", NULL };
8035
8036 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ii:set_timeout", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00008037 &timeout, &flags)) {
8038 return NULL;
Jesus Cea6557aac2010-03-22 14:22:26 +00008039 }
8040
8041 MYDB_BEGIN_ALLOW_THREADS;
8042 err = self->txn->set_timeout(self->txn, (db_timeout_t)timeout, flags);
8043 MYDB_END_ALLOW_THREADS;
8044
8045 RETURN_IF_ERR();
8046 RETURN_NONE();
8047}
8048
8049
8050#if (DBVER >= 44)
8051static PyObject*
8052DBTxn_set_name(DBTxnObject* self, PyObject* args)
8053{
8054 int err;
8055 const char *name;
8056
8057 if (!PyArg_ParseTuple(args, "s:set_name", &name))
8058 return NULL;
8059
8060 MYDB_BEGIN_ALLOW_THREADS;
8061 err = self->txn->set_name(self->txn, name);
8062 MYDB_END_ALLOW_THREADS;
8063
8064 RETURN_IF_ERR();
8065 RETURN_NONE();
8066}
8067#endif
8068
8069
8070#if (DBVER >= 44)
8071static PyObject*
8072DBTxn_get_name(DBTxnObject* self)
8073{
8074 int err;
8075 const char *name;
8076
8077 MYDB_BEGIN_ALLOW_THREADS;
8078 err = self->txn->get_name(self->txn, &name);
8079 MYDB_END_ALLOW_THREADS;
8080
8081 RETURN_IF_ERR();
8082#if (PY_VERSION_HEX < 0x03000000)
8083 if (!name) {
8084 return PyString_FromString("");
8085 }
8086 return PyString_FromString(name);
8087#else
8088 if (!name) {
8089 return PyUnicode_FromString("");
8090 }
8091 return PyUnicode_FromString(name);
8092#endif
8093}
8094#endif
8095
8096
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008097#if (DBVER >= 43)
8098/* --------------------------------------------------------------------- */
8099/* DBSequence methods */
8100
8101
8102static PyObject*
Jesus Ceaef9764f2008-05-13 18:45:46 +00008103DBSequence_close_internal(DBSequenceObject* self, int flags, int do_not_close)
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008104{
Jesus Ceaef9764f2008-05-13 18:45:46 +00008105 int err=0;
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008106
Jesus Ceaef9764f2008-05-13 18:45:46 +00008107 if (self->sequence!=NULL) {
8108 EXTRACT_FROM_DOUBLE_LINKED_LIST(self);
8109 if (self->txn) {
8110 EXTRACT_FROM_DOUBLE_LINKED_LIST_TXN(self);
8111 self->txn=NULL;
8112 }
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008113
Jesus Cea5cd5f122008-09-23 18:54:08 +00008114 /*
8115 ** "do_not_close" is used to dispose all related objects in the
8116 ** tree, without actually releasing the "root" object.
8117 ** This is done, for example, because function calls like
8118 ** "DBSequence.remove()" implicitly close the underlying handle. So
8119 ** the handle doesn't need to be closed, but related objects
8120 ** must be cleaned up.
8121 */
Jesus Ceaef9764f2008-05-13 18:45:46 +00008122 if (!do_not_close) {
8123 MYDB_BEGIN_ALLOW_THREADS
8124 err = self->sequence->close(self->sequence, flags);
8125 MYDB_END_ALLOW_THREADS
8126 }
8127 self->sequence = NULL;
8128
8129 RETURN_IF_ERR();
8130 }
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008131
8132 RETURN_NONE();
8133}
8134
8135static PyObject*
Jesus Ceaef9764f2008-05-13 18:45:46 +00008136DBSequence_close(DBSequenceObject* self, PyObject* args)
8137{
8138 int flags=0;
8139 if (!PyArg_ParseTuple(args,"|i:close", &flags))
8140 return NULL;
8141
8142 return DBSequence_close_internal(self,flags,0);
8143}
8144
8145static PyObject*
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008146DBSequence_get(DBSequenceObject* self, PyObject* args, PyObject* kwargs)
8147{
8148 int err, flags = 0;
8149 int delta = 1;
8150 db_seq_t value;
8151 PyObject *txnobj = NULL;
8152 DB_TXN *txn = NULL;
8153 static char* kwnames[] = {"delta", "txn", "flags", NULL };
8154 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|iOi:get", kwnames, &delta, &txnobj, &flags))
8155 return NULL;
8156 CHECK_SEQUENCE_NOT_CLOSED(self)
8157
8158 if (!checkTxnObj(txnobj, &txn))
8159 return NULL;
8160
8161 MYDB_BEGIN_ALLOW_THREADS
8162 err = self->sequence->get(self->sequence, txn, delta, &value, flags);
8163 MYDB_END_ALLOW_THREADS
8164
8165 RETURN_IF_ERR();
8166 return PyLong_FromLongLong(value);
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008167}
8168
8169static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008170DBSequence_get_dbp(DBSequenceObject* self)
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008171{
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008172 CHECK_SEQUENCE_NOT_CLOSED(self)
8173 Py_INCREF(self->mydb);
8174 return (PyObject* )self->mydb;
8175}
8176
8177static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008178DBSequence_get_key(DBSequenceObject* self)
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008179{
8180 int err;
8181 DBT key;
Neal Norwitz088beae2007-10-12 03:01:54 +00008182 PyObject *retval = NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00008183
Gregory P. Smithe70be5c2007-10-06 07:48:10 +00008184 key.flags = DB_DBT_MALLOC;
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008185 CHECK_SEQUENCE_NOT_CLOSED(self)
8186 MYDB_BEGIN_ALLOW_THREADS
8187 err = self->sequence->get_key(self->sequence, &key);
8188 MYDB_END_ALLOW_THREADS
8189
Gregory P. Smithe70be5c2007-10-06 07:48:10 +00008190 if (!err)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008191 retval = Build_PyString(key.data, key.size);
Gregory P. Smithe70be5c2007-10-06 07:48:10 +00008192
8193 FREE_DBT(key);
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008194 RETURN_IF_ERR();
8195
Gregory P. Smithe70be5c2007-10-06 07:48:10 +00008196 return retval;
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008197}
8198
8199static PyObject*
Jesus Cea6557aac2010-03-22 14:22:26 +00008200DBSequence_initial_value(DBSequenceObject* self, PyObject* args)
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008201{
8202 int err;
Jesus Ceaef9764f2008-05-13 18:45:46 +00008203 PY_LONG_LONG value;
8204 db_seq_t value2;
Jesus Cea6557aac2010-03-22 14:22:26 +00008205 if (!PyArg_ParseTuple(args,"L:initial_value", &value))
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008206 return NULL;
8207 CHECK_SEQUENCE_NOT_CLOSED(self)
8208
Jesus Ceaef9764f2008-05-13 18:45:46 +00008209 value2=value; /* If truncation, compiler should show a warning */
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008210 MYDB_BEGIN_ALLOW_THREADS
Jesus Ceaef9764f2008-05-13 18:45:46 +00008211 err = self->sequence->initial_value(self->sequence, value2);
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008212 MYDB_END_ALLOW_THREADS
8213
8214 RETURN_IF_ERR();
8215
8216 RETURN_NONE();
8217}
8218
8219static PyObject*
8220DBSequence_open(DBSequenceObject* self, PyObject* args, PyObject* kwargs)
8221{
8222 int err, flags = 0;
8223 PyObject* keyobj;
8224 PyObject *txnobj = NULL;
8225 DB_TXN *txn = NULL;
8226 DBT key;
8227
8228 static char* kwnames[] = {"key", "txn", "flags", NULL };
Neal Norwitzdd2a6bf2006-06-06 07:23:01 +00008229 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|Oi:open", kwnames, &keyobj, &txnobj, &flags))
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008230 return NULL;
8231
8232 if (!checkTxnObj(txnobj, &txn))
8233 return NULL;
8234
8235 if (!make_key_dbt(self->mydb, keyobj, &key, NULL))
8236 return NULL;
8237
8238 MYDB_BEGIN_ALLOW_THREADS
8239 err = self->sequence->open(self->sequence, txn, &key, flags);
8240 MYDB_END_ALLOW_THREADS
8241
Jesus Ceaac25fab2008-09-03 17:50:32 +00008242 FREE_DBT(key);
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008243 RETURN_IF_ERR();
8244
Jesus Ceaef9764f2008-05-13 18:45:46 +00008245 if (txn) {
8246 INSERT_IN_DOUBLE_LINKED_LIST_TXN(((DBTxnObject *)txnobj)->children_sequences,self);
8247 self->txn=(DBTxnObject *)txnobj;
8248 }
8249
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008250 RETURN_NONE();
8251}
8252
8253static PyObject*
8254DBSequence_remove(DBSequenceObject* self, PyObject* args, PyObject* kwargs)
8255{
Jesus Ceaef9764f2008-05-13 18:45:46 +00008256 PyObject *dummy;
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008257 int err, flags = 0;
8258 PyObject *txnobj = NULL;
8259 DB_TXN *txn = NULL;
8260
8261 static char* kwnames[] = {"txn", "flags", NULL };
Neal Norwitzdd2a6bf2006-06-06 07:23:01 +00008262 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Oi:remove", kwnames, &txnobj, &flags))
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008263 return NULL;
8264
8265 if (!checkTxnObj(txnobj, &txn))
8266 return NULL;
8267
8268 CHECK_SEQUENCE_NOT_CLOSED(self)
8269
8270 MYDB_BEGIN_ALLOW_THREADS
8271 err = self->sequence->remove(self->sequence, txn, flags);
8272 MYDB_END_ALLOW_THREADS
8273
Jesus Ceaef9764f2008-05-13 18:45:46 +00008274 dummy=DBSequence_close_internal(self,flags,1);
8275 Py_XDECREF(dummy);
8276
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008277 RETURN_IF_ERR();
8278 RETURN_NONE();
8279}
8280
8281static PyObject*
8282DBSequence_set_cachesize(DBSequenceObject* self, PyObject* args)
8283{
8284 int err, size;
Neal Norwitzdd2a6bf2006-06-06 07:23:01 +00008285 if (!PyArg_ParseTuple(args,"i:set_cachesize", &size))
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008286 return NULL;
8287 CHECK_SEQUENCE_NOT_CLOSED(self)
8288
8289 MYDB_BEGIN_ALLOW_THREADS
8290 err = self->sequence->set_cachesize(self->sequence, size);
8291 MYDB_END_ALLOW_THREADS
8292
8293 RETURN_IF_ERR();
8294 RETURN_NONE();
8295}
8296
8297static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008298DBSequence_get_cachesize(DBSequenceObject* self)
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008299{
8300 int err, size;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008301
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008302 CHECK_SEQUENCE_NOT_CLOSED(self)
8303
8304 MYDB_BEGIN_ALLOW_THREADS
8305 err = self->sequence->get_cachesize(self->sequence, &size);
8306 MYDB_END_ALLOW_THREADS
8307
8308 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008309 return NUMBER_FromLong(size);
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008310}
8311
8312static PyObject*
8313DBSequence_set_flags(DBSequenceObject* self, PyObject* args)
8314{
8315 int err, flags = 0;
Neal Norwitzdd2a6bf2006-06-06 07:23:01 +00008316 if (!PyArg_ParseTuple(args,"i:set_flags", &flags))
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008317 return NULL;
8318 CHECK_SEQUENCE_NOT_CLOSED(self)
8319
8320 MYDB_BEGIN_ALLOW_THREADS
8321 err = self->sequence->set_flags(self->sequence, flags);
8322 MYDB_END_ALLOW_THREADS
8323
8324 RETURN_IF_ERR();
8325 RETURN_NONE();
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008326}
8327
8328static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008329DBSequence_get_flags(DBSequenceObject* self)
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008330{
8331 unsigned int flags;
8332 int err;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008333
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008334 CHECK_SEQUENCE_NOT_CLOSED(self)
8335
8336 MYDB_BEGIN_ALLOW_THREADS
8337 err = self->sequence->get_flags(self->sequence, &flags);
8338 MYDB_END_ALLOW_THREADS
8339
8340 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008341 return NUMBER_FromLong((int)flags);
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008342}
8343
8344static PyObject*
8345DBSequence_set_range(DBSequenceObject* self, PyObject* args)
8346{
8347 int err;
Jesus Ceaef9764f2008-05-13 18:45:46 +00008348 PY_LONG_LONG min, max;
8349 db_seq_t min2, max2;
Tim Petersbb21b2c2006-06-06 15:50:17 +00008350 if (!PyArg_ParseTuple(args,"(LL):set_range", &min, &max))
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008351 return NULL;
8352 CHECK_SEQUENCE_NOT_CLOSED(self)
8353
Jesus Ceaef9764f2008-05-13 18:45:46 +00008354 min2=min; /* If truncation, compiler should show a warning */
8355 max2=max;
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008356 MYDB_BEGIN_ALLOW_THREADS
Jesus Ceaef9764f2008-05-13 18:45:46 +00008357 err = self->sequence->set_range(self->sequence, min2, max2);
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008358 MYDB_END_ALLOW_THREADS
8359
8360 RETURN_IF_ERR();
8361 RETURN_NONE();
8362}
8363
8364static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008365DBSequence_get_range(DBSequenceObject* self)
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008366{
8367 int err;
Jesus Ceaef9764f2008-05-13 18:45:46 +00008368 PY_LONG_LONG min, max;
8369 db_seq_t min2, max2;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008370
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008371 CHECK_SEQUENCE_NOT_CLOSED(self)
8372
8373 MYDB_BEGIN_ALLOW_THREADS
Jesus Ceaef9764f2008-05-13 18:45:46 +00008374 err = self->sequence->get_range(self->sequence, &min2, &max2);
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008375 MYDB_END_ALLOW_THREADS
8376
8377 RETURN_IF_ERR();
Jesus Ceaef9764f2008-05-13 18:45:46 +00008378 min=min2; /* If truncation, compiler should show a warning */
8379 max=max2;
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008380 return Py_BuildValue("(LL)", min, max);
8381}
8382
Jesus Cea6557aac2010-03-22 14:22:26 +00008383
8384static PyObject*
8385DBSequence_stat_print(DBSequenceObject* self, PyObject* args, PyObject *kwargs)
8386{
8387 int err;
8388 int flags=0;
8389 static char* kwnames[] = { "flags", NULL };
8390
8391 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:stat_print",
8392 kwnames, &flags))
8393 {
8394 return NULL;
8395 }
8396
8397 CHECK_SEQUENCE_NOT_CLOSED(self);
8398
8399 MYDB_BEGIN_ALLOW_THREADS;
8400 err = self->sequence->stat_print(self->sequence, flags);
8401 MYDB_END_ALLOW_THREADS;
8402 RETURN_IF_ERR();
8403 RETURN_NONE();
8404}
8405
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008406static PyObject*
8407DBSequence_stat(DBSequenceObject* self, PyObject* args, PyObject* kwargs)
8408{
8409 int err, flags = 0;
8410 DB_SEQUENCE_STAT* sp = NULL;
8411 PyObject* dict_stat;
8412 static char* kwnames[] = {"flags", NULL };
8413 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:stat", kwnames, &flags))
8414 return NULL;
8415 CHECK_SEQUENCE_NOT_CLOSED(self);
8416
8417 MYDB_BEGIN_ALLOW_THREADS;
8418 err = self->sequence->stat(self->sequence, &sp, flags);
8419 MYDB_END_ALLOW_THREADS;
8420 RETURN_IF_ERR();
8421
8422 if ((dict_stat = PyDict_New()) == NULL) {
8423 free(sp);
8424 return NULL;
8425 }
8426
8427
8428#define MAKE_INT_ENTRY(name) _addIntToDict(dict_stat, #name, sp->st_##name)
8429#define MAKE_LONG_LONG_ENTRY(name) _addDb_seq_tToDict(dict_stat, #name, sp->st_##name)
8430
8431 MAKE_INT_ENTRY(wait);
8432 MAKE_INT_ENTRY(nowait);
8433 MAKE_LONG_LONG_ENTRY(current);
8434 MAKE_LONG_LONG_ENTRY(value);
8435 MAKE_LONG_LONG_ENTRY(last_value);
8436 MAKE_LONG_LONG_ENTRY(min);
8437 MAKE_LONG_LONG_ENTRY(max);
8438 MAKE_INT_ENTRY(cache_size);
8439 MAKE_INT_ENTRY(flags);
8440
8441#undef MAKE_INT_ENTRY
8442#undef MAKE_LONG_LONG_ENTRY
8443
8444 free(sp);
8445 return dict_stat;
8446}
8447#endif
8448
8449
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008450/* --------------------------------------------------------------------- */
8451/* Method definition tables and type objects */
8452
8453static PyMethodDef DB_methods[] = {
Jesus Cea4907d272008-08-31 14:00:51 +00008454 {"append", (PyCFunction)DB_append, METH_VARARGS|METH_KEYWORDS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008455 {"associate", (PyCFunction)DB_associate, METH_VARARGS|METH_KEYWORDS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008456 {"close", (PyCFunction)DB_close, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008457#if (DBVER >= 47)
8458 {"compact", (PyCFunction)DB_compact, METH_VARARGS|METH_KEYWORDS},
8459#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008460 {"consume", (PyCFunction)DB_consume, METH_VARARGS|METH_KEYWORDS},
8461 {"consume_wait", (PyCFunction)DB_consume_wait, METH_VARARGS|METH_KEYWORDS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008462 {"cursor", (PyCFunction)DB_cursor, METH_VARARGS|METH_KEYWORDS},
8463 {"delete", (PyCFunction)DB_delete, METH_VARARGS|METH_KEYWORDS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008464 {"fd", (PyCFunction)DB_fd, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008465#if (DBVER >= 46)
8466 {"exists", (PyCFunction)DB_exists,
8467 METH_VARARGS|METH_KEYWORDS},
8468#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008469 {"get", (PyCFunction)DB_get, METH_VARARGS|METH_KEYWORDS},
Gregory P. Smith19699a92004-06-28 04:06:49 +00008470 {"pget", (PyCFunction)DB_pget, METH_VARARGS|METH_KEYWORDS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008471 {"get_both", (PyCFunction)DB_get_both, METH_VARARGS|METH_KEYWORDS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008472 {"get_byteswapped", (PyCFunction)DB_get_byteswapped,METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008473 {"get_size", (PyCFunction)DB_get_size, METH_VARARGS|METH_KEYWORDS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008474 {"get_type", (PyCFunction)DB_get_type, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008475 {"join", (PyCFunction)DB_join, METH_VARARGS},
8476 {"key_range", (PyCFunction)DB_key_range, METH_VARARGS|METH_KEYWORDS},
Jesus Cea4907d272008-08-31 14:00:51 +00008477 {"has_key", (PyCFunction)DB_has_key, METH_VARARGS|METH_KEYWORDS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008478 {"items", (PyCFunction)DB_items, METH_VARARGS},
8479 {"keys", (PyCFunction)DB_keys, METH_VARARGS},
8480 {"open", (PyCFunction)DB_open, METH_VARARGS|METH_KEYWORDS},
8481 {"put", (PyCFunction)DB_put, METH_VARARGS|METH_KEYWORDS},
8482 {"remove", (PyCFunction)DB_remove, METH_VARARGS|METH_KEYWORDS},
8483 {"rename", (PyCFunction)DB_rename, METH_VARARGS},
8484 {"set_bt_minkey", (PyCFunction)DB_set_bt_minkey, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008485#if (DBVER >= 42)
8486 {"get_bt_minkey", (PyCFunction)DB_get_bt_minkey, METH_NOARGS},
8487#endif
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008488 {"set_bt_compare", (PyCFunction)DB_set_bt_compare, METH_O},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008489 {"set_cachesize", (PyCFunction)DB_set_cachesize, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008490#if (DBVER >= 42)
8491 {"get_cachesize", (PyCFunction)DB_get_cachesize, METH_NOARGS},
Barry Warsaw9a0d7792002-12-30 20:53:52 +00008492#endif
Jesus Cea6557aac2010-03-22 14:22:26 +00008493 {"set_encrypt", (PyCFunction)DB_set_encrypt, METH_VARARGS|METH_KEYWORDS},
8494#if (DBVER >= 42)
8495 {"get_encrypt_flags", (PyCFunction)DB_get_encrypt_flags, METH_NOARGS},
8496#endif
8497
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008498 {"set_flags", (PyCFunction)DB_set_flags, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008499#if (DBVER >= 42)
8500 {"get_flags", (PyCFunction)DB_get_flags, METH_NOARGS},
8501#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008502 {"set_h_ffactor", (PyCFunction)DB_set_h_ffactor, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008503#if (DBVER >= 42)
8504 {"get_h_ffactor", (PyCFunction)DB_get_h_ffactor, METH_NOARGS},
8505#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008506 {"set_h_nelem", (PyCFunction)DB_set_h_nelem, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008507#if (DBVER >= 42)
8508 {"get_h_nelem", (PyCFunction)DB_get_h_nelem, METH_NOARGS},
8509#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008510 {"set_lorder", (PyCFunction)DB_set_lorder, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008511#if (DBVER >= 42)
8512 {"get_lorder", (PyCFunction)DB_get_lorder, METH_NOARGS},
8513#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008514 {"set_pagesize", (PyCFunction)DB_set_pagesize, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008515#if (DBVER >= 42)
8516 {"get_pagesize", (PyCFunction)DB_get_pagesize, METH_NOARGS},
8517#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008518 {"set_re_delim", (PyCFunction)DB_set_re_delim, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008519#if (DBVER >= 42)
8520 {"get_re_delim", (PyCFunction)DB_get_re_delim, METH_NOARGS},
8521#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008522 {"set_re_len", (PyCFunction)DB_set_re_len, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008523#if (DBVER >= 42)
8524 {"get_re_len", (PyCFunction)DB_get_re_len, METH_NOARGS},
8525#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008526 {"set_re_pad", (PyCFunction)DB_set_re_pad, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008527#if (DBVER >= 42)
8528 {"get_re_pad", (PyCFunction)DB_get_re_pad, METH_NOARGS},
8529#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008530 {"set_re_source", (PyCFunction)DB_set_re_source, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008531#if (DBVER >= 42)
8532 {"get_re_source", (PyCFunction)DB_get_re_source, METH_NOARGS},
8533#endif
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008534 {"set_q_extentsize",(PyCFunction)DB_set_q_extentsize, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008535#if (DBVER >= 42)
8536 {"get_q_extentsize",(PyCFunction)DB_get_q_extentsize, METH_NOARGS},
8537#endif
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008538 {"set_private", (PyCFunction)DB_set_private, METH_O},
8539 {"get_private", (PyCFunction)DB_get_private, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008540#if (DBVER >= 46)
8541 {"set_priority", (PyCFunction)DB_set_priority, METH_VARARGS},
8542 {"get_priority", (PyCFunction)DB_get_priority, METH_NOARGS},
8543#endif
Gregory P. Smith8b7e9172004-12-13 09:51:23 +00008544 {"stat", (PyCFunction)DB_stat, METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008545#if (DBVER >= 43)
8546 {"stat_print", (PyCFunction)DB_stat_print,
8547 METH_VARARGS|METH_KEYWORDS},
8548#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008549 {"sync", (PyCFunction)DB_sync, METH_VARARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008550 {"truncate", (PyCFunction)DB_truncate, METH_VARARGS|METH_KEYWORDS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008551 {"type", (PyCFunction)DB_get_type, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008552 {"upgrade", (PyCFunction)DB_upgrade, METH_VARARGS},
8553 {"values", (PyCFunction)DB_values, METH_VARARGS},
8554 {"verify", (PyCFunction)DB_verify, METH_VARARGS|METH_KEYWORDS},
8555 {"set_get_returns_none",(PyCFunction)DB_set_get_returns_none, METH_VARARGS},
8556 {NULL, NULL} /* sentinel */
8557};
8558
8559
Jesus Cea6557aac2010-03-22 14:22:26 +00008560/* We need this to support __contains__() */
8561static PySequenceMethods DB_sequence = {
8562 0, /* sq_length, mapping wins here */
8563 0, /* sq_concat */
8564 0, /* sq_repeat */
8565 0, /* sq_item */
8566 0, /* sq_slice */
8567 0, /* sq_ass_item */
8568 0, /* sq_ass_slice */
8569 (objobjproc)DB_contains, /* sq_contains */
8570 0, /* sq_inplace_concat */
8571 0, /* sq_inplace_repeat */
8572};
8573
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008574static PyMappingMethods DB_mapping = {
Martin v. Löwis70ee3cc2006-06-12 04:26:31 +00008575 DB_length, /*mp_length*/
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008576 (binaryfunc)DB_subscript, /*mp_subscript*/
8577 (objobjargproc)DB_ass_sub, /*mp_ass_subscript*/
8578};
8579
8580
8581static PyMethodDef DBCursor_methods[] = {
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008582 {"close", (PyCFunction)DBC_close, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008583 {"count", (PyCFunction)DBC_count, METH_VARARGS},
8584 {"current", (PyCFunction)DBC_current, METH_VARARGS|METH_KEYWORDS},
8585 {"delete", (PyCFunction)DBC_delete, METH_VARARGS},
8586 {"dup", (PyCFunction)DBC_dup, METH_VARARGS},
8587 {"first", (PyCFunction)DBC_first, METH_VARARGS|METH_KEYWORDS},
8588 {"get", (PyCFunction)DBC_get, METH_VARARGS|METH_KEYWORDS},
Gregory P. Smith19699a92004-06-28 04:06:49 +00008589 {"pget", (PyCFunction)DBC_pget, METH_VARARGS|METH_KEYWORDS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008590 {"get_recno", (PyCFunction)DBC_get_recno, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008591 {"last", (PyCFunction)DBC_last, METH_VARARGS|METH_KEYWORDS},
8592 {"next", (PyCFunction)DBC_next, METH_VARARGS|METH_KEYWORDS},
8593 {"prev", (PyCFunction)DBC_prev, METH_VARARGS|METH_KEYWORDS},
8594 {"put", (PyCFunction)DBC_put, METH_VARARGS|METH_KEYWORDS},
8595 {"set", (PyCFunction)DBC_set, METH_VARARGS|METH_KEYWORDS},
8596 {"set_range", (PyCFunction)DBC_set_range, METH_VARARGS|METH_KEYWORDS},
8597 {"get_both", (PyCFunction)DBC_get_both, METH_VARARGS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008598 {"get_current_size",(PyCFunction)DBC_get_current_size, METH_NOARGS},
Gregory P. Smith455d46f2003-07-09 04:45:59 +00008599 {"set_both", (PyCFunction)DBC_set_both, METH_VARARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008600 {"set_recno", (PyCFunction)DBC_set_recno, METH_VARARGS|METH_KEYWORDS},
8601 {"consume", (PyCFunction)DBC_consume, METH_VARARGS|METH_KEYWORDS},
8602 {"next_dup", (PyCFunction)DBC_next_dup, METH_VARARGS|METH_KEYWORDS},
8603 {"next_nodup", (PyCFunction)DBC_next_nodup, METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008604#if (DBVER >= 46)
8605 {"prev_dup", (PyCFunction)DBC_prev_dup,
8606 METH_VARARGS|METH_KEYWORDS},
8607#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008608 {"prev_nodup", (PyCFunction)DBC_prev_nodup, METH_VARARGS|METH_KEYWORDS},
8609 {"join_item", (PyCFunction)DBC_join_item, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008610#if (DBVER >= 46)
8611 {"set_priority", (PyCFunction)DBC_set_priority,
8612 METH_VARARGS|METH_KEYWORDS},
8613 {"get_priority", (PyCFunction)DBC_get_priority, METH_NOARGS},
8614#endif
8615 {NULL, NULL} /* sentinel */
8616};
8617
8618
8619static PyMethodDef DBLogCursor_methods[] = {
8620 {"close", (PyCFunction)DBLogCursor_close, METH_NOARGS},
8621 {"current", (PyCFunction)DBLogCursor_current, METH_NOARGS},
8622 {"first", (PyCFunction)DBLogCursor_first, METH_NOARGS},
8623 {"last", (PyCFunction)DBLogCursor_last, METH_NOARGS},
8624 {"next", (PyCFunction)DBLogCursor_next, METH_NOARGS},
8625 {"prev", (PyCFunction)DBLogCursor_prev, METH_NOARGS},
8626 {"set", (PyCFunction)DBLogCursor_set, METH_VARARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008627 {NULL, NULL} /* sentinel */
8628};
8629
8630
8631static PyMethodDef DBEnv_methods[] = {
8632 {"close", (PyCFunction)DBEnv_close, METH_VARARGS},
8633 {"open", (PyCFunction)DBEnv_open, METH_VARARGS},
8634 {"remove", (PyCFunction)DBEnv_remove, METH_VARARGS},
Barry Warsaw9a0d7792002-12-30 20:53:52 +00008635 {"dbremove", (PyCFunction)DBEnv_dbremove, METH_VARARGS|METH_KEYWORDS},
8636 {"dbrename", (PyCFunction)DBEnv_dbrename, METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008637#if (DBVER >= 46)
8638 {"set_thread_count", (PyCFunction)DBEnv_set_thread_count, METH_VARARGS},
8639 {"get_thread_count", (PyCFunction)DBEnv_get_thread_count, METH_NOARGS},
8640#endif
Barry Warsaw9a0d7792002-12-30 20:53:52 +00008641 {"set_encrypt", (PyCFunction)DBEnv_set_encrypt, METH_VARARGS|METH_KEYWORDS},
Jesus Ceaef9764f2008-05-13 18:45:46 +00008642#if (DBVER >= 42)
Jesus Cea6557aac2010-03-22 14:22:26 +00008643 {"get_encrypt_flags", (PyCFunction)DBEnv_get_encrypt_flags, METH_NOARGS},
8644 {"get_timeout", (PyCFunction)DBEnv_get_timeout,
8645 METH_VARARGS|METH_KEYWORDS},
8646#endif
8647 {"set_timeout", (PyCFunction)DBEnv_set_timeout, METH_VARARGS|METH_KEYWORDS},
8648 {"set_shm_key", (PyCFunction)DBEnv_set_shm_key, METH_VARARGS},
8649#if (DBVER >= 42)
8650 {"get_shm_key", (PyCFunction)DBEnv_get_shm_key, METH_NOARGS},
8651#endif
8652#if (DBVER >= 46)
8653 {"set_cache_max", (PyCFunction)DBEnv_set_cache_max, METH_VARARGS},
8654 {"get_cache_max", (PyCFunction)DBEnv_get_cache_max, METH_NOARGS},
8655#endif
8656 {"set_cachesize", (PyCFunction)DBEnv_set_cachesize, METH_VARARGS},
8657#if (DBVER >= 42)
8658 {"get_cachesize", (PyCFunction)DBEnv_get_cachesize, METH_NOARGS},
8659#endif
8660 {"memp_trickle", (PyCFunction)DBEnv_memp_trickle, METH_VARARGS},
8661 {"memp_sync", (PyCFunction)DBEnv_memp_sync, METH_VARARGS},
8662 {"memp_stat", (PyCFunction)DBEnv_memp_stat,
8663 METH_VARARGS|METH_KEYWORDS},
8664#if (DBVER >= 43)
8665 {"memp_stat_print", (PyCFunction)DBEnv_memp_stat_print,
8666 METH_VARARGS|METH_KEYWORDS},
8667#endif
8668#if (DBVER >= 44)
8669 {"mutex_set_max", (PyCFunction)DBEnv_mutex_set_max, METH_VARARGS},
8670 {"mutex_get_max", (PyCFunction)DBEnv_mutex_get_max, METH_NOARGS},
8671 {"mutex_set_align", (PyCFunction)DBEnv_mutex_set_align, METH_VARARGS},
8672 {"mutex_get_align", (PyCFunction)DBEnv_mutex_get_align, METH_NOARGS},
8673 {"mutex_set_increment", (PyCFunction)DBEnv_mutex_set_increment,
8674 METH_VARARGS},
8675 {"mutex_get_increment", (PyCFunction)DBEnv_mutex_get_increment,
8676 METH_NOARGS},
8677 {"mutex_set_tas_spins", (PyCFunction)DBEnv_mutex_set_tas_spins,
8678 METH_VARARGS},
8679 {"mutex_get_tas_spins", (PyCFunction)DBEnv_mutex_get_tas_spins,
8680 METH_NOARGS},
8681 {"mutex_stat", (PyCFunction)DBEnv_mutex_stat, METH_VARARGS},
8682#if (DBVER >= 44)
8683 {"mutex_stat_print", (PyCFunction)DBEnv_mutex_stat_print,
8684 METH_VARARGS|METH_KEYWORDS},
8685#endif
8686#endif
8687 {"set_data_dir", (PyCFunction)DBEnv_set_data_dir, METH_VARARGS},
8688#if (DBVER >= 42)
8689 {"get_data_dirs", (PyCFunction)DBEnv_get_data_dirs, METH_NOARGS},
8690#endif
8691#if (DBVER >= 42)
8692 {"get_flags", (PyCFunction)DBEnv_get_flags, METH_NOARGS},
8693#endif
8694 {"set_flags", (PyCFunction)DBEnv_set_flags, METH_VARARGS},
8695#if (DBVER >= 47)
8696 {"log_set_config", (PyCFunction)DBEnv_log_set_config, METH_VARARGS},
8697 {"log_get_config", (PyCFunction)DBEnv_log_get_config, METH_VARARGS},
8698#endif
8699 {"set_lg_bsize", (PyCFunction)DBEnv_set_lg_bsize, METH_VARARGS},
8700#if (DBVER >= 42)
8701 {"get_lg_bsize", (PyCFunction)DBEnv_get_lg_bsize, METH_NOARGS},
8702#endif
8703 {"set_lg_dir", (PyCFunction)DBEnv_set_lg_dir, METH_VARARGS},
8704#if (DBVER >= 42)
8705 {"get_lg_dir", (PyCFunction)DBEnv_get_lg_dir, METH_NOARGS},
8706#endif
8707 {"set_lg_max", (PyCFunction)DBEnv_set_lg_max, METH_VARARGS},
8708#if (DBVER >= 42)
8709 {"get_lg_max", (PyCFunction)DBEnv_get_lg_max, METH_NOARGS},
Jesus Ceaef9764f2008-05-13 18:45:46 +00008710#endif
Gregory P. Smithe9477062005-06-04 06:46:59 +00008711 {"set_lg_regionmax",(PyCFunction)DBEnv_set_lg_regionmax, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008712#if (DBVER >= 42)
8713 {"get_lg_regionmax",(PyCFunction)DBEnv_get_lg_regionmax, METH_NOARGS},
8714#endif
8715#if (DBVER >= 44)
8716 {"set_lg_filemode", (PyCFunction)DBEnv_set_lg_filemode, METH_VARARGS},
8717 {"get_lg_filemode", (PyCFunction)DBEnv_get_lg_filemode, METH_NOARGS},
8718#endif
8719#if (DBVER >= 47)
8720 {"set_lk_partitions", (PyCFunction)DBEnv_set_lk_partitions, METH_VARARGS},
8721 {"get_lk_partitions", (PyCFunction)DBEnv_get_lk_partitions, METH_NOARGS},
8722#endif
8723 {"set_lk_detect", (PyCFunction)DBEnv_set_lk_detect, METH_VARARGS},
8724#if (DBVER >= 42)
8725 {"get_lk_detect", (PyCFunction)DBEnv_get_lk_detect, METH_NOARGS},
8726#endif
Gregory P. Smith8b96a352007-01-05 01:59:42 +00008727#if (DBVER < 45)
Jesus Cea6557aac2010-03-22 14:22:26 +00008728 {"set_lk_max", (PyCFunction)DBEnv_set_lk_max, METH_VARARGS},
Gregory P. Smith8b96a352007-01-05 01:59:42 +00008729#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008730 {"set_lk_max_locks", (PyCFunction)DBEnv_set_lk_max_locks, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008731#if (DBVER >= 42)
8732 {"get_lk_max_locks", (PyCFunction)DBEnv_get_lk_max_locks, METH_NOARGS},
8733#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008734 {"set_lk_max_lockers", (PyCFunction)DBEnv_set_lk_max_lockers, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008735#if (DBVER >= 42)
8736 {"get_lk_max_lockers", (PyCFunction)DBEnv_get_lk_max_lockers, METH_NOARGS},
8737#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008738 {"set_lk_max_objects", (PyCFunction)DBEnv_set_lk_max_objects, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008739#if (DBVER >= 42)
8740 {"get_lk_max_objects", (PyCFunction)DBEnv_get_lk_max_objects, METH_NOARGS},
8741#endif
8742#if (DBVER >= 43)
8743 {"stat_print", (PyCFunction)DBEnv_stat_print,
8744 METH_VARARGS|METH_KEYWORDS},
8745#endif
8746 {"set_mp_mmapsize", (PyCFunction)DBEnv_set_mp_mmapsize, METH_VARARGS},
8747#if (DBVER >= 42)
8748 {"get_mp_mmapsize", (PyCFunction)DBEnv_get_mp_mmapsize, METH_NOARGS},
8749#endif
8750 {"set_tmp_dir", (PyCFunction)DBEnv_set_tmp_dir, METH_VARARGS},
8751#if (DBVER >= 42)
8752 {"get_tmp_dir", (PyCFunction)DBEnv_get_tmp_dir, METH_NOARGS},
8753#endif
8754 {"txn_begin", (PyCFunction)DBEnv_txn_begin, METH_VARARGS|METH_KEYWORDS},
8755 {"txn_checkpoint", (PyCFunction)DBEnv_txn_checkpoint, METH_VARARGS},
8756 {"txn_stat", (PyCFunction)DBEnv_txn_stat, METH_VARARGS},
8757#if (DBVER >= 43)
8758 {"txn_stat_print", (PyCFunction)DBEnv_txn_stat_print,
8759 METH_VARARGS|METH_KEYWORDS},
8760#endif
8761#if (DBVER >= 42)
8762 {"get_tx_max", (PyCFunction)DBEnv_get_tx_max, METH_NOARGS},
8763 {"get_tx_timestamp", (PyCFunction)DBEnv_get_tx_timestamp, METH_NOARGS},
8764#endif
8765 {"set_tx_max", (PyCFunction)DBEnv_set_tx_max, METH_VARARGS},
Gregory P. Smith8a474042006-01-27 07:05:40 +00008766 {"set_tx_timestamp", (PyCFunction)DBEnv_set_tx_timestamp, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008767 {"lock_detect", (PyCFunction)DBEnv_lock_detect, METH_VARARGS},
8768 {"lock_get", (PyCFunction)DBEnv_lock_get, METH_VARARGS},
8769 {"lock_id", (PyCFunction)DBEnv_lock_id, METH_NOARGS},
8770 {"lock_id_free", (PyCFunction)DBEnv_lock_id_free, METH_VARARGS},
8771 {"lock_put", (PyCFunction)DBEnv_lock_put, METH_VARARGS},
8772 {"lock_stat", (PyCFunction)DBEnv_lock_stat, METH_VARARGS},
8773#if (DBVER >= 43)
8774 {"lock_stat_print", (PyCFunction)DBEnv_lock_stat_print,
8775 METH_VARARGS|METH_KEYWORDS},
8776#endif
8777 {"log_cursor", (PyCFunction)DBEnv_log_cursor, METH_NOARGS},
8778 {"log_file", (PyCFunction)DBEnv_log_file, METH_VARARGS},
Gregory P. Smithdb8a8072006-06-05 01:56:15 +00008779#if (DBVER >= 44)
Jesus Cea6557aac2010-03-22 14:22:26 +00008780 {"log_printf", (PyCFunction)DBEnv_log_printf,
8781 METH_VARARGS|METH_KEYWORDS},
8782#endif
8783 {"log_archive", (PyCFunction)DBEnv_log_archive, METH_VARARGS},
8784 {"log_flush", (PyCFunction)DBEnv_log_flush, METH_NOARGS},
8785 {"log_stat", (PyCFunction)DBEnv_log_stat, METH_VARARGS},
8786#if (DBVER >= 43)
8787 {"log_stat_print", (PyCFunction)DBEnv_log_stat_print,
8788 METH_VARARGS|METH_KEYWORDS},
8789#endif
8790#if (DBVER >= 44)
8791 {"fileid_reset", (PyCFunction)DBEnv_fileid_reset, METH_VARARGS|METH_KEYWORDS},
8792 {"lsn_reset", (PyCFunction)DBEnv_lsn_reset, METH_VARARGS|METH_KEYWORDS},
Gregory P. Smithdb8a8072006-06-05 01:56:15 +00008793#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008794 {"set_get_returns_none",(PyCFunction)DBEnv_set_get_returns_none, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008795 {"txn_recover", (PyCFunction)DBEnv_txn_recover, METH_NOARGS},
Matthias Klose54cc5392010-03-15 12:46:18 +00008796#if (DBVER < 48)
Jesus Ceaca3939c2008-05-22 15:27:38 +00008797 {"set_rpc_server", (PyCFunction)DBEnv_set_rpc_server,
Stefan Krah77112732011-09-15 22:56:00 +02008798 METH_VARARGS|METH_KEYWORDS},
Matthias Klose54cc5392010-03-15 12:46:18 +00008799#endif
Jesus Cea6557aac2010-03-22 14:22:26 +00008800#if (DBVER >= 43)
8801 {"set_mp_max_openfd", (PyCFunction)DBEnv_set_mp_max_openfd, METH_VARARGS},
8802 {"get_mp_max_openfd", (PyCFunction)DBEnv_get_mp_max_openfd, METH_NOARGS},
8803 {"set_mp_max_write", (PyCFunction)DBEnv_set_mp_max_write, METH_VARARGS},
8804 {"get_mp_max_write", (PyCFunction)DBEnv_get_mp_max_write, METH_NOARGS},
8805#endif
8806 {"set_verbose", (PyCFunction)DBEnv_set_verbose, METH_VARARGS},
Jesus Ceaef9764f2008-05-13 18:45:46 +00008807#if (DBVER >= 42)
8808 {"get_verbose", (PyCFunction)DBEnv_get_verbose, METH_VARARGS},
8809#endif
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008810 {"set_private", (PyCFunction)DBEnv_set_private, METH_O},
8811 {"get_private", (PyCFunction)DBEnv_get_private, METH_NOARGS},
8812 {"rep_start", (PyCFunction)DBEnv_rep_start,
8813 METH_VARARGS|METH_KEYWORDS},
8814 {"rep_set_transport", (PyCFunction)DBEnv_rep_set_transport, METH_VARARGS},
8815 {"rep_process_message", (PyCFunction)DBEnv_rep_process_message,
8816 METH_VARARGS},
8817#if (DBVER >= 46)
8818 {"rep_elect", (PyCFunction)DBEnv_rep_elect, METH_VARARGS},
8819#endif
8820#if (DBVER >= 44)
8821 {"rep_set_config", (PyCFunction)DBEnv_rep_set_config, METH_VARARGS},
8822 {"rep_get_config", (PyCFunction)DBEnv_rep_get_config, METH_VARARGS},
8823 {"rep_sync", (PyCFunction)DBEnv_rep_sync, METH_NOARGS},
Jesus Ceaef9764f2008-05-13 18:45:46 +00008824#endif
8825#if (DBVER >= 45)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008826 {"rep_set_limit", (PyCFunction)DBEnv_rep_set_limit, METH_VARARGS},
8827 {"rep_get_limit", (PyCFunction)DBEnv_rep_get_limit, METH_NOARGS},
8828#endif
8829#if (DBVER >= 47)
8830 {"rep_set_request", (PyCFunction)DBEnv_rep_set_request, METH_VARARGS},
8831 {"rep_get_request", (PyCFunction)DBEnv_rep_get_request, METH_NOARGS},
8832#endif
8833#if (DBVER >= 45)
8834 {"set_event_notify", (PyCFunction)DBEnv_set_event_notify, METH_O},
Jesus Ceaef9764f2008-05-13 18:45:46 +00008835#endif
8836#if (DBVER >= 45)
8837 {"rep_set_nsites", (PyCFunction)DBEnv_rep_set_nsites, METH_VARARGS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008838 {"rep_get_nsites", (PyCFunction)DBEnv_rep_get_nsites, METH_NOARGS},
Jesus Ceaef9764f2008-05-13 18:45:46 +00008839 {"rep_set_priority", (PyCFunction)DBEnv_rep_set_priority, METH_VARARGS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008840 {"rep_get_priority", (PyCFunction)DBEnv_rep_get_priority, METH_NOARGS},
Jesus Ceaef9764f2008-05-13 18:45:46 +00008841 {"rep_set_timeout", (PyCFunction)DBEnv_rep_set_timeout, METH_VARARGS},
8842 {"rep_get_timeout", (PyCFunction)DBEnv_rep_get_timeout, METH_VARARGS},
8843#endif
Jesus Cea6557aac2010-03-22 14:22:26 +00008844#if (DBVER >= 47)
8845 {"rep_set_clockskew", (PyCFunction)DBEnv_rep_set_clockskew, METH_VARARGS},
8846 {"rep_get_clockskew", (PyCFunction)DBEnv_rep_get_clockskew, METH_VARARGS},
8847#endif
8848 {"rep_stat", (PyCFunction)DBEnv_rep_stat,
8849 METH_VARARGS|METH_KEYWORDS},
8850#if (DBVER >= 43)
8851 {"rep_stat_print", (PyCFunction)DBEnv_rep_stat_print,
8852 METH_VARARGS|METH_KEYWORDS},
8853#endif
8854
Jesus Ceaef9764f2008-05-13 18:45:46 +00008855#if (DBVER >= 45)
8856 {"repmgr_start", (PyCFunction)DBEnv_repmgr_start,
8857 METH_VARARGS|METH_KEYWORDS},
8858 {"repmgr_set_local_site", (PyCFunction)DBEnv_repmgr_set_local_site,
8859 METH_VARARGS|METH_KEYWORDS},
8860 {"repmgr_add_remote_site", (PyCFunction)DBEnv_repmgr_add_remote_site,
8861 METH_VARARGS|METH_KEYWORDS},
8862 {"repmgr_set_ack_policy", (PyCFunction)DBEnv_repmgr_set_ack_policy,
8863 METH_VARARGS},
8864 {"repmgr_get_ack_policy", (PyCFunction)DBEnv_repmgr_get_ack_policy,
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008865 METH_NOARGS},
Jesus Ceaef9764f2008-05-13 18:45:46 +00008866 {"repmgr_site_list", (PyCFunction)DBEnv_repmgr_site_list,
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008867 METH_NOARGS},
Jesus Ceaef9764f2008-05-13 18:45:46 +00008868#endif
8869#if (DBVER >= 46)
8870 {"repmgr_stat", (PyCFunction)DBEnv_repmgr_stat,
8871 METH_VARARGS|METH_KEYWORDS},
8872 {"repmgr_stat_print", (PyCFunction)DBEnv_repmgr_stat_print,
8873 METH_VARARGS|METH_KEYWORDS},
8874#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008875 {NULL, NULL} /* sentinel */
8876};
8877
8878
8879static PyMethodDef DBTxn_methods[] = {
8880 {"commit", (PyCFunction)DBTxn_commit, METH_VARARGS},
8881 {"prepare", (PyCFunction)DBTxn_prepare, METH_VARARGS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008882 {"discard", (PyCFunction)DBTxn_discard, METH_NOARGS},
8883 {"abort", (PyCFunction)DBTxn_abort, METH_NOARGS},
8884 {"id", (PyCFunction)DBTxn_id, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008885 {"set_timeout", (PyCFunction)DBTxn_set_timeout,
8886 METH_VARARGS|METH_KEYWORDS},
8887#if (DBVER >= 44)
8888 {"set_name", (PyCFunction)DBTxn_set_name, METH_VARARGS},
8889 {"get_name", (PyCFunction)DBTxn_get_name, METH_NOARGS},
8890#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008891 {NULL, NULL} /* sentinel */
8892};
8893
8894
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008895#if (DBVER >= 43)
8896static PyMethodDef DBSequence_methods[] = {
8897 {"close", (PyCFunction)DBSequence_close, METH_VARARGS},
8898 {"get", (PyCFunction)DBSequence_get, METH_VARARGS|METH_KEYWORDS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008899 {"get_dbp", (PyCFunction)DBSequence_get_dbp, METH_NOARGS},
8900 {"get_key", (PyCFunction)DBSequence_get_key, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008901 {"initial_value", (PyCFunction)DBSequence_initial_value, METH_VARARGS},
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008902 {"open", (PyCFunction)DBSequence_open, METH_VARARGS|METH_KEYWORDS},
8903 {"remove", (PyCFunction)DBSequence_remove, METH_VARARGS|METH_KEYWORDS},
8904 {"set_cachesize", (PyCFunction)DBSequence_set_cachesize, METH_VARARGS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008905 {"get_cachesize", (PyCFunction)DBSequence_get_cachesize, METH_NOARGS},
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008906 {"set_flags", (PyCFunction)DBSequence_set_flags, METH_VARARGS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008907 {"get_flags", (PyCFunction)DBSequence_get_flags, METH_NOARGS},
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008908 {"set_range", (PyCFunction)DBSequence_set_range, METH_VARARGS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008909 {"get_range", (PyCFunction)DBSequence_get_range, METH_NOARGS},
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008910 {"stat", (PyCFunction)DBSequence_stat, METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008911 {"stat_print", (PyCFunction)DBSequence_stat_print,
8912 METH_VARARGS|METH_KEYWORDS},
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008913 {NULL, NULL} /* sentinel */
8914};
8915#endif
8916
8917
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008918static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008919DBEnv_db_home_get(DBEnvObject* self)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008920{
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008921 const char *home = NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008922
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008923 CHECK_ENV_NOT_CLOSED(self);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008924
Jesus Ceaef9764f2008-05-13 18:45:46 +00008925#if (DBVER >= 42)
Jesus Cea6557aac2010-03-22 14:22:26 +00008926 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008927 self->db_env->get_home(self->db_env, &home);
Jesus Cea6557aac2010-03-22 14:22:26 +00008928 MYDB_END_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00008929#else
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008930 home=self->db_env->db_home;
Jesus Ceaef9764f2008-05-13 18:45:46 +00008931#endif
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008932
8933 if (home == NULL) {
8934 RETURN_NONE();
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008935 }
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008936 return PyBytes_FromString(home);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008937}
8938
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008939static PyGetSetDef DBEnv_getsets[] = {
8940 {"db_home", (getter)DBEnv_db_home_get, NULL,},
8941 {NULL}
8942};
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008943
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008944
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008945statichere PyTypeObject DB_Type = {
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008946#if (PY_VERSION_HEX < 0x03000000)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008947 PyObject_HEAD_INIT(NULL)
8948 0, /*ob_size*/
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008949#else
8950 PyVarObject_HEAD_INIT(NULL, 0)
8951#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008952 "DB", /*tp_name*/
8953 sizeof(DBObject), /*tp_basicsize*/
8954 0, /*tp_itemsize*/
8955 /* methods */
8956 (destructor)DB_dealloc, /*tp_dealloc*/
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008957 0, /*tp_print*/
8958 0, /*tp_getattr*/
8959 0, /*tp_setattr*/
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008960 0, /*tp_compare*/
8961 0, /*tp_repr*/
8962 0, /*tp_as_number*/
Jesus Cea6557aac2010-03-22 14:22:26 +00008963 &DB_sequence,/*tp_as_sequence*/
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008964 &DB_mapping,/*tp_as_mapping*/
8965 0, /*tp_hash*/
Antoine Pitrouc83ea132010-05-09 14:46:46 +00008966 0, /* tp_call */
8967 0, /* tp_str */
8968 0, /* tp_getattro */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008969 0, /* tp_setattro */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00008970 0, /* tp_as_buffer */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008971#if (PY_VERSION_HEX < 0x03000000)
Gregory P. Smith31c50652004-06-28 01:20:40 +00008972 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008973#else
8974 Py_TPFLAGS_DEFAULT, /* tp_flags */
8975#endif
8976 0, /* tp_doc */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00008977 0, /* tp_traverse */
8978 0, /* tp_clear */
8979 0, /* tp_richcompare */
Gregory P. Smith31c50652004-06-28 01:20:40 +00008980 offsetof(DBObject, in_weakreflist), /* tp_weaklistoffset */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008981 0, /*tp_iter*/
8982 0, /*tp_iternext*/
8983 DB_methods, /*tp_methods*/
8984 0, /*tp_members*/
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008985};
8986
8987
8988statichere PyTypeObject DBCursor_Type = {
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008989#if (PY_VERSION_HEX < 0x03000000)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008990 PyObject_HEAD_INIT(NULL)
8991 0, /*ob_size*/
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008992#else
8993 PyVarObject_HEAD_INIT(NULL, 0)
8994#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008995 "DBCursor", /*tp_name*/
8996 sizeof(DBCursorObject), /*tp_basicsize*/
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008997 0, /*tp_itemsize*/
8998 /* methods */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008999 (destructor)DBCursor_dealloc,/*tp_dealloc*/
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009000 0, /*tp_print*/
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009001 0, /*tp_getattr*/
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009002 0, /*tp_setattr*/
9003 0, /*tp_compare*/
9004 0, /*tp_repr*/
9005 0, /*tp_as_number*/
9006 0, /*tp_as_sequence*/
9007 0, /*tp_as_mapping*/
9008 0, /*tp_hash*/
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009009 0, /*tp_call*/
9010 0, /*tp_str*/
9011 0, /*tp_getattro*/
9012 0, /*tp_setattro*/
9013 0, /*tp_as_buffer*/
9014#if (PY_VERSION_HEX < 0x03000000)
Gregory P. Smith31c50652004-06-28 01:20:40 +00009015 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009016#else
9017 Py_TPFLAGS_DEFAULT, /* tp_flags */
9018#endif
9019 0, /* tp_doc */
9020 0, /* tp_traverse */
9021 0, /* tp_clear */
9022 0, /* tp_richcompare */
9023 offsetof(DBCursorObject, in_weakreflist), /* tp_weaklistoffset */
9024 0, /*tp_iter*/
9025 0, /*tp_iternext*/
9026 DBCursor_methods, /*tp_methods*/
9027 0, /*tp_members*/
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009028};
9029
9030
Jesus Cea6557aac2010-03-22 14:22:26 +00009031statichere PyTypeObject DBLogCursor_Type = {
9032#if (PY_VERSION_HEX < 0x03000000)
9033 PyObject_HEAD_INIT(NULL)
9034 0, /*ob_size*/
9035#else
9036 PyVarObject_HEAD_INIT(NULL, 0)
9037#endif
9038 "DBLogCursor", /*tp_name*/
9039 sizeof(DBLogCursorObject), /*tp_basicsize*/
9040 0, /*tp_itemsize*/
9041 /* methods */
9042 (destructor)DBLogCursor_dealloc,/*tp_dealloc*/
9043 0, /*tp_print*/
9044 0, /*tp_getattr*/
9045 0, /*tp_setattr*/
9046 0, /*tp_compare*/
9047 0, /*tp_repr*/
9048 0, /*tp_as_number*/
9049 0, /*tp_as_sequence*/
9050 0, /*tp_as_mapping*/
9051 0, /*tp_hash*/
9052 0, /*tp_call*/
9053 0, /*tp_str*/
9054 0, /*tp_getattro*/
9055 0, /*tp_setattro*/
9056 0, /*tp_as_buffer*/
9057#if (PY_VERSION_HEX < 0x03000000)
9058 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
9059#else
9060 Py_TPFLAGS_DEFAULT, /* tp_flags */
9061#endif
9062 0, /* tp_doc */
9063 0, /* tp_traverse */
9064 0, /* tp_clear */
9065 0, /* tp_richcompare */
9066 offsetof(DBLogCursorObject, in_weakreflist), /* tp_weaklistoffset */
9067 0, /*tp_iter*/
9068 0, /*tp_iternext*/
9069 DBLogCursor_methods, /*tp_methods*/
9070 0, /*tp_members*/
9071};
9072
9073
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009074statichere PyTypeObject DBEnv_Type = {
9075#if (PY_VERSION_HEX < 0x03000000)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009076 PyObject_HEAD_INIT(NULL)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009077 0, /*ob_size*/
9078#else
9079 PyVarObject_HEAD_INIT(NULL, 0)
9080#endif
9081 "DBEnv", /*tp_name*/
9082 sizeof(DBEnvObject), /*tp_basicsize*/
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009083 0, /*tp_itemsize*/
9084 /* methods */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009085 (destructor)DBEnv_dealloc, /*tp_dealloc*/
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009086 0, /*tp_print*/
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009087 0, /*tp_getattr*/
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009088 0, /*tp_setattr*/
9089 0, /*tp_compare*/
9090 0, /*tp_repr*/
9091 0, /*tp_as_number*/
9092 0, /*tp_as_sequence*/
9093 0, /*tp_as_mapping*/
9094 0, /*tp_hash*/
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009095 0, /* tp_call */
9096 0, /* tp_str */
9097 0, /* tp_getattro */
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009098 0, /* tp_setattro */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009099 0, /* tp_as_buffer */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009100#if (PY_VERSION_HEX < 0x03000000)
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009101 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009102#else
9103 Py_TPFLAGS_DEFAULT, /* tp_flags */
9104#endif
9105 0, /* tp_doc */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009106 0, /* tp_traverse */
9107 0, /* tp_clear */
9108 0, /* tp_richcompare */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009109 offsetof(DBEnvObject, in_weakreflist), /* tp_weaklistoffset */
9110 0, /* tp_iter */
9111 0, /* tp_iternext */
9112 DBEnv_methods, /* tp_methods */
9113 0, /* tp_members */
9114 DBEnv_getsets, /* tp_getsets */
9115};
9116
9117statichere PyTypeObject DBTxn_Type = {
9118#if (PY_VERSION_HEX < 0x03000000)
9119 PyObject_HEAD_INIT(NULL)
9120 0, /*ob_size*/
9121#else
9122 PyVarObject_HEAD_INIT(NULL, 0)
9123#endif
9124 "DBTxn", /*tp_name*/
9125 sizeof(DBTxnObject), /*tp_basicsize*/
9126 0, /*tp_itemsize*/
9127 /* methods */
9128 (destructor)DBTxn_dealloc, /*tp_dealloc*/
9129 0, /*tp_print*/
9130 0, /*tp_getattr*/
9131 0, /*tp_setattr*/
9132 0, /*tp_compare*/
9133 0, /*tp_repr*/
9134 0, /*tp_as_number*/
9135 0, /*tp_as_sequence*/
9136 0, /*tp_as_mapping*/
9137 0, /*tp_hash*/
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009138 0, /* tp_call */
9139 0, /* tp_str */
9140 0, /* tp_getattro */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009141 0, /* tp_setattro */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009142 0, /* tp_as_buffer */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009143#if (PY_VERSION_HEX < 0x03000000)
9144 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
9145#else
9146 Py_TPFLAGS_DEFAULT, /* tp_flags */
9147#endif
9148 0, /* tp_doc */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009149 0, /* tp_traverse */
9150 0, /* tp_clear */
9151 0, /* tp_richcompare */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009152 offsetof(DBTxnObject, in_weakreflist), /* tp_weaklistoffset */
9153 0, /*tp_iter*/
9154 0, /*tp_iternext*/
9155 DBTxn_methods, /*tp_methods*/
9156 0, /*tp_members*/
9157};
9158
9159
9160statichere PyTypeObject DBLock_Type = {
9161#if (PY_VERSION_HEX < 0x03000000)
9162 PyObject_HEAD_INIT(NULL)
9163 0, /*ob_size*/
9164#else
9165 PyVarObject_HEAD_INIT(NULL, 0)
9166#endif
9167 "DBLock", /*tp_name*/
9168 sizeof(DBLockObject), /*tp_basicsize*/
9169 0, /*tp_itemsize*/
9170 /* methods */
9171 (destructor)DBLock_dealloc, /*tp_dealloc*/
9172 0, /*tp_print*/
9173 0, /*tp_getattr*/
9174 0, /*tp_setattr*/
9175 0, /*tp_compare*/
9176 0, /*tp_repr*/
9177 0, /*tp_as_number*/
9178 0, /*tp_as_sequence*/
9179 0, /*tp_as_mapping*/
9180 0, /*tp_hash*/
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009181 0, /* tp_call */
9182 0, /* tp_str */
9183 0, /* tp_getattro */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009184 0, /* tp_setattro */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009185 0, /* tp_as_buffer */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009186#if (PY_VERSION_HEX < 0x03000000)
9187 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
9188#else
9189 Py_TPFLAGS_DEFAULT, /* tp_flags */
9190#endif
9191 0, /* tp_doc */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009192 0, /* tp_traverse */
9193 0, /* tp_clear */
9194 0, /* tp_richcompare */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009195 offsetof(DBLockObject, in_weakreflist), /* tp_weaklistoffset */
9196};
9197
9198#if (DBVER >= 43)
9199statichere PyTypeObject DBSequence_Type = {
9200#if (PY_VERSION_HEX < 0x03000000)
9201 PyObject_HEAD_INIT(NULL)
9202 0, /*ob_size*/
9203#else
9204 PyVarObject_HEAD_INIT(NULL, 0)
9205#endif
9206 "DBSequence", /*tp_name*/
9207 sizeof(DBSequenceObject), /*tp_basicsize*/
9208 0, /*tp_itemsize*/
9209 /* methods */
9210 (destructor)DBSequence_dealloc, /*tp_dealloc*/
9211 0, /*tp_print*/
9212 0, /*tp_getattr*/
9213 0, /*tp_setattr*/
9214 0, /*tp_compare*/
9215 0, /*tp_repr*/
9216 0, /*tp_as_number*/
9217 0, /*tp_as_sequence*/
9218 0, /*tp_as_mapping*/
9219 0, /*tp_hash*/
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009220 0, /* tp_call */
9221 0, /* tp_str */
9222 0, /* tp_getattro */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009223 0, /* tp_setattro */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009224 0, /* tp_as_buffer */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009225#if (PY_VERSION_HEX < 0x03000000)
9226 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
9227#else
9228 Py_TPFLAGS_DEFAULT, /* tp_flags */
9229#endif
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009230 0, /* tp_doc */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009231 0, /* tp_traverse */
9232 0, /* tp_clear */
9233 0, /* tp_richcompare */
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009234 offsetof(DBSequenceObject, in_weakreflist), /* tp_weaklistoffset */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009235 0, /*tp_iter*/
9236 0, /*tp_iternext*/
9237 DBSequence_methods, /*tp_methods*/
9238 0, /*tp_members*/
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009239};
9240#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009241
9242/* --------------------------------------------------------------------- */
9243/* Module-level functions */
9244
9245static PyObject*
9246DB_construct(PyObject* self, PyObject* args, PyObject* kwargs)
9247{
9248 PyObject* dbenvobj = NULL;
9249 int flags = 0;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00009250 static char* kwnames[] = { "dbEnv", "flags", NULL};
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009251
Barry Warsaw9a0d7792002-12-30 20:53:52 +00009252 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Oi:DB", kwnames,
9253 &dbenvobj, &flags))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009254 return NULL;
9255 if (dbenvobj == Py_None)
9256 dbenvobj = NULL;
9257 else if (dbenvobj && !DBEnvObject_Check(dbenvobj)) {
9258 makeTypeError("DBEnv", dbenvobj);
9259 return NULL;
9260 }
9261
9262 return (PyObject* )newDBObject((DBEnvObject*)dbenvobj, flags);
9263}
9264
9265
9266static PyObject*
9267DBEnv_construct(PyObject* self, PyObject* args)
9268{
9269 int flags = 0;
9270 if (!PyArg_ParseTuple(args, "|i:DbEnv", &flags)) return NULL;
9271 return (PyObject* )newDBEnvObject(flags);
9272}
9273
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009274#if (DBVER >= 43)
9275static PyObject*
9276DBSequence_construct(PyObject* self, PyObject* args, PyObject* kwargs)
9277{
Neal Norwitzb4fcf8d2006-06-11 05:44:18 +00009278 PyObject* dbobj;
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009279 int flags = 0;
9280 static char* kwnames[] = { "db", "flags", NULL};
9281
9282 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|i:DBSequence", kwnames, &dbobj, &flags))
9283 return NULL;
Neal Norwitzb4fcf8d2006-06-11 05:44:18 +00009284 if (!DBObject_Check(dbobj)) {
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009285 makeTypeError("DB", dbobj);
9286 return NULL;
9287 }
9288 return (PyObject* )newDBSequenceObject((DBObject*)dbobj, flags);
9289}
9290#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009291
9292static char bsddb_version_doc[] =
9293"Returns a tuple of major, minor, and patch release numbers of the\n\
9294underlying DB library.";
9295
9296static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009297bsddb_version(PyObject* self)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009298{
9299 int major, minor, patch;
9300
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009301 db_version(&major, &minor, &patch);
9302 return Py_BuildValue("(iii)", major, minor, patch);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009303}
9304
9305
9306/* List of functions defined in the module */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009307static PyMethodDef bsddb_methods[] = {
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009308 {"DB", (PyCFunction)DB_construct, METH_VARARGS | METH_KEYWORDS },
9309 {"DBEnv", (PyCFunction)DBEnv_construct, METH_VARARGS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009310#if (DBVER >= 43)
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009311 {"DBSequence", (PyCFunction)DBSequence_construct, METH_VARARGS | METH_KEYWORDS },
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009312#endif
9313 {"version", (PyCFunction)bsddb_version, METH_NOARGS, bsddb_version_doc},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009314 {NULL, NULL} /* sentinel */
9315};
9316
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009317
Gregory P. Smith39250532007-10-09 06:02:21 +00009318/* API structure */
9319static BSDDB_api bsddb_api;
9320
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009321
9322/* --------------------------------------------------------------------- */
9323/* Module initialization */
9324
9325
9326/* Convenience routine to export an integer value.
9327 * Errors are silently ignored, for better or for worse...
9328 */
9329#define ADD_INT(dict, NAME) _addIntToDict(dict, #NAME, NAME)
9330
Gregory P. Smith41631e82003-09-21 00:08:14 +00009331#define MODULE_NAME_MAX_LEN 11
9332static char _bsddbModuleName[MODULE_NAME_MAX_LEN+1] = "_bsddb";
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009333
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009334#if (PY_VERSION_HEX >= 0x03000000)
9335static struct PyModuleDef bsddbmodule = {
9336 PyModuleDef_HEAD_INIT,
9337 _bsddbModuleName, /* Name of module */
9338 NULL, /* module documentation, may be NULL */
9339 -1, /* size of per-interpreter state of the module,
9340 or -1 if the module keeps state in global variables. */
9341 bsddb_methods,
9342 NULL, /* Reload */
9343 NULL, /* Traverse */
9344 NULL, /* Clear */
9345 NULL /* Free */
9346};
9347#endif
9348
9349
9350#if (PY_VERSION_HEX < 0x03000000)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009351DL_EXPORT(void) init_bsddb(void)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009352#else
9353PyMODINIT_FUNC PyInit__bsddb(void) /* Note the two underscores */
9354#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009355{
9356 PyObject* m;
9357 PyObject* d;
Gregory P. Smith39250532007-10-09 06:02:21 +00009358 PyObject* py_api;
Jesus Cea6557aac2010-03-22 14:22:26 +00009359 PyObject* pybsddb_version_s;
9360 PyObject* db_version_s;
9361 PyObject* cvsid_s;
9362
9363#if (PY_VERSION_HEX < 0x03000000)
9364 pybsddb_version_s = PyString_FromString(PY_BSDDB_VERSION);
9365 db_version_s = PyString_FromString(DB_VERSION_STRING);
9366 cvsid_s = PyString_FromString(rcs_id);
9367#else
9368 /* This data should be ascii, so UTF-8 conversion is fine */
9369 pybsddb_version_s = PyUnicode_FromString(PY_BSDDB_VERSION);
9370 db_version_s = PyUnicode_FromString(DB_VERSION_STRING);
9371 cvsid_s = PyUnicode_FromString(rcs_id);
9372#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009373
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009374 /* Initialize object types */
9375 if ((PyType_Ready(&DB_Type) < 0)
9376 || (PyType_Ready(&DBCursor_Type) < 0)
Jesus Cea6557aac2010-03-22 14:22:26 +00009377 || (PyType_Ready(&DBLogCursor_Type) < 0)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009378 || (PyType_Ready(&DBEnv_Type) < 0)
9379 || (PyType_Ready(&DBTxn_Type) < 0)
9380 || (PyType_Ready(&DBLock_Type) < 0)
9381#if (DBVER >= 43)
9382 || (PyType_Ready(&DBSequence_Type) < 0)
9383#endif
9384 ) {
9385#if (PY_VERSION_HEX < 0x03000000)
9386 return;
9387#else
9388 return NULL;
9389#endif
9390 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009391
Mark Hammonda69d4092003-04-22 23:13:27 +00009392#if defined(WITH_THREAD) && !defined(MYDB_USE_GILSTATE)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009393 /* Save the current interpreter, so callbacks can do the right thing. */
Nicholas Bastin2786d902004-03-25 02:16:23 +00009394 _db_interpreterState = PyThreadState_GET()->interp;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009395#endif
9396
9397 /* Create the module and add the functions */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009398#if (PY_VERSION_HEX < 0x03000000)
Gregory P. Smith41631e82003-09-21 00:08:14 +00009399 m = Py_InitModule(_bsddbModuleName, bsddb_methods);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009400#else
9401 m=PyModule_Create(&bsddbmodule);
9402#endif
9403 if (m == NULL) {
9404#if (PY_VERSION_HEX < 0x03000000)
9405 return;
9406#else
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009407 return NULL;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009408#endif
9409 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009410
9411 /* Add some symbolic constants to the module */
9412 d = PyModule_GetDict(m);
9413 PyDict_SetItemString(d, "__version__", pybsddb_version_s);
9414 PyDict_SetItemString(d, "cvsid", cvsid_s);
9415 PyDict_SetItemString(d, "DB_VERSION_STRING", db_version_s);
9416 Py_DECREF(pybsddb_version_s);
9417 pybsddb_version_s = NULL;
9418 Py_DECREF(cvsid_s);
9419 cvsid_s = NULL;
9420 Py_DECREF(db_version_s);
9421 db_version_s = NULL;
9422
9423 ADD_INT(d, DB_VERSION_MAJOR);
9424 ADD_INT(d, DB_VERSION_MINOR);
9425 ADD_INT(d, DB_VERSION_PATCH);
9426
9427 ADD_INT(d, DB_MAX_PAGES);
9428 ADD_INT(d, DB_MAX_RECORDS);
9429
Matthias Klose54cc5392010-03-15 12:46:18 +00009430#if (DBVER < 48)
Gregory P. Smith41631e82003-09-21 00:08:14 +00009431#if (DBVER >= 42)
9432 ADD_INT(d, DB_RPCCLIENT);
9433#else
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009434 ADD_INT(d, DB_CLIENT);
Jesus Ceaef9764f2008-05-13 18:45:46 +00009435 /* allow apps to be written using DB_RPCCLIENT on older Berkeley DB */
Gregory P. Smith41631e82003-09-21 00:08:14 +00009436 _addIntToDict(d, "DB_RPCCLIENT", DB_CLIENT);
9437#endif
Matthias Klose54cc5392010-03-15 12:46:18 +00009438#endif
9439
9440#if (DBVER < 48)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009441 ADD_INT(d, DB_XA_CREATE);
Matthias Klose54cc5392010-03-15 12:46:18 +00009442#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009443
9444 ADD_INT(d, DB_CREATE);
9445 ADD_INT(d, DB_NOMMAP);
9446 ADD_INT(d, DB_THREAD);
Jesus Ceaef9764f2008-05-13 18:45:46 +00009447#if (DBVER >= 45)
9448 ADD_INT(d, DB_MULTIVERSION);
9449#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009450
9451 ADD_INT(d, DB_FORCE);
9452 ADD_INT(d, DB_INIT_CDB);
9453 ADD_INT(d, DB_INIT_LOCK);
9454 ADD_INT(d, DB_INIT_LOG);
9455 ADD_INT(d, DB_INIT_MPOOL);
9456 ADD_INT(d, DB_INIT_TXN);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009457 ADD_INT(d, DB_JOINENV);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009458
Matthias Klose54cc5392010-03-15 12:46:18 +00009459#if (DBVER >= 48)
9460 ADD_INT(d, DB_GID_SIZE);
9461#else
Jesus Ceaef9764f2008-05-13 18:45:46 +00009462 ADD_INT(d, DB_XIDDATASIZE);
Matthias Klose54cc5392010-03-15 12:46:18 +00009463 /* Allow new code to work in old BDB releases */
9464 _addIntToDict(d, "DB_GID_SIZE", DB_XIDDATASIZE);
9465#endif
Jesus Ceaef9764f2008-05-13 18:45:46 +00009466
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009467 ADD_INT(d, DB_RECOVER);
9468 ADD_INT(d, DB_RECOVER_FATAL);
9469 ADD_INT(d, DB_TXN_NOSYNC);
9470 ADD_INT(d, DB_USE_ENVIRON);
9471 ADD_INT(d, DB_USE_ENVIRON_ROOT);
9472
9473 ADD_INT(d, DB_LOCKDOWN);
9474 ADD_INT(d, DB_PRIVATE);
9475 ADD_INT(d, DB_SYSTEM_MEM);
9476
9477 ADD_INT(d, DB_TXN_SYNC);
9478 ADD_INT(d, DB_TXN_NOWAIT);
9479
Jesus Cea6557aac2010-03-22 14:22:26 +00009480#if (DBVER >= 46)
9481 ADD_INT(d, DB_TXN_WAIT);
9482#endif
9483
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009484 ADD_INT(d, DB_EXCL);
9485 ADD_INT(d, DB_FCNTL_LOCKING);
9486 ADD_INT(d, DB_ODDFILESIZE);
9487 ADD_INT(d, DB_RDWRMASTER);
9488 ADD_INT(d, DB_RDONLY);
9489 ADD_INT(d, DB_TRUNCATE);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009490 ADD_INT(d, DB_EXTENT);
9491 ADD_INT(d, DB_CDB_ALLDB);
9492 ADD_INT(d, DB_VERIFY);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009493 ADD_INT(d, DB_UPGRADE);
9494
Jesus Cea6557aac2010-03-22 14:22:26 +00009495 ADD_INT(d, DB_PRINTABLE);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009496 ADD_INT(d, DB_AGGRESSIVE);
9497 ADD_INT(d, DB_NOORDERCHK);
9498 ADD_INT(d, DB_ORDERCHKONLY);
9499 ADD_INT(d, DB_PR_PAGE);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009500
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009501 ADD_INT(d, DB_PR_RECOVERYTEST);
9502 ADD_INT(d, DB_SALVAGE);
9503
9504 ADD_INT(d, DB_LOCK_NORUN);
9505 ADD_INT(d, DB_LOCK_DEFAULT);
9506 ADD_INT(d, DB_LOCK_OLDEST);
9507 ADD_INT(d, DB_LOCK_RANDOM);
9508 ADD_INT(d, DB_LOCK_YOUNGEST);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009509 ADD_INT(d, DB_LOCK_MAXLOCKS);
9510 ADD_INT(d, DB_LOCK_MINLOCKS);
9511 ADD_INT(d, DB_LOCK_MINWRITE);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009512
Jesus Ceaef9764f2008-05-13 18:45:46 +00009513 ADD_INT(d, DB_LOCK_EXPIRE);
Jesus Ceaef9764f2008-05-13 18:45:46 +00009514#if (DBVER >= 43)
9515 ADD_INT(d, DB_LOCK_MAXWRITE);
9516#endif
9517
Barry Warsaw9a0d7792002-12-30 20:53:52 +00009518 _addIntToDict(d, "DB_LOCK_CONFLICT", 0);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009519
9520 ADD_INT(d, DB_LOCK_DUMP);
9521 ADD_INT(d, DB_LOCK_GET);
9522 ADD_INT(d, DB_LOCK_INHERIT);
9523 ADD_INT(d, DB_LOCK_PUT);
9524 ADD_INT(d, DB_LOCK_PUT_ALL);
9525 ADD_INT(d, DB_LOCK_PUT_OBJ);
9526
9527 ADD_INT(d, DB_LOCK_NG);
9528 ADD_INT(d, DB_LOCK_READ);
9529 ADD_INT(d, DB_LOCK_WRITE);
9530 ADD_INT(d, DB_LOCK_NOWAIT);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009531 ADD_INT(d, DB_LOCK_WAIT);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009532 ADD_INT(d, DB_LOCK_IWRITE);
9533 ADD_INT(d, DB_LOCK_IREAD);
9534 ADD_INT(d, DB_LOCK_IWR);
Gregory P. Smith29602d22006-01-24 09:46:48 +00009535#if (DBVER < 44)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009536 ADD_INT(d, DB_LOCK_DIRTY);
Gregory P. Smith29602d22006-01-24 09:46:48 +00009537#else
9538 ADD_INT(d, DB_LOCK_READ_UNCOMMITTED); /* renamed in 4.4 */
9539#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009540 ADD_INT(d, DB_LOCK_WWRITE);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009541
9542 ADD_INT(d, DB_LOCK_RECORD);
9543 ADD_INT(d, DB_LOCK_UPGRADE);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009544 ADD_INT(d, DB_LOCK_SWITCH);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009545 ADD_INT(d, DB_LOCK_UPGRADE_WRITE);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009546
9547 ADD_INT(d, DB_LOCK_NOWAIT);
9548 ADD_INT(d, DB_LOCK_RECORD);
9549 ADD_INT(d, DB_LOCK_UPGRADE);
9550
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009551 ADD_INT(d, DB_LSTAT_ABORTED);
Gregory P. Smith8b7e9172004-12-13 09:51:23 +00009552#if (DBVER < 43)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009553 ADD_INT(d, DB_LSTAT_ERR);
Gregory P. Smith8b7e9172004-12-13 09:51:23 +00009554#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009555 ADD_INT(d, DB_LSTAT_FREE);
9556 ADD_INT(d, DB_LSTAT_HELD);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009557
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009558 ADD_INT(d, DB_LSTAT_PENDING);
9559 ADD_INT(d, DB_LSTAT_WAITING);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009560
9561 ADD_INT(d, DB_ARCH_ABS);
9562 ADD_INT(d, DB_ARCH_DATA);
9563 ADD_INT(d, DB_ARCH_LOG);
Gregory P. Smith3dd20022006-06-05 00:31:01 +00009564#if (DBVER >= 42)
9565 ADD_INT(d, DB_ARCH_REMOVE);
9566#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009567
9568 ADD_INT(d, DB_BTREE);
9569 ADD_INT(d, DB_HASH);
9570 ADD_INT(d, DB_RECNO);
9571 ADD_INT(d, DB_QUEUE);
9572 ADD_INT(d, DB_UNKNOWN);
9573
9574 ADD_INT(d, DB_DUP);
9575 ADD_INT(d, DB_DUPSORT);
9576 ADD_INT(d, DB_RECNUM);
9577 ADD_INT(d, DB_RENUMBER);
9578 ADD_INT(d, DB_REVSPLITOFF);
9579 ADD_INT(d, DB_SNAPSHOT);
9580
Jesus Cea6557aac2010-03-22 14:22:26 +00009581#if (DBVER >= 43)
9582 ADD_INT(d, DB_INORDER);
9583#endif
9584
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009585 ADD_INT(d, DB_JOIN_NOSORT);
9586
9587 ADD_INT(d, DB_AFTER);
9588 ADD_INT(d, DB_APPEND);
9589 ADD_INT(d, DB_BEFORE);
Gregory P. Smith8b96a352007-01-05 01:59:42 +00009590#if (DBVER < 45)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009591 ADD_INT(d, DB_CACHED_COUNTS);
Gregory P. Smith8b96a352007-01-05 01:59:42 +00009592#endif
Jesus Ceaca3939c2008-05-22 15:27:38 +00009593
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009594#if (DBVER <= 41)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009595 ADD_INT(d, DB_COMMIT);
9596#endif
9597 ADD_INT(d, DB_CONSUME);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009598 ADD_INT(d, DB_CONSUME_WAIT);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009599 ADD_INT(d, DB_CURRENT);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009600 ADD_INT(d, DB_FAST_STAT);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009601 ADD_INT(d, DB_FIRST);
9602 ADD_INT(d, DB_FLUSH);
9603 ADD_INT(d, DB_GET_BOTH);
Jesus Cea6557aac2010-03-22 14:22:26 +00009604 ADD_INT(d, DB_GET_BOTH_RANGE);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009605 ADD_INT(d, DB_GET_RECNO);
9606 ADD_INT(d, DB_JOIN_ITEM);
9607 ADD_INT(d, DB_KEYFIRST);
9608 ADD_INT(d, DB_KEYLAST);
9609 ADD_INT(d, DB_LAST);
9610 ADD_INT(d, DB_NEXT);
9611 ADD_INT(d, DB_NEXT_DUP);
9612 ADD_INT(d, DB_NEXT_NODUP);
9613 ADD_INT(d, DB_NODUPDATA);
9614 ADD_INT(d, DB_NOOVERWRITE);
9615 ADD_INT(d, DB_NOSYNC);
9616 ADD_INT(d, DB_POSITION);
9617 ADD_INT(d, DB_PREV);
9618 ADD_INT(d, DB_PREV_NODUP);
Jesus Cea6557aac2010-03-22 14:22:26 +00009619#if (DBVER >= 46)
9620 ADD_INT(d, DB_PREV_DUP);
9621#endif
Gregory P. Smith8b96a352007-01-05 01:59:42 +00009622#if (DBVER < 45)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009623 ADD_INT(d, DB_RECORDCOUNT);
Gregory P. Smith8b96a352007-01-05 01:59:42 +00009624#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009625 ADD_INT(d, DB_SET);
9626 ADD_INT(d, DB_SET_RANGE);
9627 ADD_INT(d, DB_SET_RECNO);
9628 ADD_INT(d, DB_WRITECURSOR);
9629
9630 ADD_INT(d, DB_OPFLAGS_MASK);
9631 ADD_INT(d, DB_RMW);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009632 ADD_INT(d, DB_DIRTY_READ);
9633 ADD_INT(d, DB_MULTIPLE);
9634 ADD_INT(d, DB_MULTIPLE_KEY);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009635
Gregory P. Smith29602d22006-01-24 09:46:48 +00009636#if (DBVER >= 44)
Jesus Cea6557aac2010-03-22 14:22:26 +00009637 ADD_INT(d, DB_IMMUTABLE_KEY);
Gregory P. Smith29602d22006-01-24 09:46:48 +00009638 ADD_INT(d, DB_READ_UNCOMMITTED); /* replaces DB_DIRTY_READ in 4.4 */
9639 ADD_INT(d, DB_READ_COMMITTED);
9640#endif
9641
Jesus Cea6557aac2010-03-22 14:22:26 +00009642#if (DBVER >= 44)
9643 ADD_INT(d, DB_FREELIST_ONLY);
9644 ADD_INT(d, DB_FREE_SPACE);
9645#endif
9646
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009647 ADD_INT(d, DB_DONOTINDEX);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009648
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009649 ADD_INT(d, DB_KEYEMPTY);
9650 ADD_INT(d, DB_KEYEXIST);
9651 ADD_INT(d, DB_LOCK_DEADLOCK);
9652 ADD_INT(d, DB_LOCK_NOTGRANTED);
9653 ADD_INT(d, DB_NOSERVER);
9654 ADD_INT(d, DB_NOSERVER_HOME);
9655 ADD_INT(d, DB_NOSERVER_ID);
9656 ADD_INT(d, DB_NOTFOUND);
9657 ADD_INT(d, DB_OLD_VERSION);
9658 ADD_INT(d, DB_RUNRECOVERY);
9659 ADD_INT(d, DB_VERIFY_BAD);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009660 ADD_INT(d, DB_PAGE_NOTFOUND);
9661 ADD_INT(d, DB_SECONDARY_BAD);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009662 ADD_INT(d, DB_STAT_CLEAR);
9663 ADD_INT(d, DB_REGION_INIT);
9664 ADD_INT(d, DB_NOLOCKING);
9665 ADD_INT(d, DB_YIELDCPU);
9666 ADD_INT(d, DB_PANIC_ENVIRONMENT);
9667 ADD_INT(d, DB_NOPANIC);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009668
Jesus Ceaef9764f2008-05-13 18:45:46 +00009669 ADD_INT(d, DB_OVERWRITE);
Jesus Cea6557aac2010-03-22 14:22:26 +00009670
9671#if (DBVER >= 43)
9672 ADD_INT(d, DB_STAT_SUBSYSTEM);
9673 ADD_INT(d, DB_STAT_MEMP_HASH);
Jesus Ceaef9764f2008-05-13 18:45:46 +00009674#endif
9675
Jesus Cea6557aac2010-03-22 14:22:26 +00009676#if (DBVER >= 48)
9677 ADD_INT(d, DB_OVERWRITE_DUP);
9678#endif
9679
9680#if (DBVER >= 47)
9681 ADD_INT(d, DB_FOREIGN_ABORT);
9682 ADD_INT(d, DB_FOREIGN_CASCADE);
9683 ADD_INT(d, DB_FOREIGN_NULLIFY);
9684#endif
9685
9686#if (DBVER >= 44)
Gregory P. Smithaae141a2007-11-01 21:08:14 +00009687 ADD_INT(d, DB_REGISTER);
9688#endif
9689
Jesus Cea6557aac2010-03-22 14:22:26 +00009690 ADD_INT(d, DB_EID_INVALID);
9691 ADD_INT(d, DB_EID_BROADCAST);
9692
Gregory P. Smith41631e82003-09-21 00:08:14 +00009693#if (DBVER >= 42)
9694 ADD_INT(d, DB_TIME_NOTGRANTED);
9695 ADD_INT(d, DB_TXN_NOT_DURABLE);
9696 ADD_INT(d, DB_TXN_WRITE_NOSYNC);
Gregory P. Smith41631e82003-09-21 00:08:14 +00009697 ADD_INT(d, DB_DIRECT_DB);
9698 ADD_INT(d, DB_INIT_REP);
9699 ADD_INT(d, DB_ENCRYPT);
9700 ADD_INT(d, DB_CHKSUM);
9701#endif
9702
Jesus Ceaca3939c2008-05-22 15:27:38 +00009703#if (DBVER >= 42) && (DBVER < 47)
9704 ADD_INT(d, DB_LOG_AUTOREMOVE);
9705 ADD_INT(d, DB_DIRECT_LOG);
9706#endif
9707
9708#if (DBVER >= 47)
9709 ADD_INT(d, DB_LOG_DIRECT);
9710 ADD_INT(d, DB_LOG_DSYNC);
9711 ADD_INT(d, DB_LOG_IN_MEMORY);
9712 ADD_INT(d, DB_LOG_AUTO_REMOVE);
9713 ADD_INT(d, DB_LOG_ZERO);
9714#endif
9715
Jesus Ceaef9764f2008-05-13 18:45:46 +00009716#if (DBVER >= 44)
9717 ADD_INT(d, DB_DSYNC_DB);
9718#endif
9719
9720#if (DBVER >= 45)
9721 ADD_INT(d, DB_TXN_SNAPSHOT);
9722#endif
9723
Jesus Ceaef9764f2008-05-13 18:45:46 +00009724 ADD_INT(d, DB_VERB_DEADLOCK);
9725#if (DBVER >= 46)
9726 ADD_INT(d, DB_VERB_FILEOPS);
9727 ADD_INT(d, DB_VERB_FILEOPS_ALL);
9728#endif
9729 ADD_INT(d, DB_VERB_RECOVERY);
9730#if (DBVER >= 44)
9731 ADD_INT(d, DB_VERB_REGISTER);
9732#endif
9733 ADD_INT(d, DB_VERB_REPLICATION);
9734 ADD_INT(d, DB_VERB_WAITSFOR);
Jesus Ceaef9764f2008-05-13 18:45:46 +00009735
9736#if (DBVER >= 45)
9737 ADD_INT(d, DB_EVENT_PANIC);
9738 ADD_INT(d, DB_EVENT_REP_CLIENT);
9739#if (DBVER >= 46)
9740 ADD_INT(d, DB_EVENT_REP_ELECTED);
9741#endif
9742 ADD_INT(d, DB_EVENT_REP_MASTER);
9743 ADD_INT(d, DB_EVENT_REP_NEWMASTER);
9744#if (DBVER >= 46)
9745 ADD_INT(d, DB_EVENT_REP_PERM_FAILED);
9746#endif
9747 ADD_INT(d, DB_EVENT_REP_STARTUPDONE);
9748 ADD_INT(d, DB_EVENT_WRITE_FAILED);
9749#endif
9750
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009751 ADD_INT(d, DB_REP_DUPMASTER);
9752 ADD_INT(d, DB_REP_HOLDELECTION);
9753#if (DBVER >= 44)
9754 ADD_INT(d, DB_REP_IGNORE);
9755 ADD_INT(d, DB_REP_JOIN_FAILURE);
9756#endif
9757#if (DBVER >= 42)
9758 ADD_INT(d, DB_REP_ISPERM);
9759 ADD_INT(d, DB_REP_NOTPERM);
9760#endif
9761 ADD_INT(d, DB_REP_NEWSITE);
9762
Jesus Ceaef9764f2008-05-13 18:45:46 +00009763 ADD_INT(d, DB_REP_MASTER);
9764 ADD_INT(d, DB_REP_CLIENT);
Jesus Cea6557aac2010-03-22 14:22:26 +00009765
9766 ADD_INT(d, DB_REP_PERMANENT);
9767
9768#if (DBVER >= 44)
9769 ADD_INT(d, DB_REP_CONF_NOAUTOINIT);
9770 ADD_INT(d, DB_REP_CONF_DELAYCLIENT);
9771 ADD_INT(d, DB_REP_CONF_BULK);
9772 ADD_INT(d, DB_REP_CONF_NOWAIT);
9773 ADD_INT(d, DB_REP_ANYWHERE);
9774 ADD_INT(d, DB_REP_REREQUEST);
9775#endif
9776
9777#if (DBVER >= 42)
9778 ADD_INT(d, DB_REP_NOBUFFER);
9779#endif
9780
9781#if (DBVER >= 46)
9782 ADD_INT(d, DB_REP_LEASE_EXPIRED);
9783 ADD_INT(d, DB_IGNORE_LEASE);
9784#endif
9785
9786#if (DBVER >= 47)
9787 ADD_INT(d, DB_REP_CONF_LEASE);
9788 ADD_INT(d, DB_REPMGR_CONF_2SITE_STRICT);
9789#endif
9790
Jesus Ceaef9764f2008-05-13 18:45:46 +00009791#if (DBVER >= 45)
9792 ADD_INT(d, DB_REP_ELECTION);
9793
9794 ADD_INT(d, DB_REP_ACK_TIMEOUT);
9795 ADD_INT(d, DB_REP_CONNECTION_RETRY);
9796 ADD_INT(d, DB_REP_ELECTION_TIMEOUT);
9797 ADD_INT(d, DB_REP_ELECTION_RETRY);
9798#endif
9799#if (DBVER >= 46)
9800 ADD_INT(d, DB_REP_CHECKPOINT_DELAY);
9801 ADD_INT(d, DB_REP_FULL_ELECTION_TIMEOUT);
Jesus Cea6557aac2010-03-22 14:22:26 +00009802 ADD_INT(d, DB_REP_LEASE_TIMEOUT);
9803#endif
9804#if (DBVER >= 47)
9805 ADD_INT(d, DB_REP_HEARTBEAT_MONITOR);
9806 ADD_INT(d, DB_REP_HEARTBEAT_SEND);
Jesus Ceaef9764f2008-05-13 18:45:46 +00009807#endif
Jesus Ceaef9764f2008-05-13 18:45:46 +00009808
9809#if (DBVER >= 45)
9810 ADD_INT(d, DB_REPMGR_PEER);
9811 ADD_INT(d, DB_REPMGR_ACKS_ALL);
9812 ADD_INT(d, DB_REPMGR_ACKS_ALL_PEERS);
9813 ADD_INT(d, DB_REPMGR_ACKS_NONE);
9814 ADD_INT(d, DB_REPMGR_ACKS_ONE);
9815 ADD_INT(d, DB_REPMGR_ACKS_ONE_PEER);
9816 ADD_INT(d, DB_REPMGR_ACKS_QUORUM);
9817 ADD_INT(d, DB_REPMGR_CONNECTED);
9818 ADD_INT(d, DB_REPMGR_DISCONNECTED);
Jesus Ceaef9764f2008-05-13 18:45:46 +00009819 ADD_INT(d, DB_STAT_ALL);
9820#endif
9821
Gregory P. Smith8b7e9172004-12-13 09:51:23 +00009822#if (DBVER >= 43)
Gregory P. Smith8b7e9172004-12-13 09:51:23 +00009823 ADD_INT(d, DB_BUFFER_SMALL);
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009824 ADD_INT(d, DB_SEQ_DEC);
9825 ADD_INT(d, DB_SEQ_INC);
9826 ADD_INT(d, DB_SEQ_WRAP);
Gregory P. Smith8b7e9172004-12-13 09:51:23 +00009827#endif
9828
Jesus Ceaca3939c2008-05-22 15:27:38 +00009829#if (DBVER >= 43) && (DBVER < 47)
9830 ADD_INT(d, DB_LOG_INMEMORY);
9831 ADD_INT(d, DB_DSYNC_LOG);
9832#endif
9833
Barry Warsaw9a0d7792002-12-30 20:53:52 +00009834 ADD_INT(d, DB_ENCRYPT_AES);
9835 ADD_INT(d, DB_AUTO_COMMIT);
Jesus Cea6557aac2010-03-22 14:22:26 +00009836 ADD_INT(d, DB_PRIORITY_VERY_LOW);
9837 ADD_INT(d, DB_PRIORITY_LOW);
9838 ADD_INT(d, DB_PRIORITY_DEFAULT);
9839 ADD_INT(d, DB_PRIORITY_HIGH);
9840 ADD_INT(d, DB_PRIORITY_VERY_HIGH);
9841
9842#if (DBVER >= 46)
9843 ADD_INT(d, DB_PRIORITY_UNCHANGED);
Barry Warsaw9a0d7792002-12-30 20:53:52 +00009844#endif
9845
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009846 ADD_INT(d, EINVAL);
9847 ADD_INT(d, EACCES);
9848 ADD_INT(d, ENOSPC);
9849 ADD_INT(d, ENOMEM);
9850 ADD_INT(d, EAGAIN);
9851 ADD_INT(d, EBUSY);
9852 ADD_INT(d, EEXIST);
9853 ADD_INT(d, ENOENT);
9854 ADD_INT(d, EPERM);
9855
Barry Warsaw1baa9822003-03-31 19:51:29 +00009856 ADD_INT(d, DB_SET_LOCK_TIMEOUT);
9857 ADD_INT(d, DB_SET_TXN_TIMEOUT);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009858
Gregory P. Smith7f5b6f42006-04-08 07:10:51 +00009859 /* The exception name must be correct for pickled exception *
9860 * objects to unpickle properly. */
9861#ifdef PYBSDDB_STANDALONE /* different value needed for standalone pybsddb */
9862#define PYBSDDB_EXCEPTION_BASE "bsddb3.db."
9863#else
9864#define PYBSDDB_EXCEPTION_BASE "bsddb.db."
9865#endif
9866
9867 /* All the rest of the exceptions derive only from DBError */
9868#define MAKE_EX(name) name = PyErr_NewException(PYBSDDB_EXCEPTION_BASE #name, DBError, NULL); \
9869 PyDict_SetItemString(d, #name, name)
9870
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009871 /* The base exception class is DBError */
Gregory P. Smith7f5b6f42006-04-08 07:10:51 +00009872 DBError = NULL; /* used in MAKE_EX so that it derives from nothing */
9873 MAKE_EX(DBError);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009874
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009875#if (PY_VERSION_HEX < 0x03000000)
Gregory P. Smithe9477062005-06-04 06:46:59 +00009876 /* Some magic to make DBNotFoundError and DBKeyEmptyError derive
9877 * from both DBError and KeyError, since the API only supports
9878 * using one base class. */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009879 PyDict_SetItemString(d, "KeyError", PyExc_KeyError);
Gregory P. Smithe9477062005-06-04 06:46:59 +00009880 PyRun_String("class DBNotFoundError(DBError, KeyError): pass\n"
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009881 "class DBKeyEmptyError(DBError, KeyError): pass",
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009882 Py_file_input, d, d);
9883 DBNotFoundError = PyDict_GetItemString(d, "DBNotFoundError");
Gregory P. Smithe9477062005-06-04 06:46:59 +00009884 DBKeyEmptyError = PyDict_GetItemString(d, "DBKeyEmptyError");
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009885 PyDict_DelItemString(d, "KeyError");
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009886#else
9887 /* Since Python 2.5, PyErr_NewException() accepts a tuple, to be able to
9888 ** derive from several classes. We use this new API only for Python 3.0,
9889 ** though.
9890 */
9891 {
9892 PyObject* bases;
9893
9894 bases = PyTuple_Pack(2, DBError, PyExc_KeyError);
9895
9896#define MAKE_EX2(name) name = PyErr_NewException(PYBSDDB_EXCEPTION_BASE #name, bases, NULL); \
9897 PyDict_SetItemString(d, #name, name)
9898 MAKE_EX2(DBNotFoundError);
9899 MAKE_EX2(DBKeyEmptyError);
9900
9901#undef MAKE_EX2
9902
9903 Py_XDECREF(bases);
9904 }
9905#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009906
Gregory P. Smithe2767172003-11-02 08:06:29 +00009907 MAKE_EX(DBCursorClosedError);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009908 MAKE_EX(DBKeyExistError);
9909 MAKE_EX(DBLockDeadlockError);
9910 MAKE_EX(DBLockNotGrantedError);
9911 MAKE_EX(DBOldVersionError);
9912 MAKE_EX(DBRunRecoveryError);
9913 MAKE_EX(DBVerifyBadError);
9914 MAKE_EX(DBNoServerError);
9915 MAKE_EX(DBNoServerHomeError);
9916 MAKE_EX(DBNoServerIDError);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009917 MAKE_EX(DBPageNotFoundError);
9918 MAKE_EX(DBSecondaryBadError);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009919
9920 MAKE_EX(DBInvalidArgError);
9921 MAKE_EX(DBAccessError);
9922 MAKE_EX(DBNoSpaceError);
9923 MAKE_EX(DBNoMemoryError);
9924 MAKE_EX(DBAgainError);
9925 MAKE_EX(DBBusyError);
9926 MAKE_EX(DBFileExistsError);
9927 MAKE_EX(DBNoSuchFileError);
9928 MAKE_EX(DBPermissionsError);
9929
Jesus Ceaef9764f2008-05-13 18:45:46 +00009930#if (DBVER >= 42)
9931 MAKE_EX(DBRepHandleDeadError);
9932#endif
Jesus Cea6557aac2010-03-22 14:22:26 +00009933#if (DBVER >= 44)
9934 MAKE_EX(DBRepLockoutError);
9935#endif
Jesus Ceaef9764f2008-05-13 18:45:46 +00009936
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009937 MAKE_EX(DBRepUnavailError);
9938
Jesus Cea6557aac2010-03-22 14:22:26 +00009939#if (DBVER >= 46)
9940 MAKE_EX(DBRepLeaseExpiredError);
9941#endif
9942
9943#if (DBVER >= 47)
9944 MAKE_EX(DBForeignConflictError);
9945#endif
9946
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009947#undef MAKE_EX
9948
Jesus Cea6557aac2010-03-22 14:22:26 +00009949 /* Initialise the C API structure and add it to the module */
9950 bsddb_api.db_type = &DB_Type;
9951 bsddb_api.dbcursor_type = &DBCursor_Type;
9952 bsddb_api.dblogcursor_type = &DBLogCursor_Type;
9953 bsddb_api.dbenv_type = &DBEnv_Type;
9954 bsddb_api.dbtxn_type = &DBTxn_Type;
9955 bsddb_api.dblock_type = &DBLock_Type;
Neal Norwitzf3ca1692007-10-12 03:52:34 +00009956#if (DBVER >= 43)
Jesus Cea6557aac2010-03-22 14:22:26 +00009957 bsddb_api.dbsequence_type = &DBSequence_Type;
Neal Norwitzf3ca1692007-10-12 03:52:34 +00009958#endif
Jesus Cea6557aac2010-03-22 14:22:26 +00009959 bsddb_api.makeDBError = makeDBError;
Gregory P. Smith39250532007-10-09 06:02:21 +00009960
Jesus Cea6557aac2010-03-22 14:22:26 +00009961 /*
9962 ** Capsules exist from Python 3.1, but I
9963 ** don't want to break the API compatibility
9964 ** for already published Python versions.
9965 */
9966#if (PY_VERSION_HEX < 0x03020000)
Gregory P. Smith39250532007-10-09 06:02:21 +00009967 py_api = PyCObject_FromVoidPtr((void*)&bsddb_api, NULL);
Jesus Cea6557aac2010-03-22 14:22:26 +00009968#else
9969 {
9970 char py_api_name[250];
9971
9972 strcpy(py_api_name, _bsddbModuleName);
9973 strcat(py_api_name, ".api");
9974
9975 py_api = PyCapsule_New((void*)&bsddb_api, py_api_name, NULL);
9976 }
9977#endif
9978
Jesus Cea84f2c322010-11-05 00:13:50 +00009979 /* Check error control */
9980 /*
9981 ** PyErr_NoMemory();
9982 ** py_api = NULL;
9983 */
9984
9985 if (py_api) {
9986 PyDict_SetItemString(d, "api", py_api);
9987 Py_DECREF(py_api);
9988 } else { /* Something bad happened */
9989 PyErr_WriteUnraisable(m);
Jesus Ceabf088f82010-11-08 12:57:59 +00009990 if(PyErr_Warn(PyExc_RuntimeWarning,
9991 "_bsddb/_pybsddb C API will be not available")) {
9992 PyErr_WriteUnraisable(m);
9993 }
Jesus Cea84f2c322010-11-05 00:13:50 +00009994 PyErr_Clear();
9995 }
Gregory P. Smith39250532007-10-09 06:02:21 +00009996
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009997 /* Check for errors */
9998 if (PyErr_Occurred()) {
9999 PyErr_Print();
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010000 Py_FatalError("can't initialize module _bsddb/_pybsddb");
10001 Py_DECREF(m);
10002 m = NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010003 }
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010004#if (PY_VERSION_HEX < 0x03000000)
10005 return;
10006#else
10007 return m;
10008#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010009}
Gregory P. Smith41631e82003-09-21 00:08:14 +000010010
10011/* allow this module to be named _pybsddb so that it can be installed
10012 * and imported on top of python >= 2.3 that includes its own older
10013 * copy of the library named _bsddb without importing the old version. */
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010014#if (PY_VERSION_HEX < 0x03000000)
Gregory P. Smith41631e82003-09-21 00:08:14 +000010015DL_EXPORT(void) init_pybsddb(void)
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010016#else
10017PyMODINIT_FUNC PyInit__pybsddb(void) /* Note the two underscores */
10018#endif
Gregory P. Smith41631e82003-09-21 00:08:14 +000010019{
10020 strncpy(_bsddbModuleName, "_pybsddb", MODULE_NAME_MAX_LEN);
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010021#if (PY_VERSION_HEX < 0x03000000)
Gregory P. Smith41631e82003-09-21 00:08:14 +000010022 init_bsddb();
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010023#else
10024 return PyInit__bsddb(); /* Note the two underscores */
10025#endif
Gregory P. Smith41631e82003-09-21 00:08:14 +000010026}