blob: a8867942b1fe6e1cb69ff08f72c1a0e4a38dbf39 [file] [log] [blame]
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001/*----------------------------------------------------------------------
2 Copyright (c) 1999-2001, Digital Creations, Fredericksburg, VA, USA
3 and Andrew Kuchling. All rights reserved.
4
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are
7 met:
8
9 o Redistributions of source code must retain the above copyright
10 notice, this list of conditions, and the disclaimer that follows.
11
12 o Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions, and the following disclaimer in
14 the documentation and/or other materials provided with the
15 distribution.
16
17 o Neither the name of Digital Creations nor the names of its
18 contributors may be used to endorse or promote products derived
19 from this software without specific prior written permission.
20
21 THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS AND CONTRIBUTORS *AS
22 IS* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
23 TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
24 PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL
25 CREATIONS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
28 OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
29 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
30 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
31 USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
32 DAMAGE.
33------------------------------------------------------------------------*/
34
35
36/*
37 * Handwritten code to wrap version 3.x of the Berkeley DB library,
Barry Warsaw9a0d7792002-12-30 20:53:52 +000038 * written to replace a SWIG-generated file. It has since been updated
Jesus Ceaef9764f2008-05-13 18:45:46 +000039 * to compile with Berkeley DB versions 3.2 through 4.2.
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000040 *
41 * This module was started by Andrew Kuchling to remove the dependency
Gregory P. Smithf8057852007-09-09 20:25:00 +000042 * on SWIG in a package by Gregory P. Smith who based his work on a
43 * similar package by Robin Dunn <robin@alldunn.com> which wrapped
44 * Berkeley DB 2.7.x.
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000045 *
Barry Warsaw9a0d7792002-12-30 20:53:52 +000046 * Development of this module then returned full circle back to Robin Dunn
47 * who worked on behalf of Digital Creations to complete the wrapping of
48 * the DB 3.x API and to build a solid unit test suite. Robin has
49 * since gone onto other projects (wxPython).
50 *
Jesus Ceaef9764f2008-05-13 18:45:46 +000051 * Gregory P. Smith <greg@krypto.org> was once again the maintainer.
52 *
Jesus Ceaca3939c2008-05-22 15:27:38 +000053 * Since January 2008, new maintainer is Jesus Cea <jcea@jcea.es>.
Jesus Ceaef9764f2008-05-13 18:45:46 +000054 * Jesus Cea licenses this code to PSF under a Contributor Agreement.
Barry Warsaw9a0d7792002-12-30 20:53:52 +000055 *
56 * Use the pybsddb-users@lists.sf.net mailing list for all questions.
Barry Warsawc74e4a52003-04-24 14:28:08 +000057 * Things can change faster than the header of this file is updated. This
58 * file is shared with the PyBSDDB project at SourceForge:
59 *
60 * http://pybsddb.sf.net
61 *
62 * This file should remain backward compatible with Python 2.1, but see PEP
63 * 291 for the most current backward compatibility requirements:
64 *
65 * http://www.python.org/peps/pep-0291.html
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000066 *
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070067 * This module contains 7 types:
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000068 *
69 * DB (Database)
70 * DBCursor (Database Cursor)
71 * DBEnv (database environment)
72 * DBTxn (An explicit database transaction)
73 * DBLock (A lock handle)
Gregory P. Smithf0547d02006-06-05 17:38:04 +000074 * DBSequence (Sequence)
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070075 * DBSite (Site)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000076 *
Jesus Cea6557aac2010-03-22 14:22:26 +000077 * More datatypes added:
78 *
79 * DBLogCursor (Log Cursor)
80 *
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000081 */
82
83/* --------------------------------------------------------------------- */
84
85/*
86 * Portions of this module, associated unit tests and build scripts are the
87 * result of a contract with The Written Word (http://thewrittenword.com/)
88 * Many thanks go out to them for causing me to raise the bar on quality and
89 * functionality, resulting in a better bsddb3 package for all of us to use.
90 *
91 * --Robin
92 */
93
94/* --------------------------------------------------------------------- */
95
Gregory P. Smitha703a212003-11-03 01:04:41 +000096#include <stddef.h> /* for offsetof() */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000097#include <Python.h>
Gregory P. Smith39250532007-10-09 06:02:21 +000098
99#define COMPILING_BSDDB_C
100#include "bsddb.h"
101#undef COMPILING_BSDDB_C
102
103static char *rcs_id = "$Id$";
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000104
105/* --------------------------------------------------------------------- */
106/* Various macro definitions */
107
Gregory P. Smith7f5b6f42006-04-08 07:10:51 +0000108#if (PY_VERSION_HEX < 0x02050000)
Neal Norwitz09a29fa2006-06-12 02:05:55 +0000109typedef int Py_ssize_t;
Gregory P. Smith7f5b6f42006-04-08 07:10:51 +0000110#endif
111
Gregory P. Smith572226c2008-05-26 19:03:35 +0000112#if (PY_VERSION_HEX < 0x02060000) /* really: before python trunk r63675 */
113/* This code now uses PyBytes* API function names instead of PyString*.
114 * These #defines map to their equivalent on earlier python versions. */
115#define PyBytes_FromStringAndSize PyString_FromStringAndSize
116#define PyBytes_FromString PyString_FromString
117#define PyBytes_AsStringAndSize PyString_AsStringAndSize
118#define PyBytes_Check PyString_Check
119#define PyBytes_GET_SIZE PyString_GET_SIZE
120#define PyBytes_AS_STRING PyString_AS_STRING
121#endif
122
Jesus Ceac5a11fa2008-07-23 11:38:42 +0000123#if (PY_VERSION_HEX >= 0x03000000)
124#define NUMBER_Check PyLong_Check
125#define NUMBER_AsLong PyLong_AsLong
126#define NUMBER_FromLong PyLong_FromLong
127#else
128#define NUMBER_Check PyInt_Check
129#define NUMBER_AsLong PyInt_AsLong
130#define NUMBER_FromLong PyInt_FromLong
131#endif
132
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000133#ifdef WITH_THREAD
134
135/* These are for when calling Python --> C */
136#define MYDB_BEGIN_ALLOW_THREADS Py_BEGIN_ALLOW_THREADS;
137#define MYDB_END_ALLOW_THREADS Py_END_ALLOW_THREADS;
138
139/* and these are for calling C --> Python */
Mark Hammonda69d4092003-04-22 23:13:27 +0000140#define MYDB_BEGIN_BLOCK_THREADS \
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000141 PyGILState_STATE __savestate = PyGILState_Ensure();
Mark Hammonda69d4092003-04-22 23:13:27 +0000142#define MYDB_END_BLOCK_THREADS \
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000143 PyGILState_Release(__savestate);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000144
145#else
Mark Hammonda69d4092003-04-22 23:13:27 +0000146/* Compiled without threads - avoid all this cruft */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000147#define MYDB_BEGIN_ALLOW_THREADS
148#define MYDB_END_ALLOW_THREADS
149#define MYDB_BEGIN_BLOCK_THREADS
150#define MYDB_END_BLOCK_THREADS
151
152#endif
153
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000154/* --------------------------------------------------------------------- */
155/* Exceptions */
156
157static PyObject* DBError; /* Base class, all others derive from this */
Gregory P. Smithe2767172003-11-02 08:06:29 +0000158static PyObject* DBCursorClosedError; /* raised when trying to use a closed cursor object */
Gregory P. Smithe9477062005-06-04 06:46:59 +0000159static PyObject* DBKeyEmptyError; /* DB_KEYEMPTY: also derives from KeyError */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000160static PyObject* DBKeyExistError; /* DB_KEYEXIST */
161static PyObject* DBLockDeadlockError; /* DB_LOCK_DEADLOCK */
162static PyObject* DBLockNotGrantedError; /* DB_LOCK_NOTGRANTED */
163static PyObject* DBNotFoundError; /* DB_NOTFOUND: also derives from KeyError */
164static PyObject* DBOldVersionError; /* DB_OLD_VERSION */
165static PyObject* DBRunRecoveryError; /* DB_RUNRECOVERY */
166static PyObject* DBVerifyBadError; /* DB_VERIFY_BAD */
167static PyObject* DBNoServerError; /* DB_NOSERVER */
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -0700168#if (DBVER < 52)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000169static PyObject* DBNoServerHomeError; /* DB_NOSERVER_HOME */
170static PyObject* DBNoServerIDError; /* DB_NOSERVER_ID */
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -0700171#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000172static PyObject* DBPageNotFoundError; /* DB_PAGE_NOTFOUND */
173static PyObject* DBSecondaryBadError; /* DB_SECONDARY_BAD */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000174
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000175static PyObject* DBInvalidArgError; /* EINVAL */
176static PyObject* DBAccessError; /* EACCES */
177static PyObject* DBNoSpaceError; /* ENOSPC */
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -0700178static PyObject* DBNoMemoryError; /* DB_BUFFER_SMALL */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000179static PyObject* DBAgainError; /* EAGAIN */
180static PyObject* DBBusyError; /* EBUSY */
181static PyObject* DBFileExistsError; /* EEXIST */
182static PyObject* DBNoSuchFileError; /* ENOENT */
183static PyObject* DBPermissionsError; /* EPERM */
184
Jesus Ceaef9764f2008-05-13 18:45:46 +0000185static PyObject* DBRepHandleDeadError; /* DB_REP_HANDLE_DEAD */
Jesus Cea6557aac2010-03-22 14:22:26 +0000186#if (DBVER >= 44)
187static PyObject* DBRepLockoutError; /* DB_REP_LOCKOUT */
188#endif
189
190#if (DBVER >= 46)
191static PyObject* DBRepLeaseExpiredError; /* DB_REP_LEASE_EXPIRED */
192#endif
193
194#if (DBVER >= 47)
195static PyObject* DBForeignConflictError; /* DB_FOREIGN_CONFLICT */
196#endif
197
Jesus Ceaef9764f2008-05-13 18:45:46 +0000198
Jesus Ceac5a11fa2008-07-23 11:38:42 +0000199static PyObject* DBRepUnavailError; /* DB_REP_UNAVAIL */
200
Matthias Klose54cc5392010-03-15 12:46:18 +0000201#if (DBVER < 48)
202#define DB_GID_SIZE DB_XIDDATASIZE
203#endif
204
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000205
206/* --------------------------------------------------------------------- */
207/* Structure definitions */
208
Gregory P. Smith39250532007-10-09 06:02:21 +0000209#if PYTHON_API_VERSION < 1010
210#error "Python 2.1 or later required"
Gregory P. Smitha703a212003-11-03 01:04:41 +0000211#endif
212
Gregory P. Smith31c50652004-06-28 01:20:40 +0000213
Gregory P. Smith39250532007-10-09 06:02:21 +0000214/* Defaults for moduleFlags in DBEnvObject and DBObject. */
Gregory P. Smith455d46f2003-07-09 04:45:59 +0000215#define DEFAULT_GET_RETURNS_NONE 1
Gregory P. Smitha703a212003-11-03 01:04:41 +0000216#define DEFAULT_CURSOR_SET_RETURNS_NONE 1 /* 0 in pybsddb < 4.2, python < 2.4 */
Gregory P. Smith455d46f2003-07-09 04:45:59 +0000217
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000218
Jesus Ceac5a11fa2008-07-23 11:38:42 +0000219/* See comment in Python 2.6 "object.h" */
220#ifndef staticforward
221#define staticforward static
222#endif
223#ifndef statichere
224#define statichere static
225#endif
226
227staticforward PyTypeObject DB_Type, DBCursor_Type, DBEnv_Type, DBTxn_Type,
Jesus Cea6557aac2010-03-22 14:22:26 +0000228 DBLock_Type, DBLogCursor_Type;
Jesus Ceaef9764f2008-05-13 18:45:46 +0000229staticforward PyTypeObject DBSequence_Type;
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -0700230#if (DBVER >= 52)
231staticforward PyTypeObject DBSite_Type;
Jesus Ceaef9764f2008-05-13 18:45:46 +0000232#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000233
Martin v. Löwis83c92012008-04-24 13:17:24 +0000234#ifndef Py_TYPE
Gregory P. Smithfc006692007-11-05 09:06:28 +0000235/* for compatibility with Python 2.5 and earlier */
Christian Heimese93237d2007-12-19 02:37:44 +0000236#define Py_TYPE(ob) (((PyObject*)(ob))->ob_type)
Gregory P. Smithfc006692007-11-05 09:06:28 +0000237#endif
238
Christian Heimese93237d2007-12-19 02:37:44 +0000239#define DBObject_Check(v) (Py_TYPE(v) == &DB_Type)
240#define DBCursorObject_Check(v) (Py_TYPE(v) == &DBCursor_Type)
Jesus Cea6557aac2010-03-22 14:22:26 +0000241#define DBLogCursorObject_Check(v) (Py_TYPE(v) == &DBLogCursor_Type)
Christian Heimese93237d2007-12-19 02:37:44 +0000242#define DBEnvObject_Check(v) (Py_TYPE(v) == &DBEnv_Type)
243#define DBTxnObject_Check(v) (Py_TYPE(v) == &DBTxn_Type)
244#define DBLockObject_Check(v) (Py_TYPE(v) == &DBLock_Type)
Christian Heimese93237d2007-12-19 02:37:44 +0000245#define DBSequenceObject_Check(v) (Py_TYPE(v) == &DBSequence_Type)
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -0700246#if (DBVER >= 52)
247#define DBSiteObject_Check(v) (Py_TYPE(v) == &DBSite_Type)
Gregory P. Smithf0547d02006-06-05 17:38:04 +0000248#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000249
Jesus Ceaef9764f2008-05-13 18:45:46 +0000250#if (DBVER < 46)
251 #define _DBC_close(dbc) dbc->c_close(dbc)
252 #define _DBC_count(dbc,a,b) dbc->c_count(dbc,a,b)
253 #define _DBC_del(dbc,a) dbc->c_del(dbc,a)
254 #define _DBC_dup(dbc,a,b) dbc->c_dup(dbc,a,b)
255 #define _DBC_get(dbc,a,b,c) dbc->c_get(dbc,a,b,c)
256 #define _DBC_pget(dbc,a,b,c,d) dbc->c_pget(dbc,a,b,c,d)
257 #define _DBC_put(dbc,a,b,c) dbc->c_put(dbc,a,b,c)
258#else
259 #define _DBC_close(dbc) dbc->close(dbc)
260 #define _DBC_count(dbc,a,b) dbc->count(dbc,a,b)
261 #define _DBC_del(dbc,a) dbc->del(dbc,a)
262 #define _DBC_dup(dbc,a,b) dbc->dup(dbc,a,b)
263 #define _DBC_get(dbc,a,b,c) dbc->get(dbc,a,b,c)
264 #define _DBC_pget(dbc,a,b,c,d) dbc->pget(dbc,a,b,c,d)
265 #define _DBC_put(dbc,a,b,c) dbc->put(dbc,a,b,c)
266#endif
267
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000268
269/* --------------------------------------------------------------------- */
270/* Utility macros and functions */
271
Jesus Ceaef9764f2008-05-13 18:45:46 +0000272#define INSERT_IN_DOUBLE_LINKED_LIST(backlink,object) \
273 { \
274 object->sibling_next=backlink; \
275 object->sibling_prev_p=&(backlink); \
276 backlink=object; \
277 if (object->sibling_next) { \
278 object->sibling_next->sibling_prev_p=&(object->sibling_next); \
279 } \
280 }
281
282#define EXTRACT_FROM_DOUBLE_LINKED_LIST(object) \
283 { \
284 if (object->sibling_next) { \
285 object->sibling_next->sibling_prev_p=object->sibling_prev_p; \
286 } \
287 *(object->sibling_prev_p)=object->sibling_next; \
288 }
289
290#define EXTRACT_FROM_DOUBLE_LINKED_LIST_MAYBE_NULL(object) \
291 { \
292 if (object->sibling_next) { \
293 object->sibling_next->sibling_prev_p=object->sibling_prev_p; \
294 } \
295 if (object->sibling_prev_p) { \
296 *(object->sibling_prev_p)=object->sibling_next; \
297 } \
298 }
299
300#define INSERT_IN_DOUBLE_LINKED_LIST_TXN(backlink,object) \
301 { \
302 object->sibling_next_txn=backlink; \
303 object->sibling_prev_p_txn=&(backlink); \
304 backlink=object; \
305 if (object->sibling_next_txn) { \
306 object->sibling_next_txn->sibling_prev_p_txn= \
307 &(object->sibling_next_txn); \
308 } \
309 }
310
311#define EXTRACT_FROM_DOUBLE_LINKED_LIST_TXN(object) \
312 { \
313 if (object->sibling_next_txn) { \
314 object->sibling_next_txn->sibling_prev_p_txn= \
315 object->sibling_prev_p_txn; \
316 } \
317 *(object->sibling_prev_p_txn)=object->sibling_next_txn; \
318 }
319
320
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000321#define RETURN_IF_ERR() \
322 if (makeDBError(err)) { \
323 return NULL; \
324 }
325
326#define RETURN_NONE() Py_INCREF(Py_None); return Py_None;
327
Gregory P. Smithe2767172003-11-02 08:06:29 +0000328#define _CHECK_OBJECT_NOT_CLOSED(nonNull, pyErrObj, name) \
329 if ((nonNull) == NULL) { \
330 PyObject *errTuple = NULL; \
331 errTuple = Py_BuildValue("(is)", 0, #name " object has been closed"); \
Jesus Ceac5a11fa2008-07-23 11:38:42 +0000332 if (errTuple) { \
333 PyErr_SetObject((pyErrObj), errTuple); \
334 Py_DECREF(errTuple); \
335 } \
Gregory P. Smithe2767172003-11-02 08:06:29 +0000336 return NULL; \
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000337 }
338
Gregory P. Smithe2767172003-11-02 08:06:29 +0000339#define CHECK_DB_NOT_CLOSED(dbobj) \
340 _CHECK_OBJECT_NOT_CLOSED(dbobj->db, DBError, DB)
341
342#define CHECK_ENV_NOT_CLOSED(env) \
343 _CHECK_OBJECT_NOT_CLOSED(env->db_env, DBError, DBEnv)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000344
345#define CHECK_CURSOR_NOT_CLOSED(curs) \
Gregory P. Smithe2767172003-11-02 08:06:29 +0000346 _CHECK_OBJECT_NOT_CLOSED(curs->dbc, DBCursorClosedError, DBCursor)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000347
Jesus Cea6557aac2010-03-22 14:22:26 +0000348#define CHECK_LOGCURSOR_NOT_CLOSED(logcurs) \
349 _CHECK_OBJECT_NOT_CLOSED(logcurs->logc, DBCursorClosedError, DBLogCursor)
350
Gregory P. Smithf0547d02006-06-05 17:38:04 +0000351#define CHECK_SEQUENCE_NOT_CLOSED(curs) \
352 _CHECK_OBJECT_NOT_CLOSED(curs->sequence, DBError, DBSequence)
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -0700353
354#if (DBVER >= 52)
355#define CHECK_SITE_NOT_CLOSED(db_site) \
356 _CHECK_OBJECT_NOT_CLOSED(db_site->site, DBError, DBSite)
Gregory P. Smithf0547d02006-06-05 17:38:04 +0000357#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000358
359#define CHECK_DBFLAG(mydb, flag) (((mydb)->flags & (flag)) || \
360 (((mydb)->myenvobj != NULL) && ((mydb)->myenvobj->flags & (flag))))
361
362#define CLEAR_DBT(dbt) (memset(&(dbt), 0, sizeof(dbt)))
363
364#define FREE_DBT(dbt) if ((dbt.flags & (DB_DBT_MALLOC|DB_DBT_REALLOC)) && \
Gregory P. Smithdc5af702004-06-27 23:32:34 +0000365 dbt.data != NULL) { free(dbt.data); dbt.data = NULL; }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000366
367
368static int makeDBError(int err);
369
370
371/* Return the access method type of the DBObject */
372static int _DB_get_type(DBObject* self)
373{
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000374 DBTYPE type;
375 int err;
Jesus Ceac5a11fa2008-07-23 11:38:42 +0000376
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000377 err = self->db->get_type(self->db, &type);
378 if (makeDBError(err)) {
379 return -1;
380 }
381 return type;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000382}
383
384
385/* Create a DBT structure (containing key and data values) from Python
386 strings. Returns 1 on success, 0 on an error. */
387static int make_dbt(PyObject* obj, DBT* dbt)
388{
389 CLEAR_DBT(*dbt);
390 if (obj == Py_None) {
391 /* no need to do anything, the structure has already been zeroed */
392 }
393 else if (!PyArg_Parse(obj, "s#", &dbt->data, &dbt->size)) {
394 PyErr_SetString(PyExc_TypeError,
Jesus Cea4907d272008-08-31 14:00:51 +0000395#if (PY_VERSION_HEX < 0x03000000)
Gregory P. Smithdc5af702004-06-27 23:32:34 +0000396 "Data values must be of type string or None.");
Jesus Cea4907d272008-08-31 14:00:51 +0000397#else
398 "Data values must be of type bytes or None.");
399#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000400 return 0;
401 }
402 return 1;
403}
404
405
406/* Recno and Queue DBs can have integer keys. This function figures out
407 what's been given, verifies that it's allowed, and then makes the DBT.
408
Gregory P. Smithdc5af702004-06-27 23:32:34 +0000409 Caller MUST call FREE_DBT(key) when done. */
Barry Warsaw9a0d7792002-12-30 20:53:52 +0000410static int
411make_key_dbt(DBObject* self, PyObject* keyobj, DBT* key, int* pflags)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000412{
413 db_recno_t recno;
414 int type;
415
416 CLEAR_DBT(*key);
Gustavo Niemeyerf073b752004-01-20 15:24:29 +0000417 if (keyobj == Py_None) {
Gustavo Niemeyer024f2de2004-01-20 15:14:55 +0000418 type = _DB_get_type(self);
Gustavo Niemeyer8974f722004-01-20 15:20:03 +0000419 if (type == -1)
420 return 0;
Gustavo Niemeyer024f2de2004-01-20 15:14:55 +0000421 if (type == DB_RECNO || type == DB_QUEUE) {
422 PyErr_SetString(
423 PyExc_TypeError,
424 "None keys not allowed for Recno and Queue DB's");
425 return 0;
426 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000427 /* no need to do anything, the structure has already been zeroed */
428 }
429
Christian Heimes593daf52008-05-26 12:51:38 +0000430 else if (PyBytes_Check(keyobj)) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000431 /* verify access method type */
432 type = _DB_get_type(self);
433 if (type == -1)
434 return 0;
435 if (type == DB_RECNO || type == DB_QUEUE) {
Barry Warsaw9a0d7792002-12-30 20:53:52 +0000436 PyErr_SetString(
437 PyExc_TypeError,
Jesus Cea4907d272008-08-31 14:00:51 +0000438#if (PY_VERSION_HEX < 0x03000000)
Barry Warsaw9a0d7792002-12-30 20:53:52 +0000439 "String keys not allowed for Recno and Queue DB's");
Jesus Cea4907d272008-08-31 14:00:51 +0000440#else
441 "Bytes keys not allowed for Recno and Queue DB's");
442#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000443 return 0;
444 }
445
Gregory P. Smith10bed542007-10-09 06:50:43 +0000446 /*
447 * NOTE(gps): I don't like doing a data copy here, it seems
448 * wasteful. But without a clean way to tell FREE_DBT if it
449 * should free key->data or not we have to. Other places in
450 * the code check for DB_THREAD and forceably set DBT_MALLOC
451 * when we otherwise would leave flags 0 to indicate that.
452 */
Christian Heimes593daf52008-05-26 12:51:38 +0000453 key->data = malloc(PyBytes_GET_SIZE(keyobj));
Gregory P. Smith10bed542007-10-09 06:50:43 +0000454 if (key->data == NULL) {
455 PyErr_SetString(PyExc_MemoryError, "Key memory allocation failed");
456 return 0;
457 }
Christian Heimes593daf52008-05-26 12:51:38 +0000458 memcpy(key->data, PyBytes_AS_STRING(keyobj),
459 PyBytes_GET_SIZE(keyobj));
Gregory P. Smith10bed542007-10-09 06:50:43 +0000460 key->flags = DB_DBT_REALLOC;
Christian Heimes593daf52008-05-26 12:51:38 +0000461 key->size = PyBytes_GET_SIZE(keyobj);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000462 }
463
Jesus Ceac5a11fa2008-07-23 11:38:42 +0000464 else if (NUMBER_Check(keyobj)) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000465 /* verify access method type */
466 type = _DB_get_type(self);
467 if (type == -1)
468 return 0;
469 if (type == DB_BTREE && pflags != NULL) {
Barry Warsaw9a0d7792002-12-30 20:53:52 +0000470 /* if BTREE then an Integer key is allowed with the
471 * DB_SET_RECNO flag */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000472 *pflags |= DB_SET_RECNO;
473 }
474 else if (type != DB_RECNO && type != DB_QUEUE) {
Barry Warsaw9a0d7792002-12-30 20:53:52 +0000475 PyErr_SetString(
476 PyExc_TypeError,
477 "Integer keys only allowed for Recno and Queue DB's");
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000478 return 0;
479 }
480
Barry Warsaw9a0d7792002-12-30 20:53:52 +0000481 /* Make a key out of the requested recno, use allocated space so DB
482 * will be able to realloc room for the real key if needed. */
Jesus Ceac5a11fa2008-07-23 11:38:42 +0000483 recno = NUMBER_AsLong(keyobj);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000484 key->data = malloc(sizeof(db_recno_t));
485 if (key->data == NULL) {
486 PyErr_SetString(PyExc_MemoryError, "Key memory allocation failed");
487 return 0;
488 }
489 key->ulen = key->size = sizeof(db_recno_t);
490 memcpy(key->data, &recno, sizeof(db_recno_t));
491 key->flags = DB_DBT_REALLOC;
492 }
493 else {
494 PyErr_Format(PyExc_TypeError,
Jesus Cea4907d272008-08-31 14:00:51 +0000495#if (PY_VERSION_HEX < 0x03000000)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000496 "String or Integer object expected for key, %s found",
Jesus Cea4907d272008-08-31 14:00:51 +0000497#else
498 "Bytes or Integer object expected for key, %s found",
499#endif
Christian Heimese93237d2007-12-19 02:37:44 +0000500 Py_TYPE(keyobj)->tp_name);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000501 return 0;
502 }
503
504 return 1;
505}
506
507
508/* Add partial record access to an existing DBT data struct.
509 If dlen and doff are set, then the DB_DBT_PARTIAL flag will be set
510 and the data storage/retrieval will be done using dlen and doff. */
511static int add_partial_dbt(DBT* d, int dlen, int doff) {
512 /* if neither were set we do nothing (-1 is the default value) */
513 if ((dlen == -1) && (doff == -1)) {
514 return 1;
515 }
516
517 if ((dlen < 0) || (doff < 0)) {
518 PyErr_SetString(PyExc_TypeError, "dlen and doff must both be >= 0");
519 return 0;
520 }
521
522 d->flags = d->flags | DB_DBT_PARTIAL;
523 d->dlen = (unsigned int) dlen;
524 d->doff = (unsigned int) doff;
525 return 1;
526}
527
Gregory P. Smith8b7e9172004-12-13 09:51:23 +0000528/* a safe strcpy() without the zeroing behaviour and semantics of strncpy. */
529/* TODO: make this use the native libc strlcpy() when available (BSD) */
530unsigned int our_strlcpy(char* dest, const char* src, unsigned int n)
531{
532 unsigned int srclen, copylen;
533
534 srclen = strlen(src);
535 if (n <= 0)
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000536 return srclen;
Gregory P. Smith8b7e9172004-12-13 09:51:23 +0000537 copylen = (srclen > n-1) ? n-1 : srclen;
538 /* populate dest[0] thru dest[copylen-1] */
539 memcpy(dest, src, copylen);
540 /* guarantee null termination */
541 dest[copylen] = 0;
542
543 return srclen;
544}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000545
Barry Warsaw9a0d7792002-12-30 20:53:52 +0000546/* Callback used to save away more information about errors from the DB
547 * library. */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000548static char _db_errmsg[1024];
Gregory P. Smith8b7e9172004-12-13 09:51:23 +0000549static void _db_errorCallback(const DB_ENV *db_env,
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000550 const char* prefix, const char* msg)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000551{
Gregory P. Smith8b7e9172004-12-13 09:51:23 +0000552 our_strlcpy(_db_errmsg, msg, sizeof(_db_errmsg));
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000553}
554
555
Jesus Ceaef9764f2008-05-13 18:45:46 +0000556/*
557** We need these functions because some results
558** are undefined if pointer is NULL. Some other
559** give None instead of "".
560**
561** This functions are static and will be
562** -I hope- inlined.
563*/
564static const char *DummyString = "This string is a simple placeholder";
565static PyObject *Build_PyString(const char *p,int s)
566{
567 if (!p) {
568 p=DummyString;
569 assert(s==0);
570 }
Christian Heimes593daf52008-05-26 12:51:38 +0000571 return PyBytes_FromStringAndSize(p,s);
Jesus Ceaef9764f2008-05-13 18:45:46 +0000572}
573
574static PyObject *BuildValue_S(const void *p,int s)
575{
576 if (!p) {
577 p=DummyString;
578 assert(s==0);
579 }
Jesus Cea4907d272008-08-31 14:00:51 +0000580 return PyBytes_FromStringAndSize(p, s);
Jesus Ceaef9764f2008-05-13 18:45:46 +0000581}
582
583static PyObject *BuildValue_SS(const void *p1,int s1,const void *p2,int s2)
584{
Jesus Cea4907d272008-08-31 14:00:51 +0000585PyObject *a, *b, *r;
586
Jesus Ceaef9764f2008-05-13 18:45:46 +0000587 if (!p1) {
588 p1=DummyString;
589 assert(s1==0);
590 }
591 if (!p2) {
592 p2=DummyString;
593 assert(s2==0);
594 }
Jesus Cea4907d272008-08-31 14:00:51 +0000595
596 if (!(a = PyBytes_FromStringAndSize(p1, s1))) {
597 return NULL;
598 }
599 if (!(b = PyBytes_FromStringAndSize(p2, s2))) {
600 Py_DECREF(a);
601 return NULL;
602 }
603
Jesus Cea4907d272008-08-31 14:00:51 +0000604 r = PyTuple_Pack(2, a, b) ;
Jesus Cea4907d272008-08-31 14:00:51 +0000605 Py_DECREF(a);
606 Py_DECREF(b);
607 return r;
Jesus Ceaef9764f2008-05-13 18:45:46 +0000608}
609
610static PyObject *BuildValue_IS(int i,const void *p,int s)
611{
Jesus Cea4907d272008-08-31 14:00:51 +0000612 PyObject *a, *r;
613
Jesus Ceaef9764f2008-05-13 18:45:46 +0000614 if (!p) {
615 p=DummyString;
616 assert(s==0);
617 }
Jesus Cea4907d272008-08-31 14:00:51 +0000618
619 if (!(a = PyBytes_FromStringAndSize(p, s))) {
620 return NULL;
621 }
622
623 r = Py_BuildValue("iO", i, a);
624 Py_DECREF(a);
625 return r;
Jesus Ceaef9764f2008-05-13 18:45:46 +0000626}
627
Jesus Cea4907d272008-08-31 14:00:51 +0000628static PyObject *BuildValue_LS(long l,const void *p,int s)
Jesus Ceaef9764f2008-05-13 18:45:46 +0000629{
Jesus Cea4907d272008-08-31 14:00:51 +0000630 PyObject *a, *r;
631
Jesus Ceaef9764f2008-05-13 18:45:46 +0000632 if (!p) {
633 p=DummyString;
634 assert(s==0);
635 }
Jesus Cea4907d272008-08-31 14:00:51 +0000636
637 if (!(a = PyBytes_FromStringAndSize(p, s))) {
638 return NULL;
639 }
640
641 r = Py_BuildValue("lO", l, a);
642 Py_DECREF(a);
643 return r;
Jesus Ceaef9764f2008-05-13 18:45:46 +0000644}
645
646
647
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000648/* make a nice exception object to raise for errors. */
649static int makeDBError(int err)
650{
651 char errTxt[2048]; /* really big, just in case... */
Barry Warsaw9a0d7792002-12-30 20:53:52 +0000652 PyObject *errObj = NULL;
653 PyObject *errTuple = NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000654 int exceptionRaised = 0;
Neal Norwitzdce937f2006-07-23 08:01:43 +0000655 unsigned int bytes_left;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000656
657 switch (err) {
Jesus Cea6557aac2010-03-22 14:22:26 +0000658 case 0: /* successful, no error */
659 return 0;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000660
661 case DB_KEYEMPTY: errObj = DBKeyEmptyError; break;
662 case DB_KEYEXIST: errObj = DBKeyExistError; break;
663 case DB_LOCK_DEADLOCK: errObj = DBLockDeadlockError; break;
664 case DB_LOCK_NOTGRANTED: errObj = DBLockNotGrantedError; break;
665 case DB_NOTFOUND: errObj = DBNotFoundError; break;
666 case DB_OLD_VERSION: errObj = DBOldVersionError; break;
667 case DB_RUNRECOVERY: errObj = DBRunRecoveryError; break;
668 case DB_VERIFY_BAD: errObj = DBVerifyBadError; break;
669 case DB_NOSERVER: errObj = DBNoServerError; break;
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -0700670#if (DBVER < 52)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000671 case DB_NOSERVER_HOME: errObj = DBNoServerHomeError; break;
672 case DB_NOSERVER_ID: errObj = DBNoServerIDError; break;
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -0700673#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000674 case DB_PAGE_NOTFOUND: errObj = DBPageNotFoundError; break;
675 case DB_SECONDARY_BAD: errObj = DBSecondaryBadError; break;
Gregory P. Smith8b7e9172004-12-13 09:51:23 +0000676 case DB_BUFFER_SMALL: errObj = DBNoMemoryError; break;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000677
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000678 case ENOMEM: errObj = PyExc_MemoryError; break;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000679 case EINVAL: errObj = DBInvalidArgError; break;
680 case EACCES: errObj = DBAccessError; break;
681 case ENOSPC: errObj = DBNoSpaceError; break;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000682 case EAGAIN: errObj = DBAgainError; break;
683 case EBUSY : errObj = DBBusyError; break;
684 case EEXIST: errObj = DBFileExistsError; break;
685 case ENOENT: errObj = DBNoSuchFileError; break;
686 case EPERM : errObj = DBPermissionsError; break;
687
Jesus Ceaef9764f2008-05-13 18:45:46 +0000688 case DB_REP_HANDLE_DEAD : errObj = DBRepHandleDeadError; break;
Jesus Cea6557aac2010-03-22 14:22:26 +0000689#if (DBVER >= 44)
690 case DB_REP_LOCKOUT : errObj = DBRepLockoutError; break;
691#endif
692
693#if (DBVER >= 46)
694 case DB_REP_LEASE_EXPIRED : errObj = DBRepLeaseExpiredError; break;
695#endif
696
697#if (DBVER >= 47)
698 case DB_FOREIGN_CONFLICT : errObj = DBForeignConflictError; break;
699#endif
Jesus Ceaef9764f2008-05-13 18:45:46 +0000700
Jesus Ceac5a11fa2008-07-23 11:38:42 +0000701 case DB_REP_UNAVAIL : errObj = DBRepUnavailError; break;
702
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000703 default: errObj = DBError; break;
704 }
705
706 if (errObj != NULL) {
Neal Norwitzdce937f2006-07-23 08:01:43 +0000707 bytes_left = our_strlcpy(errTxt, db_strerror(err), sizeof(errTxt));
708 /* Ensure that bytes_left never goes negative */
709 if (_db_errmsg[0] && bytes_left < (sizeof(errTxt) - 4)) {
710 bytes_left = sizeof(errTxt) - bytes_left - 4 - 1;
711 assert(bytes_left >= 0);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000712 strcat(errTxt, " -- ");
Neal Norwitzdce937f2006-07-23 08:01:43 +0000713 strncat(errTxt, _db_errmsg, bytes_left);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000714 }
Neal Norwitzdce937f2006-07-23 08:01:43 +0000715 _db_errmsg[0] = 0;
Barry Warsaw9a0d7792002-12-30 20:53:52 +0000716
Jesus Ceac5a11fa2008-07-23 11:38:42 +0000717 errTuple = Py_BuildValue("(is)", err, errTxt);
718 if (errTuple == NULL) {
719 Py_DECREF(errObj);
720 return !0;
721 }
Barry Warsaw9a0d7792002-12-30 20:53:52 +0000722 PyErr_SetObject(errObj, errTuple);
Jesus Ceac5a11fa2008-07-23 11:38:42 +0000723 Py_DECREF(errTuple);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000724 }
725
726 return ((errObj != NULL) || exceptionRaised);
727}
728
729
730
731/* set a type exception */
732static void makeTypeError(char* expected, PyObject* found)
733{
734 PyErr_Format(PyExc_TypeError, "Expected %s argument, %s found.",
Christian Heimese93237d2007-12-19 02:37:44 +0000735 expected, Py_TYPE(found)->tp_name);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000736}
737
738
739/* verify that an obj is either None or a DBTxn, and set the txn pointer */
740static int checkTxnObj(PyObject* txnobj, DB_TXN** txn)
741{
742 if (txnobj == Py_None || txnobj == NULL) {
743 *txn = NULL;
744 return 1;
745 }
746 if (DBTxnObject_Check(txnobj)) {
747 *txn = ((DBTxnObject*)txnobj)->txn;
748 return 1;
749 }
750 else
751 makeTypeError("DBTxn", txnobj);
752 return 0;
753}
754
755
756/* Delete a key from a database
757 Returns 0 on success, -1 on an error. */
758static int _DB_delete(DBObject* self, DB_TXN *txn, DBT *key, int flags)
759{
760 int err;
761
762 MYDB_BEGIN_ALLOW_THREADS;
763 err = self->db->del(self->db, txn, key, 0);
764 MYDB_END_ALLOW_THREADS;
765 if (makeDBError(err)) {
766 return -1;
767 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000768 return 0;
769}
770
771
772/* Store a key into a database
773 Returns 0 on success, -1 on an error. */
774static int _DB_put(DBObject* self, DB_TXN *txn, DBT *key, DBT *data, int flags)
775{
776 int err;
777
778 MYDB_BEGIN_ALLOW_THREADS;
779 err = self->db->put(self->db, txn, key, data, flags);
780 MYDB_END_ALLOW_THREADS;
781 if (makeDBError(err)) {
782 return -1;
783 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000784 return 0;
785}
786
787/* Get a key/data pair from a cursor */
788static PyObject* _DBCursor_get(DBCursorObject* self, int extra_flags,
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000789 PyObject *args, PyObject *kwargs, char *format)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000790{
791 int err;
792 PyObject* retval = NULL;
793 DBT key, data;
794 int dlen = -1;
795 int doff = -1;
796 int flags = 0;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +0000797 static char* kwnames[] = { "flags", "dlen", "doff", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000798
799 if (!PyArg_ParseTupleAndKeywords(args, kwargs, format, kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000800 &flags, &dlen, &doff))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000801 return NULL;
802
803 CHECK_CURSOR_NOT_CLOSED(self);
804
805 flags |= extra_flags;
806 CLEAR_DBT(key);
807 CLEAR_DBT(data);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000808 if (!add_partial_dbt(&data, dlen, doff))
809 return NULL;
810
811 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +0000812 err = _DBC_get(self->dbc, &key, &data, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000813 MYDB_END_ALLOW_THREADS;
814
Gregory P. Smithe9477062005-06-04 06:46:59 +0000815 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000816 && self->mydb->moduleFlags.getReturnsNone) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000817 Py_INCREF(Py_None);
818 retval = Py_None;
819 }
820 else if (makeDBError(err)) {
821 retval = NULL;
822 }
823 else { /* otherwise, success! */
824
825 /* if Recno or Queue, return the key as an Int */
826 switch (_DB_get_type(self->mydb)) {
827 case -1:
828 retval = NULL;
829 break;
830
831 case DB_RECNO:
832 case DB_QUEUE:
Jesus Ceaef9764f2008-05-13 18:45:46 +0000833 retval = BuildValue_IS(*((db_recno_t*)key.data), data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000834 break;
835 case DB_HASH:
836 case DB_BTREE:
837 default:
Jesus Ceaef9764f2008-05-13 18:45:46 +0000838 retval = BuildValue_SS(key.data, key.size, data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000839 break;
840 }
841 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000842 return retval;
843}
844
845
846/* add an integer to a dictionary using the given name as a key */
847static void _addIntToDict(PyObject* dict, char *name, int value)
848{
Jesus Ceac5a11fa2008-07-23 11:38:42 +0000849 PyObject* v = NUMBER_FromLong((long) value);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000850 if (!v || PyDict_SetItemString(dict, name, v))
851 PyErr_Clear();
852
853 Py_XDECREF(v);
854}
Kristján Valur Jónssonbd77c032007-04-26 15:24:54 +0000855
856/* The same, when the value is a time_t */
857static void _addTimeTToDict(PyObject* dict, char *name, time_t value)
858{
859 PyObject* v;
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000860 /* if the value fits in regular int, use that. */
Jesus Ceaef9764f2008-05-13 18:45:46 +0000861#ifdef PY_LONG_LONG
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000862 if (sizeof(time_t) > sizeof(long))
863 v = PyLong_FromLongLong((PY_LONG_LONG) value);
864 else
Kristján Valur Jónssonbd77c032007-04-26 15:24:54 +0000865#endif
Antoine Pitrouc83ea132010-05-09 14:46:46 +0000866 v = NUMBER_FromLong((long) value);
Kristján Valur Jónssonbd77c032007-04-26 15:24:54 +0000867 if (!v || PyDict_SetItemString(dict, name, v))
868 PyErr_Clear();
869
870 Py_XDECREF(v);
871}
872
Gregory P. Smithf0547d02006-06-05 17:38:04 +0000873/* add an db_seq_t to a dictionary using the given name as a key */
874static void _addDb_seq_tToDict(PyObject* dict, char *name, db_seq_t value)
875{
876 PyObject* v = PyLong_FromLongLong(value);
877 if (!v || PyDict_SetItemString(dict, name, v))
878 PyErr_Clear();
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000879
Gregory P. Smithf0547d02006-06-05 17:38:04 +0000880 Py_XDECREF(v);
881}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000882
Jesus Ceaef9764f2008-05-13 18:45:46 +0000883static void _addDB_lsnToDict(PyObject* dict, char *name, DB_LSN value)
884{
885 PyObject *v = Py_BuildValue("(ll)",value.file,value.offset);
886 if (!v || PyDict_SetItemString(dict, name, v))
887 PyErr_Clear();
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000888
Jesus Ceaef9764f2008-05-13 18:45:46 +0000889 Py_XDECREF(v);
890}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000891
892/* --------------------------------------------------------------------- */
893/* Allocators and deallocators */
894
895static DBObject*
896newDBObject(DBEnvObject* arg, int flags)
897{
898 DBObject* self;
899 DB_ENV* db_env = NULL;
900 int err;
901
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000902 self = PyObject_New(DBObject, &DB_Type);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000903 if (self == NULL)
904 return NULL;
905
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000906 self->flags = 0;
907 self->setflags = 0;
908 self->myenvobj = NULL;
Jesus Ceac5a11fa2008-07-23 11:38:42 +0000909 self->db = NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +0000910 self->children_cursors = NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +0000911 self->children_sequences = NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000912 self->associateCallback = NULL;
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +0000913 self->btCompareCallback = NULL;
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -0700914 self->dupCompareCallback = NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000915 self->primaryDBType = 0;
Jesus Ceac5a11fa2008-07-23 11:38:42 +0000916 Py_INCREF(Py_None);
Jesus Cea4907d272008-08-31 14:00:51 +0000917 self->private_obj = Py_None;
Gregory P. Smith31c50652004-06-28 01:20:40 +0000918 self->in_weakreflist = NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000919
920 /* keep a reference to our python DBEnv object */
921 if (arg) {
922 Py_INCREF(arg);
923 self->myenvobj = arg;
924 db_env = arg->db_env;
Jesus Ceaef9764f2008-05-13 18:45:46 +0000925 INSERT_IN_DOUBLE_LINKED_LIST(self->myenvobj->children_dbs,self);
926 } else {
927 self->sibling_prev_p=NULL;
928 self->sibling_next=NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000929 }
Jesus Ceaef9764f2008-05-13 18:45:46 +0000930 self->txn=NULL;
931 self->sibling_prev_p_txn=NULL;
932 self->sibling_next_txn=NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000933
Victor Stinner2c277312017-05-03 18:04:18 +0200934 if (self->myenvobj) {
Gregory P. Smith455d46f2003-07-09 04:45:59 +0000935 self->moduleFlags = self->myenvobj->moduleFlags;
Victor Stinner2c277312017-05-03 18:04:18 +0200936 }
937 else {
Gregory P. Smith455d46f2003-07-09 04:45:59 +0000938 self->moduleFlags.getReturnsNone = DEFAULT_GET_RETURNS_NONE;
939 self->moduleFlags.cursorSetReturnsNone = DEFAULT_CURSOR_SET_RETURNS_NONE;
Victor Stinner2c277312017-05-03 18:04:18 +0200940 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000941
942 MYDB_BEGIN_ALLOW_THREADS;
943 err = db_create(&self->db, db_env, flags);
Neal Norwitzdce937f2006-07-23 08:01:43 +0000944 if (self->db != NULL) {
945 self->db->set_errcall(self->db, _db_errorCallback);
Neal Norwitzdce937f2006-07-23 08:01:43 +0000946 self->db->app_private = (void*)self;
Neal Norwitzdce937f2006-07-23 08:01:43 +0000947 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000948 MYDB_END_ALLOW_THREADS;
Gregory P. Smith31c50652004-06-28 01:20:40 +0000949 /* TODO add a weakref(self) to the self->myenvobj->open_child_weakrefs
950 * list so that a DBEnv can refuse to close without aborting any open
Gregory P. Smithf0547d02006-06-05 17:38:04 +0000951 * DBTxns and closing any open DBs first. */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000952 if (makeDBError(err)) {
953 if (self->myenvobj) {
Serhiy Storchaka98a97222014-02-09 13:14:04 +0200954 Py_CLEAR(self->myenvobj);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000955 }
Gregory P. Smith664782e2008-05-17 06:12:02 +0000956 Py_DECREF(self);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000957 self = NULL;
958 }
959 return self;
960}
961
962
Jesus Ceaef9764f2008-05-13 18:45:46 +0000963/* Forward declaration */
Jesus Cea5cd5f122008-09-23 18:54:08 +0000964static PyObject *DB_close_internal(DBObject* self, int flags, int do_not_close);
Jesus Ceaef9764f2008-05-13 18:45:46 +0000965
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000966static void
967DB_dealloc(DBObject* self)
968{
Jesus Ceaef9764f2008-05-13 18:45:46 +0000969 PyObject *dummy;
970
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000971 if (self->db != NULL) {
Jesus Cea5cd5f122008-09-23 18:54:08 +0000972 dummy=DB_close_internal(self, 0, 0);
973 /*
974 ** Raising exceptions while doing
975 ** garbage collection is a fatal error.
976 */
977 if (dummy)
978 Py_DECREF(dummy);
979 else
980 PyErr_Clear();
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000981 }
Gregory P. Smith31c50652004-06-28 01:20:40 +0000982 if (self->in_weakreflist != NULL) {
983 PyObject_ClearWeakRefs((PyObject *) self);
984 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000985 if (self->myenvobj) {
Serhiy Storchaka98a97222014-02-09 13:14:04 +0200986 Py_CLEAR(self->myenvobj);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000987 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000988 if (self->associateCallback != NULL) {
Serhiy Storchaka98a97222014-02-09 13:14:04 +0200989 Py_CLEAR(self->associateCallback);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000990 }
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +0000991 if (self->btCompareCallback != NULL) {
Serhiy Storchaka98a97222014-02-09 13:14:04 +0200992 Py_CLEAR(self->btCompareCallback);
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +0000993 }
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -0700994 if (self->dupCompareCallback != NULL) {
Serhiy Storchaka98a97222014-02-09 13:14:04 +0200995 Py_CLEAR(self->dupCompareCallback);
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -0700996 }
Jesus Cea4907d272008-08-31 14:00:51 +0000997 Py_DECREF(self->private_obj);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000998 PyObject_Del(self);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +0000999}
1000
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001001static DBCursorObject*
Jesus Ceaef9764f2008-05-13 18:45:46 +00001002newDBCursorObject(DBC* dbc, DBTxnObject *txn, DBObject* db)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001003{
Neal Norwitzb4a55812004-07-09 23:30:57 +00001004 DBCursorObject* self = PyObject_New(DBCursorObject, &DBCursor_Type);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001005 if (self == NULL)
1006 return NULL;
1007
1008 self->dbc = dbc;
1009 self->mydb = db;
Jesus Ceaef9764f2008-05-13 18:45:46 +00001010
1011 INSERT_IN_DOUBLE_LINKED_LIST(self->mydb->children_cursors,self);
1012 if (txn && ((PyObject *)txn!=Py_None)) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001013 INSERT_IN_DOUBLE_LINKED_LIST_TXN(txn->children_cursors,self);
1014 self->txn=txn;
Jesus Ceaef9764f2008-05-13 18:45:46 +00001015 } else {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001016 self->txn=NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00001017 }
1018
Gregory P. Smitha703a212003-11-03 01:04:41 +00001019 self->in_weakreflist = NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001020 Py_INCREF(self->mydb);
1021 return self;
1022}
1023
1024
Jesus Ceaef9764f2008-05-13 18:45:46 +00001025/* Forward declaration */
1026static PyObject *DBC_close_internal(DBCursorObject* self);
1027
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001028static void
1029DBCursor_dealloc(DBCursorObject* self)
1030{
Jesus Ceaef9764f2008-05-13 18:45:46 +00001031 PyObject *dummy;
Gregory P. Smitha703a212003-11-03 01:04:41 +00001032
Jesus Ceaef9764f2008-05-13 18:45:46 +00001033 if (self->dbc != NULL) {
Jesus Cea5cd5f122008-09-23 18:54:08 +00001034 dummy=DBC_close_internal(self);
1035 /*
1036 ** Raising exceptions while doing
1037 ** garbage collection is a fatal error.
1038 */
1039 if (dummy)
1040 Py_DECREF(dummy);
1041 else
1042 PyErr_Clear();
Jesus Ceaef9764f2008-05-13 18:45:46 +00001043 }
Gregory P. Smitha703a212003-11-03 01:04:41 +00001044 if (self->in_weakreflist != NULL) {
1045 PyObject_ClearWeakRefs((PyObject *) self);
1046 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00001047 Py_DECREF(self->mydb);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001048 PyObject_Del(self);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001049}
1050
1051
Jesus Cea6557aac2010-03-22 14:22:26 +00001052static DBLogCursorObject*
1053newDBLogCursorObject(DB_LOGC* dblogc, DBEnvObject* env)
1054{
1055 DBLogCursorObject* self;
1056
1057 self = PyObject_New(DBLogCursorObject, &DBLogCursor_Type);
1058
1059 if (self == NULL)
1060 return NULL;
1061
1062 self->logc = dblogc;
1063 self->env = env;
1064
1065 INSERT_IN_DOUBLE_LINKED_LIST(self->env->children_logcursors, self);
1066
1067 self->in_weakreflist = NULL;
1068 Py_INCREF(self->env);
1069 return self;
1070}
1071
1072
1073/* Forward declaration */
1074static PyObject *DBLogCursor_close_internal(DBLogCursorObject* self);
1075
1076static void
1077DBLogCursor_dealloc(DBLogCursorObject* self)
1078{
1079 PyObject *dummy;
1080
1081 if (self->logc != NULL) {
1082 dummy = DBLogCursor_close_internal(self);
1083 /*
1084 ** Raising exceptions while doing
1085 ** garbage collection is a fatal error.
1086 */
1087 if (dummy)
1088 Py_DECREF(dummy);
1089 else
1090 PyErr_Clear();
1091 }
1092 if (self->in_weakreflist != NULL) {
1093 PyObject_ClearWeakRefs((PyObject *) self);
1094 }
1095 Py_DECREF(self->env);
1096 PyObject_Del(self);
1097}
1098
1099
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001100static DBEnvObject*
1101newDBEnvObject(int flags)
1102{
1103 int err;
Neal Norwitzb4a55812004-07-09 23:30:57 +00001104 DBEnvObject* self = PyObject_New(DBEnvObject, &DBEnv_Type);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001105 if (self == NULL)
1106 return NULL;
1107
Jesus Cea5cd5f122008-09-23 18:54:08 +00001108 self->db_env = NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001109 self->closed = 1;
1110 self->flags = flags;
Gregory P. Smith455d46f2003-07-09 04:45:59 +00001111 self->moduleFlags.getReturnsNone = DEFAULT_GET_RETURNS_NONE;
1112 self->moduleFlags.cursorSetReturnsNone = DEFAULT_CURSOR_SET_RETURNS_NONE;
Jesus Ceaef9764f2008-05-13 18:45:46 +00001113 self->children_dbs = NULL;
1114 self->children_txns = NULL;
Jesus Cea6557aac2010-03-22 14:22:26 +00001115 self->children_logcursors = NULL ;
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07001116#if (DBVER >= 52)
1117 self->children_sites = NULL;
1118#endif
Jesus Ceac5a11fa2008-07-23 11:38:42 +00001119 Py_INCREF(Py_None);
Jesus Cea4907d272008-08-31 14:00:51 +00001120 self->private_obj = Py_None;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00001121 Py_INCREF(Py_None);
1122 self->rep_transport = Py_None;
Gregory P. Smith31c50652004-06-28 01:20:40 +00001123 self->in_weakreflist = NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00001124 self->event_notifyCallback = NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00001125
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001126 MYDB_BEGIN_ALLOW_THREADS;
1127 err = db_env_create(&self->db_env, flags);
1128 MYDB_END_ALLOW_THREADS;
1129 if (makeDBError(err)) {
Gregory P. Smith664782e2008-05-17 06:12:02 +00001130 Py_DECREF(self);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001131 self = NULL;
1132 }
1133 else {
1134 self->db_env->set_errcall(self->db_env, _db_errorCallback);
Jesus Cea4907d272008-08-31 14:00:51 +00001135 self->db_env->app_private = self;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001136 }
1137 return self;
1138}
1139
Jesus Ceaef9764f2008-05-13 18:45:46 +00001140/* Forward declaration */
1141static PyObject *DBEnv_close_internal(DBEnvObject* self, int flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001142
1143static void
1144DBEnv_dealloc(DBEnvObject* self)
1145{
Jesus Ceaef9764f2008-05-13 18:45:46 +00001146 PyObject *dummy;
1147
Jesus Ceaac25fab2008-09-03 17:50:32 +00001148 if (self->db_env) {
Jesus Cea5cd5f122008-09-23 18:54:08 +00001149 dummy=DBEnv_close_internal(self, 0);
1150 /*
1151 ** Raising exceptions while doing
1152 ** garbage collection is a fatal error.
1153 */
1154 if (dummy)
1155 Py_DECREF(dummy);
1156 else
1157 PyErr_Clear();
Jesus Ceaef9764f2008-05-13 18:45:46 +00001158 }
1159
Serhiy Storchaka98a97222014-02-09 13:14:04 +02001160 Py_CLEAR(self->event_notifyCallback);
Jesus Ceaef9764f2008-05-13 18:45:46 +00001161
Gregory P. Smith31c50652004-06-28 01:20:40 +00001162 if (self->in_weakreflist != NULL) {
1163 PyObject_ClearWeakRefs((PyObject *) self);
1164 }
Jesus Cea4907d272008-08-31 14:00:51 +00001165 Py_DECREF(self->private_obj);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00001166 Py_DECREF(self->rep_transport);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001167 PyObject_Del(self);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001168}
1169
1170
1171static DBTxnObject*
Jesus Ceaef9764f2008-05-13 18:45:46 +00001172newDBTxnObject(DBEnvObject* myenv, DBTxnObject *parent, DB_TXN *txn, int flags)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001173{
1174 int err;
Gregory P. Smith664782e2008-05-17 06:12:02 +00001175 DB_TXN *parent_txn = NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00001176
Neal Norwitzb4a55812004-07-09 23:30:57 +00001177 DBTxnObject* self = PyObject_New(DBTxnObject, &DBTxn_Type);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001178 if (self == NULL)
1179 return NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00001180
Gregory P. Smith31c50652004-06-28 01:20:40 +00001181 self->in_weakreflist = NULL;
Gregory P. Smith664782e2008-05-17 06:12:02 +00001182 self->children_txns = NULL;
1183 self->children_dbs = NULL;
1184 self->children_cursors = NULL;
1185 self->children_sequences = NULL;
1186 self->flag_prepare = 0;
1187 self->parent_txn = NULL;
1188 self->env = NULL;
Jesus Cea6557aac2010-03-22 14:22:26 +00001189 /* We initialize just in case "txn_begin" fails */
1190 self->txn = NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001191
Jesus Ceaef9764f2008-05-13 18:45:46 +00001192 if (parent && ((PyObject *)parent!=Py_None)) {
Gregory P. Smith664782e2008-05-17 06:12:02 +00001193 parent_txn = parent->txn;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001194 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00001195
1196 if (txn) {
Gregory P. Smith664782e2008-05-17 06:12:02 +00001197 self->txn = txn;
Jesus Ceaef9764f2008-05-13 18:45:46 +00001198 } else {
1199 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00001200 err = myenv->db_env->txn_begin(myenv->db_env, parent_txn, &(self->txn), flags);
Jesus Ceaef9764f2008-05-13 18:45:46 +00001201 MYDB_END_ALLOW_THREADS;
1202
1203 if (makeDBError(err)) {
Jesus Cea6557aac2010-03-22 14:22:26 +00001204 /* Free object half initialized */
Gregory P. Smith664782e2008-05-17 06:12:02 +00001205 Py_DECREF(self);
Jesus Ceaef9764f2008-05-13 18:45:46 +00001206 return NULL;
1207 }
1208 }
1209
Gregory P. Smith664782e2008-05-17 06:12:02 +00001210 /* Can't use 'parent' because could be 'parent==Py_None' */
1211 if (parent_txn) {
1212 self->parent_txn = parent;
Jesus Ceaef9764f2008-05-13 18:45:46 +00001213 Py_INCREF(parent);
1214 self->env = NULL;
Gregory P. Smith664782e2008-05-17 06:12:02 +00001215 INSERT_IN_DOUBLE_LINKED_LIST(parent->children_txns, self);
Jesus Ceaef9764f2008-05-13 18:45:46 +00001216 } else {
Gregory P. Smith664782e2008-05-17 06:12:02 +00001217 self->parent_txn = NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00001218 Py_INCREF(myenv);
1219 self->env = myenv;
Gregory P. Smith664782e2008-05-17 06:12:02 +00001220 INSERT_IN_DOUBLE_LINKED_LIST(myenv->children_txns, self);
Jesus Ceaef9764f2008-05-13 18:45:46 +00001221 }
1222
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001223 return self;
1224}
1225
Jesus Ceaef9764f2008-05-13 18:45:46 +00001226/* Forward declaration */
1227static PyObject *
1228DBTxn_abort_discard_internal(DBTxnObject* self, int discard);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001229
1230static void
1231DBTxn_dealloc(DBTxnObject* self)
1232{
Jesus Ceaef9764f2008-05-13 18:45:46 +00001233 PyObject *dummy;
1234
1235 if (self->txn) {
1236 int flag_prepare = self->flag_prepare;
Jesus Cea5cd5f122008-09-23 18:54:08 +00001237
Jesus Cea6557aac2010-03-22 14:22:26 +00001238 dummy=DBTxn_abort_discard_internal(self, 0);
Jesus Cea5cd5f122008-09-23 18:54:08 +00001239 /*
1240 ** Raising exceptions while doing
1241 ** garbage collection is a fatal error.
1242 */
1243 if (dummy)
1244 Py_DECREF(dummy);
1245 else
1246 PyErr_Clear();
1247
Jesus Ceaef9764f2008-05-13 18:45:46 +00001248 if (!flag_prepare) {
1249 PyErr_Warn(PyExc_RuntimeWarning,
1250 "DBTxn aborted in destructor. No prior commit() or abort().");
1251 }
1252 }
1253
Gregory P. Smith31c50652004-06-28 01:20:40 +00001254 if (self->in_weakreflist != NULL) {
1255 PyObject_ClearWeakRefs((PyObject *) self);
1256 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001257
Jesus Ceaef9764f2008-05-13 18:45:46 +00001258 if (self->env) {
1259 Py_DECREF(self->env);
1260 } else {
Jesus Cea6557aac2010-03-22 14:22:26 +00001261 /*
1262 ** We can have "self->env==NULL" and "self->parent_txn==NULL"
1263 ** if something happens when creating the transaction object
1264 ** and we abort the object while half done.
1265 */
1266 Py_XDECREF(self->parent_txn);
Gregory P. Smith31c50652004-06-28 01:20:40 +00001267 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001268 PyObject_Del(self);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001269}
1270
1271
1272static DBLockObject*
1273newDBLockObject(DBEnvObject* myenv, u_int32_t locker, DBT* obj,
1274 db_lockmode_t lock_mode, int flags)
1275{
1276 int err;
Neal Norwitzb4a55812004-07-09 23:30:57 +00001277 DBLockObject* self = PyObject_New(DBLockObject, &DBLock_Type);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001278 if (self == NULL)
1279 return NULL;
Gregory P. Smith31c50652004-06-28 01:20:40 +00001280 self->in_weakreflist = NULL;
Jesus Cea6557aac2010-03-22 14:22:26 +00001281 self->lock_initialized = 0; /* Just in case the call fails */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001282
1283 MYDB_BEGIN_ALLOW_THREADS;
Barry Warsaw9a0d7792002-12-30 20:53:52 +00001284 err = myenv->db_env->lock_get(myenv->db_env, locker, flags, obj, lock_mode,
1285 &self->lock);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001286 MYDB_END_ALLOW_THREADS;
1287 if (makeDBError(err)) {
Gregory P. Smith664782e2008-05-17 06:12:02 +00001288 Py_DECREF(self);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001289 self = NULL;
Jesus Cea6557aac2010-03-22 14:22:26 +00001290 } else {
1291 self->lock_initialized = 1;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001292 }
1293
1294 return self;
1295}
1296
1297
1298static void
1299DBLock_dealloc(DBLockObject* self)
1300{
Gregory P. Smith31c50652004-06-28 01:20:40 +00001301 if (self->in_weakreflist != NULL) {
1302 PyObject_ClearWeakRefs((PyObject *) self);
1303 }
Gregory P. Smith31c50652004-06-28 01:20:40 +00001304 /* TODO: is this lock held? should we release it? */
Jesus Cea6557aac2010-03-22 14:22:26 +00001305 /* CAUTION: The lock can be not initialized if the creation has failed */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001306
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001307 PyObject_Del(self);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001308}
1309
1310
Gregory P. Smithf0547d02006-06-05 17:38:04 +00001311static DBSequenceObject*
1312newDBSequenceObject(DBObject* mydb, int flags)
1313{
1314 int err;
1315 DBSequenceObject* self = PyObject_New(DBSequenceObject, &DBSequence_Type);
1316 if (self == NULL)
1317 return NULL;
1318 Py_INCREF(mydb);
1319 self->mydb = mydb;
Gregory P. Smithf0547d02006-06-05 17:38:04 +00001320
Jesus Ceaef9764f2008-05-13 18:45:46 +00001321 INSERT_IN_DOUBLE_LINKED_LIST(self->mydb->children_sequences,self);
Gregory P. Smith664782e2008-05-17 06:12:02 +00001322 self->txn = NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00001323
1324 self->in_weakreflist = NULL;
Jesus Cea6557aac2010-03-22 14:22:26 +00001325 self->sequence = NULL; /* Just in case the call fails */
Gregory P. Smithf0547d02006-06-05 17:38:04 +00001326
1327 MYDB_BEGIN_ALLOW_THREADS;
1328 err = db_sequence_create(&self->sequence, self->mydb->db, flags);
1329 MYDB_END_ALLOW_THREADS;
1330 if (makeDBError(err)) {
Gregory P. Smith664782e2008-05-17 06:12:02 +00001331 Py_DECREF(self);
Gregory P. Smithf0547d02006-06-05 17:38:04 +00001332 self = NULL;
1333 }
1334
1335 return self;
1336}
1337
Jesus Ceaef9764f2008-05-13 18:45:46 +00001338/* Forward declaration */
1339static PyObject
1340*DBSequence_close_internal(DBSequenceObject* self, int flags, int do_not_close);
Gregory P. Smithf0547d02006-06-05 17:38:04 +00001341
1342static void
1343DBSequence_dealloc(DBSequenceObject* self)
1344{
Jesus Ceaef9764f2008-05-13 18:45:46 +00001345 PyObject *dummy;
1346
1347 if (self->sequence != NULL) {
1348 dummy=DBSequence_close_internal(self,0,0);
Jesus Cea5cd5f122008-09-23 18:54:08 +00001349 /*
1350 ** Raising exceptions while doing
1351 ** garbage collection is a fatal error.
1352 */
1353 if (dummy)
1354 Py_DECREF(dummy);
1355 else
1356 PyErr_Clear();
Jesus Ceaef9764f2008-05-13 18:45:46 +00001357 }
1358
Gregory P. Smithf0547d02006-06-05 17:38:04 +00001359 if (self->in_weakreflist != NULL) {
1360 PyObject_ClearWeakRefs((PyObject *) self);
1361 }
Gregory P. Smithf0547d02006-06-05 17:38:04 +00001362
1363 Py_DECREF(self->mydb);
1364 PyObject_Del(self);
1365}
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07001366
1367#if (DBVER >= 52)
1368static DBSiteObject*
1369newDBSiteObject(DB_SITE* sitep, DBEnvObject* env)
1370{
1371 DBSiteObject* self;
1372
1373 self = PyObject_New(DBSiteObject, &DBSite_Type);
1374
1375 if (self == NULL)
1376 return NULL;
1377
1378 self->site = sitep;
1379 self->env = env;
1380
1381 INSERT_IN_DOUBLE_LINKED_LIST(self->env->children_sites, self);
1382
1383 self->in_weakreflist = NULL;
1384 Py_INCREF(self->env);
1385 return self;
1386}
1387
1388/* Forward declaration */
1389static PyObject *DBSite_close_internal(DBSiteObject* self);
1390
1391static void
1392DBSite_dealloc(DBSiteObject* self)
1393{
1394 PyObject *dummy;
1395
1396 if (self->site != NULL) {
1397 dummy = DBSite_close_internal(self);
1398 /*
1399 ** Raising exceptions while doing
1400 ** garbage collection is a fatal error.
1401 */
1402 if (dummy)
1403 Py_DECREF(dummy);
1404 else
1405 PyErr_Clear();
1406 }
1407 if (self->in_weakreflist != NULL) {
1408 PyObject_ClearWeakRefs((PyObject *) self);
1409 }
1410 Py_DECREF(self->env);
1411 PyObject_Del(self);
1412}
Gregory P. Smithf0547d02006-06-05 17:38:04 +00001413#endif
1414
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001415/* --------------------------------------------------------------------- */
1416/* DB methods */
1417
1418static PyObject*
Jesus Cea4907d272008-08-31 14:00:51 +00001419DB_append(DBObject* self, PyObject* args, PyObject* kwargs)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001420{
1421 PyObject* txnobj = NULL;
1422 PyObject* dataobj;
1423 db_recno_t recno;
1424 DBT key, data;
1425 DB_TXN *txn = NULL;
Jesus Cea4907d272008-08-31 14:00:51 +00001426 static char* kwnames[] = { "data", "txn", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001427
Jesus Cea4907d272008-08-31 14:00:51 +00001428 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O:append", kwnames,
1429 &dataobj, &txnobj))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001430 return NULL;
1431
1432 CHECK_DB_NOT_CLOSED(self);
1433
1434 /* make a dummy key out of a recno */
1435 recno = 0;
1436 CLEAR_DBT(key);
1437 key.data = &recno;
1438 key.size = sizeof(recno);
1439 key.ulen = key.size;
1440 key.flags = DB_DBT_USERMEM;
1441
1442 if (!make_dbt(dataobj, &data)) return NULL;
1443 if (!checkTxnObj(txnobj, &txn)) return NULL;
1444
1445 if (-1 == _DB_put(self, txn, &key, &data, DB_APPEND))
1446 return NULL;
1447
Jesus Ceac5a11fa2008-07-23 11:38:42 +00001448 return NUMBER_FromLong(recno);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001449}
1450
1451
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001452static int
Barry Warsaw9a0d7792002-12-30 20:53:52 +00001453_db_associateCallback(DB* db, const DBT* priKey, const DBT* priData,
1454 DBT* secKey)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001455{
1456 int retval = DB_DONOTINDEX;
1457 DBObject* secondaryDB = (DBObject*)db->app_private;
1458 PyObject* callback = secondaryDB->associateCallback;
1459 int type = secondaryDB->primaryDBType;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001460 PyObject* args;
Thomas Wouters89ba3812006-03-07 14:14:51 +00001461 PyObject* result = NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001462
1463
1464 if (callback != NULL) {
1465 MYDB_BEGIN_BLOCK_THREADS;
1466
Thomas Woutersb3153832006-03-08 01:47:19 +00001467 if (type == DB_RECNO || type == DB_QUEUE)
Jesus Ceaef9764f2008-05-13 18:45:46 +00001468 args = BuildValue_LS(*((db_recno_t*)priKey->data), priData->data, priData->size);
Thomas Woutersb3153832006-03-08 01:47:19 +00001469 else
Jesus Ceaef9764f2008-05-13 18:45:46 +00001470 args = BuildValue_SS(priKey->data, priKey->size, priData->data, priData->size);
Thomas Wouters098f6942006-03-07 14:13:17 +00001471 if (args != NULL) {
Thomas Wouters098f6942006-03-07 14:13:17 +00001472 result = PyEval_CallObject(callback, args);
1473 }
1474 if (args == NULL || result == NULL) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001475 PyErr_Print();
1476 }
1477 else if (result == Py_None) {
1478 retval = DB_DONOTINDEX;
1479 }
Jesus Ceac5a11fa2008-07-23 11:38:42 +00001480 else if (NUMBER_Check(result)) {
1481 retval = NUMBER_AsLong(result);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001482 }
Christian Heimes593daf52008-05-26 12:51:38 +00001483 else if (PyBytes_Check(result)) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001484 char* data;
Martin v. Löwis18e16552006-02-15 17:27:45 +00001485 Py_ssize_t size;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001486
1487 CLEAR_DBT(*secKey);
Christian Heimes593daf52008-05-26 12:51:38 +00001488 PyBytes_AsStringAndSize(result, &data, &size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001489 secKey->flags = DB_DBT_APPMALLOC; /* DB will free */
1490 secKey->data = malloc(size); /* TODO, check this */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001491 if (secKey->data) {
1492 memcpy(secKey->data, data, size);
1493 secKey->size = size;
1494 retval = 0;
1495 }
1496 else {
1497 PyErr_SetString(PyExc_MemoryError,
Barry Warsaw9a0d7792002-12-30 20:53:52 +00001498 "malloc failed in _db_associateCallback");
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001499 PyErr_Print();
1500 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001501 }
Jesus Cea6557aac2010-03-22 14:22:26 +00001502#if (DBVER >= 46)
1503 else if (PyList_Check(result))
1504 {
1505 char* data;
Zackery Spytz32522052018-07-21 02:27:44 -06001506 Py_ssize_t size, listlen, i;
Jesus Cea6557aac2010-03-22 14:22:26 +00001507 DBT* dbts;
1508
1509 listlen = PyList_Size(result);
1510
Zackery Spytz32522052018-07-21 02:27:44 -06001511 if (listlen > PY_SIZE_MAX / sizeof(DBT)) {
1512 PyErr_NoMemory();
1513 PyErr_Print();
1514 }
1515 else {
1516 dbts = (DBT *)malloc(sizeof(DBT) * listlen);
1517 if (dbts == NULL) {
1518 PyErr_NoMemory();
1519 PyErr_Print();
1520 }
1521 else {
1522 for (i = 0; i < listlen; i++) {
1523 if (!PyBytes_Check(PyList_GetItem(result, i))) {
1524 PyErr_SetString(PyExc_TypeError,
Jesus Cea6557aac2010-03-22 14:22:26 +00001525#if (PY_VERSION_HEX < 0x03000000)
1526"The list returned by DB->associate callback should be a list of strings.");
1527#else
1528"The list returned by DB->associate callback should be a list of bytes.");
1529#endif
Zackery Spytz32522052018-07-21 02:27:44 -06001530 break;
1531 }
Jesus Cea6557aac2010-03-22 14:22:26 +00001532
Zackery Spytz32522052018-07-21 02:27:44 -06001533 if (PyBytes_AsStringAndSize(PyList_GetItem(result, i),
1534 &data, &size) < 0) {
1535 break;
1536 }
Jesus Cea6557aac2010-03-22 14:22:26 +00001537
Zackery Spytz32522052018-07-21 02:27:44 -06001538 CLEAR_DBT(dbts[i]);
1539 dbts[i].data = malloc(size);
1540 if (dbts[i].data) {
1541 memcpy(dbts[i].data, data, size);
1542 dbts[i].size = size;
1543 dbts[i].ulen = dbts[i].size;
1544 /* DB will free. */
1545 dbts[i].flags = DB_DBT_APPMALLOC;
1546 }
1547 else {
1548 PyErr_SetString(PyExc_MemoryError,
1549 "malloc failed in "
1550 "_db_associateCallback (list)");
1551 break;
1552 }
1553 }
1554 if (PyErr_Occurred()) {
1555 PyErr_Print();
1556 while (i--) {
1557 free(dbts[i].data);
1558 }
1559 free(dbts);
1560 }
1561 else {
1562 CLEAR_DBT(*secKey);
Jesus Cea6557aac2010-03-22 14:22:26 +00001563
Zackery Spytz32522052018-07-21 02:27:44 -06001564 secKey->data = dbts;
1565 secKey->size = listlen;
1566 secKey->flags = DB_DBT_APPMALLOC | DB_DBT_MULTIPLE;
1567 retval = 0;
1568 }
Jesus Cea6557aac2010-03-22 14:22:26 +00001569 }
1570 }
Jesus Cea6557aac2010-03-22 14:22:26 +00001571 }
1572#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001573 else {
Barry Warsaw9a0d7792002-12-30 20:53:52 +00001574 PyErr_SetString(
1575 PyExc_TypeError,
Jesus Cea6557aac2010-03-22 14:22:26 +00001576#if (PY_VERSION_HEX < 0x03000000)
1577"DB associate callback should return DB_DONOTINDEX/string/list of strings.");
1578#else
1579"DB associate callback should return DB_DONOTINDEX/bytes/list of bytes.");
1580#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001581 PyErr_Print();
1582 }
1583
Thomas Woutersb3153832006-03-08 01:47:19 +00001584 Py_XDECREF(args);
1585 Py_XDECREF(result);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001586
1587 MYDB_END_BLOCK_THREADS;
1588 }
1589 return retval;
1590}
1591
1592
1593static PyObject*
1594DB_associate(DBObject* self, PyObject* args, PyObject* kwargs)
1595{
1596 int err, flags=0;
1597 DBObject* secondaryDB;
1598 PyObject* callback;
Barry Warsaw9a0d7792002-12-30 20:53:52 +00001599 PyObject *txnobj = NULL;
1600 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00001601 static char* kwnames[] = {"secondaryDB", "callback", "flags", "txn",
Jeremy Hyltonaf68c872005-12-10 18:50:16 +00001602 NULL};
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001603
Barry Warsaw9a0d7792002-12-30 20:53:52 +00001604 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|iO:associate", kwnames,
1605 &secondaryDB, &callback, &flags,
1606 &txnobj)) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001607 return NULL;
Barry Warsaw9a0d7792002-12-30 20:53:52 +00001608 }
1609
Barry Warsaw9a0d7792002-12-30 20:53:52 +00001610 if (!checkTxnObj(txnobj, &txn)) return NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001611
1612 CHECK_DB_NOT_CLOSED(self);
1613 if (!DBObject_Check(secondaryDB)) {
1614 makeTypeError("DB", (PyObject*)secondaryDB);
1615 return NULL;
1616 }
Gregory P. Smith91116b62005-06-06 10:28:06 +00001617 CHECK_DB_NOT_CLOSED(secondaryDB);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001618 if (callback == Py_None) {
1619 callback = NULL;
1620 }
1621 else if (!PyCallable_Check(callback)) {
1622 makeTypeError("Callable", callback);
1623 return NULL;
1624 }
1625
1626 /* Save a reference to the callback in the secondary DB. */
Thomas Woutersb3153832006-03-08 01:47:19 +00001627 Py_XINCREF(callback);
Serhiy Storchakabc62af12016-04-06 09:51:18 +03001628 Py_XSETREF(secondaryDB->associateCallback, callback);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001629 secondaryDB->primaryDBType = _DB_get_type(self);
1630
Martin v. Löwisb2c7aff2002-11-23 11:26:07 +00001631 /* PyEval_InitThreads is called here due to a quirk in python 1.5
1632 * - 2.2.1 (at least) according to Russell Williamson <merel@wt.net>:
1633 * The global interepreter lock is not initialized until the first
1634 * thread is created using thread.start_new_thread() or fork() is
1635 * called. that would cause the ALLOW_THREADS here to segfault due
1636 * to a null pointer reference if no threads or child processes
1637 * have been created. This works around that and is a no-op if
1638 * threads have already been initialized.
1639 * (see pybsddb-users mailing list post on 2002-08-07)
1640 */
Gregory P. Smithaa71f5f2003-01-17 07:56:16 +00001641#ifdef WITH_THREAD
Martin v. Löwisb2c7aff2002-11-23 11:26:07 +00001642 PyEval_InitThreads();
Gregory P. Smithaa71f5f2003-01-17 07:56:16 +00001643#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001644 MYDB_BEGIN_ALLOW_THREADS;
Barry Warsaw9a0d7792002-12-30 20:53:52 +00001645 err = self->db->associate(self->db,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001646 txn,
Barry Warsaw9a0d7792002-12-30 20:53:52 +00001647 secondaryDB->db,
1648 _db_associateCallback,
1649 flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001650 MYDB_END_ALLOW_THREADS;
1651
1652 if (err) {
Serhiy Storchaka98a97222014-02-09 13:14:04 +02001653 Py_CLEAR(secondaryDB->associateCallback);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001654 secondaryDB->primaryDBType = 0;
1655 }
1656
1657 RETURN_IF_ERR();
1658 RETURN_NONE();
1659}
1660
1661
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001662static PyObject*
Jesus Cea5cd5f122008-09-23 18:54:08 +00001663DB_close_internal(DBObject* self, int flags, int do_not_close)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001664{
Jesus Ceaef9764f2008-05-13 18:45:46 +00001665 PyObject *dummy;
Jesus Cea5cd5f122008-09-23 18:54:08 +00001666 int err = 0;
Jesus Ceaef9764f2008-05-13 18:45:46 +00001667
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001668 if (self->db != NULL) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00001669 /* Can be NULL if db is not in an environment */
1670 EXTRACT_FROM_DOUBLE_LINKED_LIST_MAYBE_NULL(self);
Jesus Cea4907d272008-08-31 14:00:51 +00001671
Jesus Ceaef9764f2008-05-13 18:45:46 +00001672 if (self->txn) {
1673 EXTRACT_FROM_DOUBLE_LINKED_LIST_TXN(self);
1674 self->txn=NULL;
1675 }
1676
1677 while(self->children_cursors) {
1678 dummy=DBC_close_internal(self->children_cursors);
1679 Py_XDECREF(dummy);
1680 }
1681
Jesus Ceaef9764f2008-05-13 18:45:46 +00001682 while(self->children_sequences) {
1683 dummy=DBSequence_close_internal(self->children_sequences,0,0);
1684 Py_XDECREF(dummy);
1685 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00001686
Jesus Cea5cd5f122008-09-23 18:54:08 +00001687 /*
1688 ** "do_not_close" is used to dispose all related objects in the
1689 ** tree, without actually releasing the "root" object.
1690 ** This is done, for example, because function calls like
1691 ** "DB.verify()" implicitly close the underlying handle. So
1692 ** the handle doesn't need to be closed, but related objects
1693 ** must be cleaned up.
1694 */
1695 if (!do_not_close) {
1696 MYDB_BEGIN_ALLOW_THREADS;
1697 err = self->db->close(self->db, flags);
1698 MYDB_END_ALLOW_THREADS;
1699 self->db = NULL;
1700 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001701 RETURN_IF_ERR();
1702 }
1703 RETURN_NONE();
1704}
1705
Jesus Ceaef9764f2008-05-13 18:45:46 +00001706static PyObject*
1707DB_close(DBObject* self, PyObject* args)
1708{
1709 int flags=0;
1710 if (!PyArg_ParseTuple(args,"|i:close", &flags))
1711 return NULL;
Jesus Cea5cd5f122008-09-23 18:54:08 +00001712 return DB_close_internal(self, flags, 0);
Jesus Ceaef9764f2008-05-13 18:45:46 +00001713}
1714
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001715
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001716static PyObject*
1717_DB_consume(DBObject* self, PyObject* args, PyObject* kwargs, int consume_flag)
1718{
1719 int err, flags=0, type;
1720 PyObject* txnobj = NULL;
1721 PyObject* retval = NULL;
1722 DBT key, data;
1723 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00001724 static char* kwnames[] = { "txn", "flags", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001725
1726 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Oi:consume", kwnames,
1727 &txnobj, &flags))
1728 return NULL;
1729
1730 CHECK_DB_NOT_CLOSED(self);
1731 type = _DB_get_type(self);
1732 if (type == -1)
1733 return NULL;
1734 if (type != DB_QUEUE) {
Barry Warsaw9a0d7792002-12-30 20:53:52 +00001735 PyErr_SetString(PyExc_TypeError,
1736 "Consume methods only allowed for Queue DB's");
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001737 return NULL;
1738 }
1739 if (!checkTxnObj(txnobj, &txn))
1740 return NULL;
1741
1742 CLEAR_DBT(key);
1743 CLEAR_DBT(data);
1744 if (CHECK_DBFLAG(self, DB_THREAD)) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00001745 /* Tell Berkeley DB to malloc the return value (thread safe) */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001746 data.flags = DB_DBT_MALLOC;
1747 key.flags = DB_DBT_MALLOC;
1748 }
1749
1750 MYDB_BEGIN_ALLOW_THREADS;
1751 err = self->db->get(self->db, txn, &key, &data, flags|consume_flag);
1752 MYDB_END_ALLOW_THREADS;
1753
Gregory P. Smithe9477062005-06-04 06:46:59 +00001754 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
Antoine Pitrouc83ea132010-05-09 14:46:46 +00001755 && self->moduleFlags.getReturnsNone) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001756 err = 0;
1757 Py_INCREF(Py_None);
1758 retval = Py_None;
1759 }
1760 else if (!err) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00001761 retval = BuildValue_SS(key.data, key.size, data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001762 FREE_DBT(key);
1763 FREE_DBT(data);
1764 }
1765
1766 RETURN_IF_ERR();
1767 return retval;
1768}
1769
1770static PyObject*
1771DB_consume(DBObject* self, PyObject* args, PyObject* kwargs, int consume_flag)
1772{
1773 return _DB_consume(self, args, kwargs, DB_CONSUME);
1774}
1775
1776static PyObject*
Barry Warsaw9a0d7792002-12-30 20:53:52 +00001777DB_consume_wait(DBObject* self, PyObject* args, PyObject* kwargs,
1778 int consume_flag)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001779{
1780 return _DB_consume(self, args, kwargs, DB_CONSUME_WAIT);
1781}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001782
1783
1784static PyObject*
1785DB_cursor(DBObject* self, PyObject* args, PyObject* kwargs)
1786{
1787 int err, flags=0;
1788 DBC* dbc;
1789 PyObject* txnobj = NULL;
1790 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00001791 static char* kwnames[] = { "txn", "flags", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001792
1793 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Oi:cursor", kwnames,
1794 &txnobj, &flags))
1795 return NULL;
1796 CHECK_DB_NOT_CLOSED(self);
1797 if (!checkTxnObj(txnobj, &txn))
1798 return NULL;
1799
1800 MYDB_BEGIN_ALLOW_THREADS;
1801 err = self->db->cursor(self->db, txn, &dbc, flags);
1802 MYDB_END_ALLOW_THREADS;
1803 RETURN_IF_ERR();
Jesus Ceaef9764f2008-05-13 18:45:46 +00001804 return (PyObject*) newDBCursorObject(dbc, (DBTxnObject *)txnobj, self);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001805}
1806
1807
1808static PyObject*
1809DB_delete(DBObject* self, PyObject* args, PyObject* kwargs)
1810{
1811 PyObject* txnobj = NULL;
1812 int flags = 0;
1813 PyObject* keyobj;
1814 DBT key;
1815 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00001816 static char* kwnames[] = { "key", "txn", "flags", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001817
1818 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|Oi:delete", kwnames,
1819 &keyobj, &txnobj, &flags))
1820 return NULL;
1821 CHECK_DB_NOT_CLOSED(self);
1822 if (!make_key_dbt(self, keyobj, &key, NULL))
1823 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00001824 if (!checkTxnObj(txnobj, &txn)) {
1825 FREE_DBT(key);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001826 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00001827 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001828
Gregory P. Smithdc5af702004-06-27 23:32:34 +00001829 if (-1 == _DB_delete(self, txn, &key, 0)) {
1830 FREE_DBT(key);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001831 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00001832 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001833
1834 FREE_DBT(key);
1835 RETURN_NONE();
1836}
1837
1838
Jesus Cea6557aac2010-03-22 14:22:26 +00001839#if (DBVER >= 47)
1840/*
1841** This function is available since Berkeley DB 4.4,
1842** but 4.6 version is so buggy that we only support
1843** it from BDB 4.7 and newer.
1844*/
1845static PyObject*
1846DB_compact(DBObject* self, PyObject* args, PyObject* kwargs)
1847{
1848 PyObject* txnobj = NULL;
1849 PyObject *startobj = NULL, *stopobj = NULL;
1850 int flags = 0;
1851 DB_TXN *txn = NULL;
1852 DBT *start_p = NULL, *stop_p = NULL;
1853 DBT start, stop;
1854 int err;
1855 DB_COMPACT c_data = { 0 };
1856 static char* kwnames[] = { "txn", "start", "stop", "flags",
1857 "compact_fillpercent", "compact_pages",
1858 "compact_timeout", NULL };
1859
1860
1861 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OOOiiiI:compact", kwnames,
1862 &txnobj, &startobj, &stopobj, &flags,
1863 &c_data.compact_fillpercent,
1864 &c_data.compact_pages,
1865 &c_data.compact_timeout))
1866 return NULL;
1867
1868 CHECK_DB_NOT_CLOSED(self);
1869 if (!checkTxnObj(txnobj, &txn)) {
1870 return NULL;
1871 }
1872
1873 if (startobj && make_key_dbt(self, startobj, &start, NULL)) {
1874 start_p = &start;
1875 }
1876 if (stopobj && make_key_dbt(self, stopobj, &stop, NULL)) {
1877 stop_p = &stop;
1878 }
1879
1880 MYDB_BEGIN_ALLOW_THREADS;
1881 err = self->db->compact(self->db, txn, start_p, stop_p, &c_data,
1882 flags, NULL);
1883 MYDB_END_ALLOW_THREADS;
1884
1885 if (startobj)
1886 FREE_DBT(start);
1887 if (stopobj)
1888 FREE_DBT(stop);
1889
1890 RETURN_IF_ERR();
1891
1892 return PyLong_FromUnsignedLong(c_data.compact_pages_truncated);
1893}
1894#endif
1895
1896
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001897static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00001898DB_fd(DBObject* self)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001899{
1900 int err, the_fd;
1901
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001902 CHECK_DB_NOT_CLOSED(self);
1903
1904 MYDB_BEGIN_ALLOW_THREADS;
1905 err = self->db->fd(self->db, &the_fd);
1906 MYDB_END_ALLOW_THREADS;
1907 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00001908 return NUMBER_FromLong(the_fd);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001909}
1910
1911
Jesus Cea6557aac2010-03-22 14:22:26 +00001912#if (DBVER >= 46)
1913static PyObject*
1914DB_exists(DBObject* self, PyObject* args, PyObject* kwargs)
1915{
1916 int err, flags=0;
1917 PyObject* txnobj = NULL;
1918 PyObject* keyobj;
1919 DBT key;
1920 DB_TXN *txn;
1921
1922 static char* kwnames[] = {"key", "txn", "flags", NULL};
1923
1924 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|Oi:exists", kwnames,
1925 &keyobj, &txnobj, &flags))
1926 return NULL;
1927
1928 CHECK_DB_NOT_CLOSED(self);
1929 if (!make_key_dbt(self, keyobj, &key, NULL))
1930 return NULL;
1931 if (!checkTxnObj(txnobj, &txn)) {
1932 FREE_DBT(key);
1933 return NULL;
1934 }
1935
1936 MYDB_BEGIN_ALLOW_THREADS;
1937 err = self->db->exists(self->db, txn, &key, flags);
1938 MYDB_END_ALLOW_THREADS;
1939
1940 FREE_DBT(key);
1941
1942 if (!err) {
1943 Py_INCREF(Py_True);
1944 return Py_True;
1945 }
1946 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)) {
1947 Py_INCREF(Py_False);
1948 return Py_False;
1949 }
1950
1951 /*
1952 ** If we reach there, there was an error. The
1953 ** "return" should be unreachable.
1954 */
1955 RETURN_IF_ERR();
1956 assert(0); /* This coude SHOULD be unreachable */
1957 return NULL;
1958}
1959#endif
1960
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001961static PyObject*
1962DB_get(DBObject* self, PyObject* args, PyObject* kwargs)
1963{
1964 int err, flags=0;
1965 PyObject* txnobj = NULL;
1966 PyObject* keyobj;
1967 PyObject* dfltobj = NULL;
1968 PyObject* retval = NULL;
1969 int dlen = -1;
1970 int doff = -1;
1971 DBT key, data;
1972 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00001973 static char* kwnames[] = {"key", "default", "txn", "flags", "dlen",
Jeremy Hyltonaf68c872005-12-10 18:50:16 +00001974 "doff", NULL};
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001975
1976 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|OOiii:get", kwnames,
Barry Warsaw9a0d7792002-12-30 20:53:52 +00001977 &keyobj, &dfltobj, &txnobj, &flags, &dlen,
1978 &doff))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001979 return NULL;
1980
1981 CHECK_DB_NOT_CLOSED(self);
1982 if (!make_key_dbt(self, keyobj, &key, &flags))
1983 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00001984 if (!checkTxnObj(txnobj, &txn)) {
1985 FREE_DBT(key);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001986 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00001987 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001988
1989 CLEAR_DBT(data);
1990 if (CHECK_DBFLAG(self, DB_THREAD)) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00001991 /* Tell Berkeley DB to malloc the return value (thread safe) */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001992 data.flags = DB_DBT_MALLOC;
1993 }
Gregory P. Smithdc5af702004-06-27 23:32:34 +00001994 if (!add_partial_dbt(&data, dlen, doff)) {
1995 FREE_DBT(key);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001996 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00001997 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00001998
1999 MYDB_BEGIN_ALLOW_THREADS;
2000 err = self->db->get(self->db, txn, &key, &data, flags);
2001 MYDB_END_ALLOW_THREADS;
2002
Gregory P. Smithe9477062005-06-04 06:46:59 +00002003 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY) && (dfltobj != NULL)) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002004 err = 0;
2005 Py_INCREF(dfltobj);
2006 retval = dfltobj;
2007 }
Gregory P. Smithe9477062005-06-04 06:46:59 +00002008 else if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002009 && self->moduleFlags.getReturnsNone) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002010 err = 0;
2011 Py_INCREF(Py_None);
2012 retval = Py_None;
2013 }
2014 else if (!err) {
2015 if (flags & DB_SET_RECNO) /* return both key and data */
Jesus Ceaef9764f2008-05-13 18:45:46 +00002016 retval = BuildValue_SS(key.data, key.size, data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002017 else /* return just the data */
Jesus Ceaef9764f2008-05-13 18:45:46 +00002018 retval = Build_PyString(data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002019 FREE_DBT(data);
2020 }
Gregory P. Smithdc5af702004-06-27 23:32:34 +00002021 FREE_DBT(key);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002022
2023 RETURN_IF_ERR();
2024 return retval;
2025}
2026
Gregory P. Smith19699a92004-06-28 04:06:49 +00002027static PyObject*
2028DB_pget(DBObject* self, PyObject* args, PyObject* kwargs)
2029{
2030 int err, flags=0;
2031 PyObject* txnobj = NULL;
2032 PyObject* keyobj;
2033 PyObject* dfltobj = NULL;
2034 PyObject* retval = NULL;
2035 int dlen = -1;
2036 int doff = -1;
2037 DBT key, pkey, data;
2038 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002039 static char* kwnames[] = {"key", "default", "txn", "flags", "dlen",
Jeremy Hyltonaf68c872005-12-10 18:50:16 +00002040 "doff", NULL};
Gregory P. Smith19699a92004-06-28 04:06:49 +00002041
2042 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|OOiii:pget", kwnames,
2043 &keyobj, &dfltobj, &txnobj, &flags, &dlen,
2044 &doff))
2045 return NULL;
2046
2047 CHECK_DB_NOT_CLOSED(self);
2048 if (!make_key_dbt(self, keyobj, &key, &flags))
2049 return NULL;
2050 if (!checkTxnObj(txnobj, &txn)) {
2051 FREE_DBT(key);
2052 return NULL;
2053 }
2054
2055 CLEAR_DBT(data);
2056 if (CHECK_DBFLAG(self, DB_THREAD)) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00002057 /* Tell Berkeley DB to malloc the return value (thread safe) */
Gregory P. Smith19699a92004-06-28 04:06:49 +00002058 data.flags = DB_DBT_MALLOC;
2059 }
2060 if (!add_partial_dbt(&data, dlen, doff)) {
2061 FREE_DBT(key);
2062 return NULL;
2063 }
2064
2065 CLEAR_DBT(pkey);
2066 pkey.flags = DB_DBT_MALLOC;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002067
Gregory P. Smith19699a92004-06-28 04:06:49 +00002068 MYDB_BEGIN_ALLOW_THREADS;
2069 err = self->db->pget(self->db, txn, &key, &pkey, &data, flags);
2070 MYDB_END_ALLOW_THREADS;
2071
Gregory P. Smithe9477062005-06-04 06:46:59 +00002072 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY) && (dfltobj != NULL)) {
Gregory P. Smith19699a92004-06-28 04:06:49 +00002073 err = 0;
2074 Py_INCREF(dfltobj);
2075 retval = dfltobj;
2076 }
Gregory P. Smithe9477062005-06-04 06:46:59 +00002077 else if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002078 && self->moduleFlags.getReturnsNone) {
Gregory P. Smith19699a92004-06-28 04:06:49 +00002079 err = 0;
2080 Py_INCREF(Py_None);
2081 retval = Py_None;
2082 }
2083 else if (!err) {
2084 PyObject *pkeyObj;
2085 PyObject *dataObj;
Jesus Ceaef9764f2008-05-13 18:45:46 +00002086 dataObj = Build_PyString(data.data, data.size);
Gregory P. Smith19699a92004-06-28 04:06:49 +00002087
2088 if (self->primaryDBType == DB_RECNO ||
2089 self->primaryDBType == DB_QUEUE)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002090 pkeyObj = NUMBER_FromLong(*(int *)pkey.data);
Gregory P. Smith19699a92004-06-28 04:06:49 +00002091 else
Jesus Ceaef9764f2008-05-13 18:45:46 +00002092 pkeyObj = Build_PyString(pkey.data, pkey.size);
Gregory P. Smith19699a92004-06-28 04:06:49 +00002093
2094 if (flags & DB_SET_RECNO) /* return key , pkey and data */
2095 {
2096 PyObject *keyObj;
2097 int type = _DB_get_type(self);
2098 if (type == DB_RECNO || type == DB_QUEUE)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002099 keyObj = NUMBER_FromLong(*(int *)key.data);
Gregory P. Smith19699a92004-06-28 04:06:49 +00002100 else
Jesus Ceaef9764f2008-05-13 18:45:46 +00002101 keyObj = Build_PyString(key.data, key.size);
Gregory P. Smith4e414d82006-01-24 19:55:02 +00002102 retval = PyTuple_Pack(3, keyObj, pkeyObj, dataObj);
Thomas Woutersb3153832006-03-08 01:47:19 +00002103 Py_DECREF(keyObj);
Gregory P. Smith19699a92004-06-28 04:06:49 +00002104 }
2105 else /* return just the pkey and data */
2106 {
Gregory P. Smith4e414d82006-01-24 19:55:02 +00002107 retval = PyTuple_Pack(2, pkeyObj, dataObj);
Gregory P. Smith19699a92004-06-28 04:06:49 +00002108 }
Thomas Woutersb3153832006-03-08 01:47:19 +00002109 Py_DECREF(dataObj);
2110 Py_DECREF(pkeyObj);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002111 FREE_DBT(pkey);
Gregory P. Smith19699a92004-06-28 04:06:49 +00002112 FREE_DBT(data);
2113 }
2114 FREE_DBT(key);
2115
2116 RETURN_IF_ERR();
2117 return retval;
2118}
2119
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002120
2121/* Return size of entry */
2122static PyObject*
2123DB_get_size(DBObject* self, PyObject* args, PyObject* kwargs)
2124{
2125 int err, flags=0;
2126 PyObject* txnobj = NULL;
2127 PyObject* keyobj;
2128 PyObject* retval = NULL;
2129 DBT key, data;
2130 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002131 static char* kwnames[] = { "key", "txn", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002132
2133 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O:get_size", kwnames,
2134 &keyobj, &txnobj))
2135 return NULL;
2136 CHECK_DB_NOT_CLOSED(self);
2137 if (!make_key_dbt(self, keyobj, &key, &flags))
2138 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00002139 if (!checkTxnObj(txnobj, &txn)) {
2140 FREE_DBT(key);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002141 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00002142 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002143 CLEAR_DBT(data);
2144
Gregory P. Smith8b7e9172004-12-13 09:51:23 +00002145 /* We don't allocate any memory, forcing a DB_BUFFER_SMALL error and
2146 thus getting the record size. */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002147 data.flags = DB_DBT_USERMEM;
2148 data.ulen = 0;
2149 MYDB_BEGIN_ALLOW_THREADS;
2150 err = self->db->get(self->db, txn, &key, &data, flags);
2151 MYDB_END_ALLOW_THREADS;
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07002152 if ((err == DB_BUFFER_SMALL) || (err == 0)) {
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002153 retval = NUMBER_FromLong((long)data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002154 err = 0;
2155 }
2156
2157 FREE_DBT(key);
2158 FREE_DBT(data);
2159 RETURN_IF_ERR();
2160 return retval;
2161}
2162
2163
2164static PyObject*
2165DB_get_both(DBObject* self, PyObject* args, PyObject* kwargs)
2166{
2167 int err, flags=0;
2168 PyObject* txnobj = NULL;
2169 PyObject* keyobj;
2170 PyObject* dataobj;
2171 PyObject* retval = NULL;
2172 DBT key, data;
Neal Norwitz994ebed2007-06-03 20:32:50 +00002173 void *orig_data;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002174 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002175 static char* kwnames[] = { "key", "data", "txn", "flags", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002176
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002177 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|Oi:get_both", kwnames,
2178 &keyobj, &dataobj, &txnobj, &flags))
2179 return NULL;
2180
2181 CHECK_DB_NOT_CLOSED(self);
2182 if (!make_key_dbt(self, keyobj, &key, NULL))
2183 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00002184 if ( !make_dbt(dataobj, &data) ||
2185 !checkTxnObj(txnobj, &txn) )
2186 {
2187 FREE_DBT(key);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002188 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00002189 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002190
2191 flags |= DB_GET_BOTH;
Neal Norwitz994ebed2007-06-03 20:32:50 +00002192 orig_data = data.data;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002193
2194 if (CHECK_DBFLAG(self, DB_THREAD)) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00002195 /* Tell Berkeley DB to malloc the return value (thread safe) */
Neal Norwitz994ebed2007-06-03 20:32:50 +00002196 /* XXX(nnorwitz): At least 4.4.20 and 4.5.20 require this flag. */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002197 data.flags = DB_DBT_MALLOC;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002198 }
2199
2200 MYDB_BEGIN_ALLOW_THREADS;
2201 err = self->db->get(self->db, txn, &key, &data, flags);
2202 MYDB_END_ALLOW_THREADS;
2203
Gregory P. Smithe9477062005-06-04 06:46:59 +00002204 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002205 && self->moduleFlags.getReturnsNone) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002206 err = 0;
2207 Py_INCREF(Py_None);
2208 retval = Py_None;
2209 }
2210 else if (!err) {
Neal Norwitz994ebed2007-06-03 20:32:50 +00002211 /* XXX(nnorwitz): can we do: retval = dataobj; Py_INCREF(retval); */
Jesus Ceaef9764f2008-05-13 18:45:46 +00002212 retval = Build_PyString(data.data, data.size);
Neal Norwitz994ebed2007-06-03 20:32:50 +00002213
2214 /* Even though the flags require DB_DBT_MALLOC, data is not always
2215 allocated. 4.4: allocated, 4.5: *not* allocated. :-( */
2216 if (data.data != orig_data)
2217 FREE_DBT(data);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002218 }
2219
2220 FREE_DBT(key);
2221 RETURN_IF_ERR();
2222 return retval;
2223}
2224
2225
2226static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002227DB_get_byteswapped(DBObject* self)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002228{
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002229 int err = 0;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002230 int retval = -1;
2231
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002232 CHECK_DB_NOT_CLOSED(self);
2233
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002234 MYDB_BEGIN_ALLOW_THREADS;
2235 err = self->db->get_byteswapped(self->db, &retval);
2236 MYDB_END_ALLOW_THREADS;
2237 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002238 return NUMBER_FromLong(retval);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002239}
2240
2241
2242static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002243DB_get_type(DBObject* self)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002244{
2245 int type;
2246
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002247 CHECK_DB_NOT_CLOSED(self);
2248
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002249 type = _DB_get_type(self);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002250 if (type == -1)
2251 return NULL;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002252 return NUMBER_FromLong(type);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002253}
2254
2255
2256static PyObject*
2257DB_join(DBObject* self, PyObject* args)
2258{
2259 int err, flags=0;
2260 int length, x;
2261 PyObject* cursorsObj;
2262 DBC** cursors;
2263 DBC* dbc;
2264
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002265 if (!PyArg_ParseTuple(args,"O|i:join", &cursorsObj, &flags))
2266 return NULL;
2267
2268 CHECK_DB_NOT_CLOSED(self);
2269
2270 if (!PySequence_Check(cursorsObj)) {
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002271 PyErr_SetString(PyExc_TypeError,
2272 "Sequence of DBCursor objects expected");
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002273 return NULL;
2274 }
2275
2276 length = PyObject_Length(cursorsObj);
2277 cursors = malloc((length+1) * sizeof(DBC*));
Neal Norwitz5aa96892006-08-13 18:11:43 +00002278 if (!cursors) {
Jesus Cea6557aac2010-03-22 14:22:26 +00002279 PyErr_NoMemory();
2280 return NULL;
Neal Norwitz5aa96892006-08-13 18:11:43 +00002281 }
2282
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002283 cursors[length] = NULL;
2284 for (x=0; x<length; x++) {
2285 PyObject* item = PySequence_GetItem(cursorsObj, x);
Thomas Woutersb3153832006-03-08 01:47:19 +00002286 if (item == NULL) {
2287 free(cursors);
2288 return NULL;
2289 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002290 if (!DBCursorObject_Check(item)) {
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002291 PyErr_SetString(PyExc_TypeError,
2292 "Sequence of DBCursor objects expected");
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002293 free(cursors);
2294 return NULL;
2295 }
2296 cursors[x] = ((DBCursorObject*)item)->dbc;
Thomas Woutersb2820ae2006-03-12 00:01:38 +00002297 Py_DECREF(item);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002298 }
2299
2300 MYDB_BEGIN_ALLOW_THREADS;
2301 err = self->db->join(self->db, cursors, &dbc, flags);
2302 MYDB_END_ALLOW_THREADS;
2303 free(cursors);
2304 RETURN_IF_ERR();
2305
Gregory P. Smith7441e652003-11-03 21:35:31 +00002306 /* FIXME: this is a buggy interface. The returned cursor
2307 contains internal references to the passed in cursors
2308 but does not hold python references to them or prevent
2309 them from being closed prematurely. This can cause
2310 python to crash when things are done in the wrong order. */
Jesus Ceaef9764f2008-05-13 18:45:46 +00002311 return (PyObject*) newDBCursorObject(dbc, NULL, self);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002312}
2313
2314
2315static PyObject*
2316DB_key_range(DBObject* self, PyObject* args, PyObject* kwargs)
2317{
2318 int err, flags=0;
2319 PyObject* txnobj = NULL;
2320 PyObject* keyobj;
2321 DBT key;
2322 DB_TXN *txn = NULL;
2323 DB_KEY_RANGE range;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002324 static char* kwnames[] = { "key", "txn", "flags", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002325
2326 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|Oi:key_range", kwnames,
2327 &keyobj, &txnobj, &flags))
2328 return NULL;
2329 CHECK_DB_NOT_CLOSED(self);
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002330 if (!make_dbt(keyobj, &key))
2331 /* BTree only, don't need to allow for an int key */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002332 return NULL;
2333 if (!checkTxnObj(txnobj, &txn))
2334 return NULL;
2335
2336 MYDB_BEGIN_ALLOW_THREADS;
2337 err = self->db->key_range(self->db, txn, &key, &range, flags);
2338 MYDB_END_ALLOW_THREADS;
2339
2340 RETURN_IF_ERR();
2341 return Py_BuildValue("ddd", range.less, range.equal, range.greater);
2342}
2343
2344
2345static PyObject*
2346DB_open(DBObject* self, PyObject* args, PyObject* kwargs)
2347{
2348 int err, type = DB_UNKNOWN, flags=0, mode=0660;
2349 char* filename = NULL;
2350 char* dbname = NULL;
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002351 PyObject *txnobj = NULL;
2352 DB_TXN *txn = NULL;
2353 /* with dbname */
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002354 static char* kwnames[] = {
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002355 "filename", "dbname", "dbtype", "flags", "mode", "txn", NULL};
2356 /* without dbname */
Tim Peters85b10522006-02-28 18:33:35 +00002357 static char* kwnames_basic[] = {
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002358 "filename", "dbtype", "flags", "mode", "txn", NULL};
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002359
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002360 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "z|ziiiO:open", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002361 &filename, &dbname, &type, &flags, &mode,
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002362 &txnobj))
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002363 {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002364 PyErr_Clear();
2365 type = DB_UNKNOWN; flags = 0; mode = 0660;
2366 filename = NULL; dbname = NULL;
2367 if (!PyArg_ParseTupleAndKeywords(args, kwargs,"z|iiiO:open",
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002368 kwnames_basic,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002369 &filename, &type, &flags, &mode,
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002370 &txnobj))
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002371 return NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002372 }
2373
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002374 if (!checkTxnObj(txnobj, &txn)) return NULL;
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002375
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002376 if (NULL == self->db) {
Thomas Woutersb3153832006-03-08 01:47:19 +00002377 PyObject *t = Py_BuildValue("(is)", 0,
2378 "Cannot call open() twice for DB object");
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002379 if (t) {
2380 PyErr_SetObject(DBError, t);
2381 Py_DECREF(t);
2382 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002383 return NULL;
2384 }
2385
Jesus Ceaef9764f2008-05-13 18:45:46 +00002386 if (txn) { /* Can't use 'txnobj' because could be 'txnobj==Py_None' */
2387 INSERT_IN_DOUBLE_LINKED_LIST_TXN(((DBTxnObject *)txnobj)->children_dbs,self);
2388 self->txn=(DBTxnObject *)txnobj;
2389 } else {
2390 self->txn=NULL;
2391 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00002392
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002393 MYDB_BEGIN_ALLOW_THREADS;
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002394 err = self->db->open(self->db, txn, filename, dbname, type, flags, mode);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002395 MYDB_END_ALLOW_THREADS;
Jesus Cea6557aac2010-03-22 14:22:26 +00002396
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002397 if (makeDBError(err)) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00002398 PyObject *dummy;
2399
Jesus Cea5cd5f122008-09-23 18:54:08 +00002400 dummy=DB_close_internal(self, 0, 0);
Jesus Ceaef9764f2008-05-13 18:45:46 +00002401 Py_XDECREF(dummy);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002402 return NULL;
2403 }
2404
Gregory P. Smithec10a4a2007-11-05 02:32:26 +00002405 self->db->get_flags(self->db, &self->setflags);
2406
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002407 self->flags = flags;
Jesus Ceaef9764f2008-05-13 18:45:46 +00002408
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002409 RETURN_NONE();
2410}
2411
2412
2413static PyObject*
2414DB_put(DBObject* self, PyObject* args, PyObject* kwargs)
2415{
2416 int flags=0;
2417 PyObject* txnobj = NULL;
2418 int dlen = -1;
2419 int doff = -1;
2420 PyObject* keyobj, *dataobj, *retval;
2421 DBT key, data;
2422 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002423 static char* kwnames[] = { "key", "data", "txn", "flags", "dlen",
Jeremy Hyltonaf68c872005-12-10 18:50:16 +00002424 "doff", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002425
2426 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|Oiii:put", kwnames,
2427 &keyobj, &dataobj, &txnobj, &flags, &dlen, &doff))
2428 return NULL;
2429
2430 CHECK_DB_NOT_CLOSED(self);
Gregory P. Smithdc5af702004-06-27 23:32:34 +00002431 if (!make_key_dbt(self, keyobj, &key, NULL))
2432 return NULL;
2433 if ( !make_dbt(dataobj, &data) ||
2434 !add_partial_dbt(&data, dlen, doff) ||
2435 !checkTxnObj(txnobj, &txn) )
2436 {
2437 FREE_DBT(key);
2438 return NULL;
2439 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002440
2441 if (-1 == _DB_put(self, txn, &key, &data, flags)) {
2442 FREE_DBT(key);
2443 return NULL;
2444 }
2445
2446 if (flags & DB_APPEND)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002447 retval = NUMBER_FromLong(*((db_recno_t*)key.data));
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002448 else {
2449 retval = Py_None;
2450 Py_INCREF(retval);
2451 }
2452 FREE_DBT(key);
2453 return retval;
2454}
2455
2456
2457
2458static PyObject*
2459DB_remove(DBObject* self, PyObject* args, PyObject* kwargs)
2460{
2461 char* filename;
2462 char* database = NULL;
2463 int err, flags=0;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00002464 static char* kwnames[] = { "filename", "dbname", "flags", NULL};
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002465
2466 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|zi:remove", kwnames,
2467 &filename, &database, &flags))
2468 return NULL;
2469 CHECK_DB_NOT_CLOSED(self);
2470
Jesus Cea4907d272008-08-31 14:00:51 +00002471 EXTRACT_FROM_DOUBLE_LINKED_LIST_MAYBE_NULL(self);
2472
2473 MYDB_BEGIN_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002474 err = self->db->remove(self->db, filename, database, flags);
Jesus Cea4907d272008-08-31 14:00:51 +00002475 MYDB_END_ALLOW_THREADS;
2476
Gregory P. Smithf655dff2003-05-15 00:13:18 +00002477 self->db = NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002478 RETURN_IF_ERR();
2479 RETURN_NONE();
2480}
2481
2482
2483
2484static PyObject*
2485DB_rename(DBObject* self, PyObject* args)
2486{
2487 char* filename;
2488 char* database;
2489 char* newname;
2490 int err, flags=0;
2491
Barry Warsaw9a0d7792002-12-30 20:53:52 +00002492 if (!PyArg_ParseTuple(args, "sss|i:rename", &filename, &database, &newname,
2493 &flags))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002494 return NULL;
2495 CHECK_DB_NOT_CLOSED(self);
2496
2497 MYDB_BEGIN_ALLOW_THREADS;
2498 err = self->db->rename(self->db, filename, database, newname, flags);
2499 MYDB_END_ALLOW_THREADS;
2500 RETURN_IF_ERR();
2501 RETURN_NONE();
2502}
2503
2504
2505static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002506DB_get_private(DBObject* self)
2507{
2508 /* We can give out the private field even if db is closed */
Jesus Cea4907d272008-08-31 14:00:51 +00002509 Py_INCREF(self->private_obj);
2510 return self->private_obj;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002511}
2512
2513static PyObject*
Jesus Cea4907d272008-08-31 14:00:51 +00002514DB_set_private(DBObject* self, PyObject* private_obj)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002515{
2516 /* We can set the private field even if db is closed */
Jesus Cea4907d272008-08-31 14:00:51 +00002517 Py_INCREF(private_obj);
Serhiy Storchaka763a61c2016-04-10 18:05:12 +03002518 Py_SETREF(self->private_obj, private_obj);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002519 RETURN_NONE();
2520}
2521
Jesus Cea6557aac2010-03-22 14:22:26 +00002522#if (DBVER >= 46)
2523static PyObject*
2524DB_set_priority(DBObject* self, PyObject* args)
2525{
2526 int err, priority;
2527
2528 if (!PyArg_ParseTuple(args,"i:set_priority", &priority))
2529 return NULL;
2530 CHECK_DB_NOT_CLOSED(self);
2531
2532 MYDB_BEGIN_ALLOW_THREADS;
2533 err = self->db->set_priority(self->db, priority);
2534 MYDB_END_ALLOW_THREADS;
2535 RETURN_IF_ERR();
2536 RETURN_NONE();
2537}
2538
2539static PyObject*
2540DB_get_priority(DBObject* self)
2541{
2542 int err = 0;
2543 DB_CACHE_PRIORITY priority;
2544
2545 CHECK_DB_NOT_CLOSED(self);
2546
2547 MYDB_BEGIN_ALLOW_THREADS;
2548 err = self->db->get_priority(self->db, &priority);
2549 MYDB_END_ALLOW_THREADS;
2550 RETURN_IF_ERR();
2551 return NUMBER_FromLong(priority);
2552}
2553#endif
2554
2555static PyObject*
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07002556DB_get_dbname(DBObject* self)
2557{
2558 int err;
2559 const char *filename, *dbname;
2560
2561 CHECK_DB_NOT_CLOSED(self);
2562
2563 MYDB_BEGIN_ALLOW_THREADS;
2564 err = self->db->get_dbname(self->db, &filename, &dbname);
2565 MYDB_END_ALLOW_THREADS;
2566 RETURN_IF_ERR();
2567 /* If "dbname==NULL", it is correctly converted to "None" */
2568 return Py_BuildValue("(ss)", filename, dbname);
2569}
2570
2571static PyObject*
2572DB_get_open_flags(DBObject* self)
2573{
2574 int err;
2575 unsigned int flags;
2576
2577 CHECK_DB_NOT_CLOSED(self);
2578
2579 MYDB_BEGIN_ALLOW_THREADS;
2580 err = self->db->get_open_flags(self->db, &flags);
2581 MYDB_END_ALLOW_THREADS;
2582 RETURN_IF_ERR();
2583 return NUMBER_FromLong(flags);
2584}
2585
2586static PyObject*
Jesus Cea6557aac2010-03-22 14:22:26 +00002587DB_set_q_extentsize(DBObject* self, PyObject* args)
2588{
2589 int err;
2590 u_int32_t extentsize;
2591
2592 if (!PyArg_ParseTuple(args,"i:set_q_extentsize", &extentsize))
2593 return NULL;
2594 CHECK_DB_NOT_CLOSED(self);
2595
2596 MYDB_BEGIN_ALLOW_THREADS;
2597 err = self->db->set_q_extentsize(self->db, extentsize);
2598 MYDB_END_ALLOW_THREADS;
2599 RETURN_IF_ERR();
2600 RETURN_NONE();
2601}
2602
Jesus Cea6557aac2010-03-22 14:22:26 +00002603static PyObject*
2604DB_get_q_extentsize(DBObject* self)
2605{
2606 int err = 0;
2607 u_int32_t extentsize;
2608
2609 CHECK_DB_NOT_CLOSED(self);
2610
2611 MYDB_BEGIN_ALLOW_THREADS;
2612 err = self->db->get_q_extentsize(self->db, &extentsize);
2613 MYDB_END_ALLOW_THREADS;
2614 RETURN_IF_ERR();
2615 return NUMBER_FromLong(extentsize);
2616}
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002617
2618static PyObject*
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002619DB_set_bt_minkey(DBObject* self, PyObject* args)
2620{
2621 int err, minkey;
2622
Jesus Cea6557aac2010-03-22 14:22:26 +00002623 if (!PyArg_ParseTuple(args,"i:set_bt_minkey", &minkey))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002624 return NULL;
2625 CHECK_DB_NOT_CLOSED(self);
2626
2627 MYDB_BEGIN_ALLOW_THREADS;
2628 err = self->db->set_bt_minkey(self->db, minkey);
2629 MYDB_END_ALLOW_THREADS;
2630 RETURN_IF_ERR();
2631 RETURN_NONE();
2632}
2633
Jesus Cea6557aac2010-03-22 14:22:26 +00002634static PyObject*
2635DB_get_bt_minkey(DBObject* self)
2636{
2637 int err;
2638 u_int32_t bt_minkey;
2639
2640 CHECK_DB_NOT_CLOSED(self);
2641
2642 MYDB_BEGIN_ALLOW_THREADS;
2643 err = self->db->get_bt_minkey(self->db, &bt_minkey);
2644 MYDB_END_ALLOW_THREADS;
2645 RETURN_IF_ERR();
2646 return NUMBER_FromLong(bt_minkey);
2647}
Jesus Cea6557aac2010-03-22 14:22:26 +00002648
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002649static int
Georg Brandlef1701f2006-03-07 14:57:48 +00002650_default_cmp(const DBT *leftKey,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002651 const DBT *rightKey)
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002652{
2653 int res;
2654 int lsize = leftKey->size, rsize = rightKey->size;
2655
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002656 res = memcmp(leftKey->data, rightKey->data,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002657 lsize < rsize ? lsize : rsize);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002658
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002659 if (res == 0) {
2660 if (lsize < rsize) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002661 res = -1;
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002662 }
2663 else if (lsize > rsize) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002664 res = 1;
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002665 }
2666 }
2667 return res;
2668}
2669
2670static int
Jesus Ceaef9764f2008-05-13 18:45:46 +00002671_db_compareCallback(DB* db,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002672 const DBT *leftKey,
2673 const DBT *rightKey)
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002674{
2675 int res = 0;
2676 PyObject *args;
Thomas Woutersb2820ae2006-03-12 00:01:38 +00002677 PyObject *result = NULL;
Georg Brandlef1701f2006-03-07 14:57:48 +00002678 DBObject *self = (DBObject *)db->app_private;
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002679
2680 if (self == NULL || self->btCompareCallback == NULL) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002681 MYDB_BEGIN_BLOCK_THREADS;
2682 PyErr_SetString(PyExc_TypeError,
2683 (self == 0
2684 ? "DB_bt_compare db is NULL."
2685 : "DB_bt_compare callback is NULL."));
2686 /* we're in a callback within the DB code, we can't raise */
2687 PyErr_Print();
2688 res = _default_cmp(leftKey, rightKey);
2689 MYDB_END_BLOCK_THREADS;
Georg Brandlef1701f2006-03-07 14:57:48 +00002690 } else {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002691 MYDB_BEGIN_BLOCK_THREADS;
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002692
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002693 args = BuildValue_SS(leftKey->data, leftKey->size, rightKey->data, rightKey->size);
2694 if (args != NULL) {
2695 result = PyEval_CallObject(self->btCompareCallback, args);
2696 }
2697 if (args == NULL || result == NULL) {
2698 /* we're in a callback within the DB code, we can't raise */
2699 PyErr_Print();
2700 res = _default_cmp(leftKey, rightKey);
2701 } else if (NUMBER_Check(result)) {
2702 res = NUMBER_AsLong(result);
2703 } else {
2704 PyErr_SetString(PyExc_TypeError,
2705 "DB_bt_compare callback MUST return an int.");
2706 /* we're in a callback within the DB code, we can't raise */
2707 PyErr_Print();
2708 res = _default_cmp(leftKey, rightKey);
2709 }
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002710
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002711 Py_XDECREF(args);
2712 Py_XDECREF(result);
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002713
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002714 MYDB_END_BLOCK_THREADS;
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002715 }
2716 return res;
2717}
2718
2719static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002720DB_set_bt_compare(DBObject* self, PyObject* comparator)
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002721{
2722 int err;
Thomas Woutersb3153832006-03-08 01:47:19 +00002723 PyObject *tuple, *result;
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002724
Georg Brandlef1701f2006-03-07 14:57:48 +00002725 CHECK_DB_NOT_CLOSED(self);
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002726
Georg Brandlef1701f2006-03-07 14:57:48 +00002727 if (!PyCallable_Check(comparator)) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002728 makeTypeError("Callable", comparator);
2729 return NULL;
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002730 }
2731
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002732 /*
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002733 * Perform a test call of the comparator function with two empty
2734 * string objects here. verify that it returns an int (0).
2735 * err if not.
2736 */
Thomas Woutersb3153832006-03-08 01:47:19 +00002737 tuple = Py_BuildValue("(ss)", "", "");
Georg Brandlef1701f2006-03-07 14:57:48 +00002738 result = PyEval_CallObject(comparator, tuple);
2739 Py_DECREF(tuple);
Thomas Woutersb3153832006-03-08 01:47:19 +00002740 if (result == NULL)
2741 return NULL;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002742 if (!NUMBER_Check(result)) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002743 Py_DECREF(result);
2744 PyErr_SetString(PyExc_TypeError,
2745 "callback MUST return an int");
2746 return NULL;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00002747 } else if (NUMBER_AsLong(result) != 0) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002748 Py_DECREF(result);
2749 PyErr_SetString(PyExc_TypeError,
2750 "callback failed to return 0 on two empty strings");
2751 return NULL;
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002752 }
Thomas Woutersb3153832006-03-08 01:47:19 +00002753 Py_DECREF(result);
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002754
2755 /* We don't accept multiple set_bt_compare operations, in order to
2756 * simplify the code. This would have no real use, as one cannot
2757 * change the function once the db is opened anyway */
2758 if (self->btCompareCallback != NULL) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002759 PyErr_SetString(PyExc_RuntimeError, "set_bt_compare() cannot be called more than once");
2760 return NULL;
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002761 }
2762
Georg Brandlef1701f2006-03-07 14:57:48 +00002763 Py_INCREF(comparator);
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002764 self->btCompareCallback = comparator;
2765
2766 /* This is to workaround a problem with un-initialized threads (see
2767 comment in DB_associate) */
2768#ifdef WITH_THREAD
2769 PyEval_InitThreads();
2770#endif
2771
Thomas Woutersb3153832006-03-08 01:47:19 +00002772 err = self->db->set_bt_compare(self->db, _db_compareCallback);
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002773
2774 if (err) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00002775 /* restore the old state in case of error */
2776 Py_DECREF(comparator);
2777 self->btCompareCallback = NULL;
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002778 }
2779
Georg Brandlef1701f2006-03-07 14:57:48 +00002780 RETURN_IF_ERR();
2781 RETURN_NONE();
Gregory P. Smithe4ed2de2005-06-03 07:03:07 +00002782}
2783
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07002784static int
2785_db_dupCompareCallback(DB* db,
2786 const DBT *leftKey,
2787 const DBT *rightKey)
2788{
2789 int res = 0;
2790 PyObject *args;
2791 PyObject *result = NULL;
2792 DBObject *self = (DBObject *)db->app_private;
2793
2794 if (self == NULL || self->dupCompareCallback == NULL) {
2795 MYDB_BEGIN_BLOCK_THREADS;
2796 PyErr_SetString(PyExc_TypeError,
2797 (self == 0
2798 ? "DB_dup_compare db is NULL."
2799 : "DB_dup_compare callback is NULL."));
2800 /* we're in a callback within the DB code, we can't raise */
2801 PyErr_Print();
2802 res = _default_cmp(leftKey, rightKey);
2803 MYDB_END_BLOCK_THREADS;
2804 } else {
2805 MYDB_BEGIN_BLOCK_THREADS;
2806
2807 args = BuildValue_SS(leftKey->data, leftKey->size, rightKey->data, rightKey->size);
2808 if (args != NULL) {
2809 result = PyEval_CallObject(self->dupCompareCallback, args);
2810 }
2811 if (args == NULL || result == NULL) {
2812 /* we're in a callback within the DB code, we can't raise */
2813 PyErr_Print();
2814 res = _default_cmp(leftKey, rightKey);
2815 } else if (NUMBER_Check(result)) {
2816 res = NUMBER_AsLong(result);
2817 } else {
2818 PyErr_SetString(PyExc_TypeError,
2819 "DB_dup_compare callback MUST return an int.");
2820 /* we're in a callback within the DB code, we can't raise */
2821 PyErr_Print();
2822 res = _default_cmp(leftKey, rightKey);
2823 }
2824
2825 Py_XDECREF(args);
2826 Py_XDECREF(result);
2827
2828 MYDB_END_BLOCK_THREADS;
2829 }
2830 return res;
2831}
2832
2833static PyObject*
2834DB_set_dup_compare(DBObject* self, PyObject* comparator)
2835{
2836 int err;
2837 PyObject *tuple, *result;
2838
2839 CHECK_DB_NOT_CLOSED(self);
2840
2841 if (!PyCallable_Check(comparator)) {
2842 makeTypeError("Callable", comparator);
2843 return NULL;
2844 }
2845
2846 /*
2847 * Perform a test call of the comparator function with two empty
2848 * string objects here. verify that it returns an int (0).
2849 * err if not.
2850 */
2851 tuple = Py_BuildValue("(ss)", "", "");
2852 result = PyEval_CallObject(comparator, tuple);
2853 Py_DECREF(tuple);
2854 if (result == NULL)
2855 return NULL;
2856 if (!NUMBER_Check(result)) {
2857 Py_DECREF(result);
2858 PyErr_SetString(PyExc_TypeError,
2859 "callback MUST return an int");
2860 return NULL;
2861 } else if (NUMBER_AsLong(result) != 0) {
2862 Py_DECREF(result);
2863 PyErr_SetString(PyExc_TypeError,
2864 "callback failed to return 0 on two empty strings");
2865 return NULL;
2866 }
2867 Py_DECREF(result);
2868
2869 /* We don't accept multiple set_dup_compare operations, in order to
2870 * simplify the code. This would have no real use, as one cannot
2871 * change the function once the db is opened anyway */
2872 if (self->dupCompareCallback != NULL) {
2873 PyErr_SetString(PyExc_RuntimeError, "set_dup_compare() cannot be called more than once");
2874 return NULL;
2875 }
2876
2877 Py_INCREF(comparator);
2878 self->dupCompareCallback = comparator;
2879
2880 /* This is to workaround a problem with un-initialized threads (see
2881 comment in DB_associate) */
2882#ifdef WITH_THREAD
2883 PyEval_InitThreads();
2884#endif
2885
2886 err = self->db->set_dup_compare(self->db, _db_dupCompareCallback);
2887
2888 if (err) {
2889 /* restore the old state in case of error */
2890 Py_DECREF(comparator);
2891 self->dupCompareCallback = NULL;
2892 }
2893
2894 RETURN_IF_ERR();
2895 RETURN_NONE();
2896}
2897
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002898
2899static PyObject*
2900DB_set_cachesize(DBObject* self, PyObject* args)
2901{
2902 int err;
2903 int gbytes = 0, bytes = 0, ncache = 0;
2904
2905 if (!PyArg_ParseTuple(args,"ii|i:set_cachesize",
2906 &gbytes,&bytes,&ncache))
2907 return NULL;
2908 CHECK_DB_NOT_CLOSED(self);
2909
2910 MYDB_BEGIN_ALLOW_THREADS;
2911 err = self->db->set_cachesize(self->db, gbytes, bytes, ncache);
2912 MYDB_END_ALLOW_THREADS;
2913 RETURN_IF_ERR();
2914 RETURN_NONE();
2915}
2916
Jesus Cea6557aac2010-03-22 14:22:26 +00002917static PyObject*
2918DB_get_cachesize(DBObject* self)
2919{
2920 int err;
2921 u_int32_t gbytes, bytes;
2922 int ncache;
2923
2924 CHECK_DB_NOT_CLOSED(self);
2925
2926 MYDB_BEGIN_ALLOW_THREADS;
2927 err = self->db->get_cachesize(self->db, &gbytes, &bytes, &ncache);
2928 MYDB_END_ALLOW_THREADS;
2929
2930 RETURN_IF_ERR();
2931
2932 return Py_BuildValue("(iii)", gbytes, bytes, ncache);
2933}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002934
2935static PyObject*
2936DB_set_flags(DBObject* self, PyObject* args)
2937{
2938 int err, flags;
2939
2940 if (!PyArg_ParseTuple(args,"i:set_flags", &flags))
2941 return NULL;
2942 CHECK_DB_NOT_CLOSED(self);
2943
2944 MYDB_BEGIN_ALLOW_THREADS;
2945 err = self->db->set_flags(self->db, flags);
2946 MYDB_END_ALLOW_THREADS;
2947 RETURN_IF_ERR();
2948
2949 self->setflags |= flags;
2950 RETURN_NONE();
2951}
2952
Jesus Cea6557aac2010-03-22 14:22:26 +00002953static PyObject*
2954DB_get_flags(DBObject* self)
2955{
2956 int err;
2957 u_int32_t flags;
2958
2959 CHECK_DB_NOT_CLOSED(self);
2960
2961 MYDB_BEGIN_ALLOW_THREADS;
2962 err = self->db->get_flags(self->db, &flags);
2963 MYDB_END_ALLOW_THREADS;
2964 RETURN_IF_ERR();
2965 return NUMBER_FromLong(flags);
2966}
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07002967
2968static PyObject*
2969DB_get_transactional(DBObject* self)
2970{
2971 int err;
2972
2973 CHECK_DB_NOT_CLOSED(self);
2974
2975 MYDB_BEGIN_ALLOW_THREADS;
2976 err = self->db->get_transactional(self->db);
2977 MYDB_END_ALLOW_THREADS;
2978
2979 if(err == 0) {
2980 Py_INCREF(Py_False);
2981 return Py_False;
2982 } else if(err == 1) {
2983 Py_INCREF(Py_True);
2984 return Py_True;
2985 }
2986
2987 /*
2988 ** If we reach there, there was an error. The
2989 ** "return" should be unreachable.
2990 */
2991 RETURN_IF_ERR();
2992 assert(0); /* This code SHOULD be unreachable */
2993 return NULL;
2994}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00002995
2996static PyObject*
2997DB_set_h_ffactor(DBObject* self, PyObject* args)
2998{
2999 int err, ffactor;
3000
3001 if (!PyArg_ParseTuple(args,"i:set_h_ffactor", &ffactor))
3002 return NULL;
3003 CHECK_DB_NOT_CLOSED(self);
3004
3005 MYDB_BEGIN_ALLOW_THREADS;
3006 err = self->db->set_h_ffactor(self->db, ffactor);
3007 MYDB_END_ALLOW_THREADS;
3008 RETURN_IF_ERR();
3009 RETURN_NONE();
3010}
3011
Jesus Cea6557aac2010-03-22 14:22:26 +00003012static PyObject*
3013DB_get_h_ffactor(DBObject* self)
3014{
3015 int err;
3016 u_int32_t ffactor;
3017
3018 CHECK_DB_NOT_CLOSED(self);
3019
3020 MYDB_BEGIN_ALLOW_THREADS;
3021 err = self->db->get_h_ffactor(self->db, &ffactor);
3022 MYDB_END_ALLOW_THREADS;
3023 RETURN_IF_ERR();
3024 return NUMBER_FromLong(ffactor);
3025}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003026
3027static PyObject*
3028DB_set_h_nelem(DBObject* self, PyObject* args)
3029{
3030 int err, nelem;
3031
3032 if (!PyArg_ParseTuple(args,"i:set_h_nelem", &nelem))
3033 return NULL;
3034 CHECK_DB_NOT_CLOSED(self);
3035
3036 MYDB_BEGIN_ALLOW_THREADS;
3037 err = self->db->set_h_nelem(self->db, nelem);
3038 MYDB_END_ALLOW_THREADS;
3039 RETURN_IF_ERR();
3040 RETURN_NONE();
3041}
3042
Jesus Cea6557aac2010-03-22 14:22:26 +00003043static PyObject*
3044DB_get_h_nelem(DBObject* self)
3045{
3046 int err;
3047 u_int32_t nelem;
3048
3049 CHECK_DB_NOT_CLOSED(self);
3050
3051 MYDB_BEGIN_ALLOW_THREADS;
3052 err = self->db->get_h_nelem(self->db, &nelem);
3053 MYDB_END_ALLOW_THREADS;
3054 RETURN_IF_ERR();
3055 return NUMBER_FromLong(nelem);
3056}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003057
3058static PyObject*
3059DB_set_lorder(DBObject* self, PyObject* args)
3060{
3061 int err, lorder;
3062
3063 if (!PyArg_ParseTuple(args,"i:set_lorder", &lorder))
3064 return NULL;
3065 CHECK_DB_NOT_CLOSED(self);
3066
3067 MYDB_BEGIN_ALLOW_THREADS;
3068 err = self->db->set_lorder(self->db, lorder);
3069 MYDB_END_ALLOW_THREADS;
3070 RETURN_IF_ERR();
3071 RETURN_NONE();
3072}
3073
Jesus Cea6557aac2010-03-22 14:22:26 +00003074static PyObject*
3075DB_get_lorder(DBObject* self)
3076{
3077 int err;
3078 int lorder;
3079
3080 CHECK_DB_NOT_CLOSED(self);
3081
3082 MYDB_BEGIN_ALLOW_THREADS;
3083 err = self->db->get_lorder(self->db, &lorder);
3084 MYDB_END_ALLOW_THREADS;
3085 RETURN_IF_ERR();
3086 return NUMBER_FromLong(lorder);
3087}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003088
3089static PyObject*
3090DB_set_pagesize(DBObject* self, PyObject* args)
3091{
3092 int err, pagesize;
3093
3094 if (!PyArg_ParseTuple(args,"i:set_pagesize", &pagesize))
3095 return NULL;
3096 CHECK_DB_NOT_CLOSED(self);
3097
3098 MYDB_BEGIN_ALLOW_THREADS;
3099 err = self->db->set_pagesize(self->db, pagesize);
3100 MYDB_END_ALLOW_THREADS;
3101 RETURN_IF_ERR();
3102 RETURN_NONE();
3103}
3104
Jesus Cea6557aac2010-03-22 14:22:26 +00003105static PyObject*
3106DB_get_pagesize(DBObject* self)
3107{
3108 int err;
3109 u_int32_t pagesize;
3110
3111 CHECK_DB_NOT_CLOSED(self);
3112
3113 MYDB_BEGIN_ALLOW_THREADS;
3114 err = self->db->get_pagesize(self->db, &pagesize);
3115 MYDB_END_ALLOW_THREADS;
3116 RETURN_IF_ERR();
3117 return NUMBER_FromLong(pagesize);
3118}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003119
3120static PyObject*
3121DB_set_re_delim(DBObject* self, PyObject* args)
3122{
3123 int err;
3124 char delim;
3125
3126 if (!PyArg_ParseTuple(args,"b:set_re_delim", &delim)) {
3127 PyErr_Clear();
3128 if (!PyArg_ParseTuple(args,"c:set_re_delim", &delim))
3129 return NULL;
3130 }
3131
3132 CHECK_DB_NOT_CLOSED(self);
3133
3134 MYDB_BEGIN_ALLOW_THREADS;
3135 err = self->db->set_re_delim(self->db, delim);
3136 MYDB_END_ALLOW_THREADS;
3137 RETURN_IF_ERR();
3138 RETURN_NONE();
3139}
3140
Jesus Cea6557aac2010-03-22 14:22:26 +00003141static PyObject*
3142DB_get_re_delim(DBObject* self)
3143{
3144 int err, re_delim;
3145
3146 CHECK_DB_NOT_CLOSED(self);
3147
3148 MYDB_BEGIN_ALLOW_THREADS;
3149 err = self->db->get_re_delim(self->db, &re_delim);
3150 MYDB_END_ALLOW_THREADS;
3151 RETURN_IF_ERR();
3152 return NUMBER_FromLong(re_delim);
3153}
Jesus Cea6557aac2010-03-22 14:22:26 +00003154
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003155static PyObject*
3156DB_set_re_len(DBObject* self, PyObject* args)
3157{
3158 int err, len;
3159
3160 if (!PyArg_ParseTuple(args,"i:set_re_len", &len))
3161 return NULL;
3162 CHECK_DB_NOT_CLOSED(self);
3163
3164 MYDB_BEGIN_ALLOW_THREADS;
3165 err = self->db->set_re_len(self->db, len);
3166 MYDB_END_ALLOW_THREADS;
3167 RETURN_IF_ERR();
3168 RETURN_NONE();
3169}
3170
Jesus Cea6557aac2010-03-22 14:22:26 +00003171static PyObject*
3172DB_get_re_len(DBObject* self)
3173{
3174 int err;
3175 u_int32_t re_len;
3176
3177 CHECK_DB_NOT_CLOSED(self);
3178
3179 MYDB_BEGIN_ALLOW_THREADS;
3180 err = self->db->get_re_len(self->db, &re_len);
3181 MYDB_END_ALLOW_THREADS;
3182 RETURN_IF_ERR();
3183 return NUMBER_FromLong(re_len);
3184}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003185
3186static PyObject*
3187DB_set_re_pad(DBObject* self, PyObject* args)
3188{
3189 int err;
3190 char pad;
3191
3192 if (!PyArg_ParseTuple(args,"b:set_re_pad", &pad)) {
3193 PyErr_Clear();
3194 if (!PyArg_ParseTuple(args,"c:set_re_pad", &pad))
3195 return NULL;
3196 }
3197 CHECK_DB_NOT_CLOSED(self);
3198
3199 MYDB_BEGIN_ALLOW_THREADS;
3200 err = self->db->set_re_pad(self->db, pad);
3201 MYDB_END_ALLOW_THREADS;
3202 RETURN_IF_ERR();
3203 RETURN_NONE();
3204}
3205
Jesus Cea6557aac2010-03-22 14:22:26 +00003206static PyObject*
3207DB_get_re_pad(DBObject* self)
3208{
3209 int err, re_pad;
3210
3211 CHECK_DB_NOT_CLOSED(self);
3212
3213 MYDB_BEGIN_ALLOW_THREADS;
3214 err = self->db->get_re_pad(self->db, &re_pad);
3215 MYDB_END_ALLOW_THREADS;
3216 RETURN_IF_ERR();
3217 return NUMBER_FromLong(re_pad);
3218}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003219
3220static PyObject*
3221DB_set_re_source(DBObject* self, PyObject* args)
3222{
3223 int err;
Jesus Cea6557aac2010-03-22 14:22:26 +00003224 char *source;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003225
Jesus Cea6557aac2010-03-22 14:22:26 +00003226 if (!PyArg_ParseTuple(args,"s:set_re_source", &source))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003227 return NULL;
3228 CHECK_DB_NOT_CLOSED(self);
3229
3230 MYDB_BEGIN_ALLOW_THREADS;
Jesus Cea6557aac2010-03-22 14:22:26 +00003231 err = self->db->set_re_source(self->db, source);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003232 MYDB_END_ALLOW_THREADS;
3233 RETURN_IF_ERR();
3234 RETURN_NONE();
3235}
3236
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003237static PyObject*
Jesus Cea6557aac2010-03-22 14:22:26 +00003238DB_get_re_source(DBObject* self)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003239{
3240 int err;
Jesus Cea6557aac2010-03-22 14:22:26 +00003241 const char *source;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003242
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003243 CHECK_DB_NOT_CLOSED(self);
3244
3245 MYDB_BEGIN_ALLOW_THREADS;
Jesus Cea6557aac2010-03-22 14:22:26 +00003246 err = self->db->get_re_source(self->db, &source);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003247 MYDB_END_ALLOW_THREADS;
3248 RETURN_IF_ERR();
Jesus Cea6557aac2010-03-22 14:22:26 +00003249 return PyBytes_FromString(source);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003250}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003251
3252static PyObject*
Gregory P. Smith8b7e9172004-12-13 09:51:23 +00003253DB_stat(DBObject* self, PyObject* args, PyObject* kwargs)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003254{
3255 int err, flags = 0, type;
3256 void* sp;
3257 PyObject* d;
Gregory P. Smith8b7e9172004-12-13 09:51:23 +00003258 PyObject* txnobj = NULL;
3259 DB_TXN *txn = NULL;
Gregory P. Smith2fa06792006-09-19 17:35:04 +00003260 static char* kwnames[] = { "flags", "txn", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003261
Gregory P. Smith8b7e9172004-12-13 09:51:23 +00003262 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|iO:stat", kwnames,
3263 &flags, &txnobj))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003264 return NULL;
Gregory P. Smith8b7e9172004-12-13 09:51:23 +00003265 if (!checkTxnObj(txnobj, &txn))
3266 return NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003267 CHECK_DB_NOT_CLOSED(self);
3268
3269 MYDB_BEGIN_ALLOW_THREADS;
Gregory P. Smith8b7e9172004-12-13 09:51:23 +00003270 err = self->db->stat(self->db, txn, &sp, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003271 MYDB_END_ALLOW_THREADS;
3272 RETURN_IF_ERR();
3273
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003274 /* Turn the stat structure into a dictionary */
3275 type = _DB_get_type(self);
3276 if ((type == -1) || ((d = PyDict_New()) == NULL)) {
3277 free(sp);
3278 return NULL;
3279 }
3280
3281#define MAKE_HASH_ENTRY(name) _addIntToDict(d, #name, ((DB_HASH_STAT*)sp)->hash_##name)
3282#define MAKE_BT_ENTRY(name) _addIntToDict(d, #name, ((DB_BTREE_STAT*)sp)->bt_##name)
3283#define MAKE_QUEUE_ENTRY(name) _addIntToDict(d, #name, ((DB_QUEUE_STAT*)sp)->qs_##name)
3284
3285 switch (type) {
3286 case DB_HASH:
3287 MAKE_HASH_ENTRY(magic);
3288 MAKE_HASH_ENTRY(version);
3289 MAKE_HASH_ENTRY(nkeys);
3290 MAKE_HASH_ENTRY(ndata);
Jesus Ceaef9764f2008-05-13 18:45:46 +00003291#if (DBVER >= 46)
3292 MAKE_HASH_ENTRY(pagecnt);
3293#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003294 MAKE_HASH_ENTRY(pagesize);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003295 MAKE_HASH_ENTRY(ffactor);
3296 MAKE_HASH_ENTRY(buckets);
3297 MAKE_HASH_ENTRY(free);
3298 MAKE_HASH_ENTRY(bfree);
3299 MAKE_HASH_ENTRY(bigpages);
3300 MAKE_HASH_ENTRY(big_bfree);
3301 MAKE_HASH_ENTRY(overflows);
3302 MAKE_HASH_ENTRY(ovfl_free);
3303 MAKE_HASH_ENTRY(dup);
3304 MAKE_HASH_ENTRY(dup_free);
3305 break;
3306
3307 case DB_BTREE:
3308 case DB_RECNO:
3309 MAKE_BT_ENTRY(magic);
3310 MAKE_BT_ENTRY(version);
3311 MAKE_BT_ENTRY(nkeys);
3312 MAKE_BT_ENTRY(ndata);
Jesus Ceaef9764f2008-05-13 18:45:46 +00003313#if (DBVER >= 46)
3314 MAKE_BT_ENTRY(pagecnt);
3315#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003316 MAKE_BT_ENTRY(pagesize);
3317 MAKE_BT_ENTRY(minkey);
3318 MAKE_BT_ENTRY(re_len);
3319 MAKE_BT_ENTRY(re_pad);
3320 MAKE_BT_ENTRY(levels);
3321 MAKE_BT_ENTRY(int_pg);
3322 MAKE_BT_ENTRY(leaf_pg);
3323 MAKE_BT_ENTRY(dup_pg);
3324 MAKE_BT_ENTRY(over_pg);
Jesus Ceaef9764f2008-05-13 18:45:46 +00003325 MAKE_BT_ENTRY(empty_pg);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003326 MAKE_BT_ENTRY(free);
3327 MAKE_BT_ENTRY(int_pgfree);
3328 MAKE_BT_ENTRY(leaf_pgfree);
3329 MAKE_BT_ENTRY(dup_pgfree);
3330 MAKE_BT_ENTRY(over_pgfree);
3331 break;
3332
3333 case DB_QUEUE:
3334 MAKE_QUEUE_ENTRY(magic);
3335 MAKE_QUEUE_ENTRY(version);
3336 MAKE_QUEUE_ENTRY(nkeys);
3337 MAKE_QUEUE_ENTRY(ndata);
3338 MAKE_QUEUE_ENTRY(pagesize);
Jesus Ceaef9764f2008-05-13 18:45:46 +00003339 MAKE_QUEUE_ENTRY(extentsize);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003340 MAKE_QUEUE_ENTRY(pages);
3341 MAKE_QUEUE_ENTRY(re_len);
3342 MAKE_QUEUE_ENTRY(re_pad);
3343 MAKE_QUEUE_ENTRY(pgfree);
3344#if (DBVER == 31)
3345 MAKE_QUEUE_ENTRY(start);
3346#endif
3347 MAKE_QUEUE_ENTRY(first_recno);
3348 MAKE_QUEUE_ENTRY(cur_recno);
3349 break;
3350
3351 default:
3352 PyErr_SetString(PyExc_TypeError, "Unknown DB type, unable to stat");
3353 Py_DECREF(d);
3354 d = NULL;
3355 }
3356
3357#undef MAKE_HASH_ENTRY
3358#undef MAKE_BT_ENTRY
3359#undef MAKE_QUEUE_ENTRY
3360
3361 free(sp);
3362 return d;
3363}
3364
Jesus Cea6557aac2010-03-22 14:22:26 +00003365static PyObject*
3366DB_stat_print(DBObject* self, PyObject* args, PyObject *kwargs)
3367{
3368 int err;
3369 int flags=0;
3370 static char* kwnames[] = { "flags", NULL };
3371
3372 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:stat_print",
3373 kwnames, &flags))
3374 {
3375 return NULL;
3376 }
3377 CHECK_DB_NOT_CLOSED(self);
3378 MYDB_BEGIN_ALLOW_THREADS;
3379 err = self->db->stat_print(self->db, flags);
3380 MYDB_END_ALLOW_THREADS;
3381 RETURN_IF_ERR();
3382 RETURN_NONE();
3383}
Jesus Cea6557aac2010-03-22 14:22:26 +00003384
3385
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003386static PyObject*
3387DB_sync(DBObject* self, PyObject* args)
3388{
3389 int err;
3390 int flags = 0;
3391
3392 if (!PyArg_ParseTuple(args,"|i:sync", &flags ))
3393 return NULL;
3394 CHECK_DB_NOT_CLOSED(self);
3395
3396 MYDB_BEGIN_ALLOW_THREADS;
3397 err = self->db->sync(self->db, flags);
3398 MYDB_END_ALLOW_THREADS;
3399 RETURN_IF_ERR();
3400 RETURN_NONE();
3401}
3402
3403
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003404static PyObject*
3405DB_truncate(DBObject* self, PyObject* args, PyObject* kwargs)
3406{
3407 int err, flags=0;
3408 u_int32_t count=0;
3409 PyObject* txnobj = NULL;
3410 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003411 static char* kwnames[] = { "txn", "flags", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003412
3413 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Oi:cursor", kwnames,
3414 &txnobj, &flags))
3415 return NULL;
3416 CHECK_DB_NOT_CLOSED(self);
3417 if (!checkTxnObj(txnobj, &txn))
3418 return NULL;
3419
3420 MYDB_BEGIN_ALLOW_THREADS;
3421 err = self->db->truncate(self->db, txn, &count, flags);
3422 MYDB_END_ALLOW_THREADS;
3423 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00003424 return NUMBER_FromLong(count);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003425}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003426
3427
3428static PyObject*
3429DB_upgrade(DBObject* self, PyObject* args)
3430{
3431 int err, flags=0;
3432 char *filename;
3433
3434 if (!PyArg_ParseTuple(args,"s|i:upgrade", &filename, &flags))
3435 return NULL;
3436 CHECK_DB_NOT_CLOSED(self);
3437
3438 MYDB_BEGIN_ALLOW_THREADS;
3439 err = self->db->upgrade(self->db, filename, flags);
3440 MYDB_END_ALLOW_THREADS;
3441 RETURN_IF_ERR();
3442 RETURN_NONE();
3443}
3444
3445
3446static PyObject*
3447DB_verify(DBObject* self, PyObject* args, PyObject* kwargs)
3448{
3449 int err, flags=0;
3450 char* fileName;
3451 char* dbName=NULL;
3452 char* outFileName=NULL;
3453 FILE* outFile=NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003454 static char* kwnames[] = { "filename", "dbname", "outfile", "flags",
Jeremy Hyltonaf68c872005-12-10 18:50:16 +00003455 NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003456
3457 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|zzi:verify", kwnames,
3458 &fileName, &dbName, &outFileName, &flags))
3459 return NULL;
3460
3461 CHECK_DB_NOT_CLOSED(self);
3462 if (outFileName)
3463 outFile = fopen(outFileName, "w");
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003464 /* XXX(nnorwitz): it should probably be an exception if outFile
3465 can't be opened. */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003466
Jesus Ceaef9764f2008-05-13 18:45:46 +00003467 { /* DB.verify acts as a DB handle destructor (like close) */
3468 PyObject *error;
3469
Jesus Cea5cd5f122008-09-23 18:54:08 +00003470 error=DB_close_internal(self, 0, 1);
Jesus Cea6557aac2010-03-22 14:22:26 +00003471 if (error) {
Serhiy Storchakaaffac002015-07-24 08:05:45 +03003472 if (outFile)
3473 fclose(outFile);
3474 return error;
Jesus Ceaef9764f2008-05-13 18:45:46 +00003475 }
Serhiy Storchakaaffac002015-07-24 08:05:45 +03003476 }
Gregory P. Smith41631e82003-09-21 00:08:14 +00003477
Jesus Cea5cd5f122008-09-23 18:54:08 +00003478 MYDB_BEGIN_ALLOW_THREADS;
3479 err = self->db->verify(self->db, fileName, dbName, outFile, flags);
3480 MYDB_END_ALLOW_THREADS;
3481
3482 self->db = NULL; /* Implicit close; related objects already released */
3483
3484 if (outFile)
3485 fclose(outFile);
3486
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003487 RETURN_IF_ERR();
3488 RETURN_NONE();
3489}
3490
3491
3492static PyObject*
3493DB_set_get_returns_none(DBObject* self, PyObject* args)
3494{
3495 int flags=0;
Gregory P. Smith455d46f2003-07-09 04:45:59 +00003496 int oldValue=0;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003497
3498 if (!PyArg_ParseTuple(args,"i:set_get_returns_none", &flags))
3499 return NULL;
3500 CHECK_DB_NOT_CLOSED(self);
3501
Gregory P. Smith455d46f2003-07-09 04:45:59 +00003502 if (self->moduleFlags.getReturnsNone)
3503 ++oldValue;
3504 if (self->moduleFlags.cursorSetReturnsNone)
3505 ++oldValue;
3506 self->moduleFlags.getReturnsNone = (flags >= 1);
3507 self->moduleFlags.cursorSetReturnsNone = (flags >= 2);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00003508 return NUMBER_FromLong(oldValue);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003509}
3510
Barry Warsaw9a0d7792002-12-30 20:53:52 +00003511static PyObject*
3512DB_set_encrypt(DBObject* self, PyObject* args, PyObject* kwargs)
3513{
3514 int err;
3515 u_int32_t flags=0;
3516 char *passwd = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00003517 static char* kwnames[] = { "passwd", "flags", NULL };
Barry Warsaw9a0d7792002-12-30 20:53:52 +00003518
3519 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|i:set_encrypt", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00003520 &passwd, &flags)) {
3521 return NULL;
Barry Warsaw9a0d7792002-12-30 20:53:52 +00003522 }
3523
3524 MYDB_BEGIN_ALLOW_THREADS;
3525 err = self->db->set_encrypt(self->db, passwd, flags);
3526 MYDB_END_ALLOW_THREADS;
3527
3528 RETURN_IF_ERR();
3529 RETURN_NONE();
3530}
Jesus Cea6557aac2010-03-22 14:22:26 +00003531
Jesus Cea6557aac2010-03-22 14:22:26 +00003532static PyObject*
3533DB_get_encrypt_flags(DBObject* self)
3534{
3535 int err;
3536 u_int32_t flags;
3537
3538 MYDB_BEGIN_ALLOW_THREADS;
3539 err = self->db->get_encrypt_flags(self->db, &flags);
3540 MYDB_END_ALLOW_THREADS;
3541
3542 RETURN_IF_ERR();
3543
3544 return NUMBER_FromLong(flags);
3545}
Jesus Cea6557aac2010-03-22 14:22:26 +00003546
Barry Warsaw9a0d7792002-12-30 20:53:52 +00003547
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003548
3549/*-------------------------------------------------------------- */
3550/* Mapping and Dictionary-like access routines */
3551
Martin v. Löwis70ee3cc2006-06-12 04:26:31 +00003552Py_ssize_t DB_length(PyObject* _self)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003553{
3554 int err;
Gregory P. Smith3c228b12006-06-05 23:59:37 +00003555 Py_ssize_t size = 0;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003556 void* sp;
Martin v. Löwis70ee3cc2006-06-12 04:26:31 +00003557 DBObject* self = (DBObject*)_self;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003558
3559 if (self->db == NULL) {
Thomas Woutersb3153832006-03-08 01:47:19 +00003560 PyObject *t = Py_BuildValue("(is)", 0, "DB object has been closed");
Jesus Ceac5a11fa2008-07-23 11:38:42 +00003561 if (t) {
3562 PyErr_SetObject(DBError, t);
3563 Py_DECREF(t);
3564 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003565 return -1;
3566 }
3567
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003568 MYDB_BEGIN_ALLOW_THREADS;
Jesus Cea6557aac2010-03-22 14:22:26 +00003569 err = self->db->stat(self->db, /*txnid*/ NULL, &sp, 0);
Jesus Cea6557aac2010-03-22 14:22:26 +00003570 MYDB_END_ALLOW_THREADS;
Gregory P. Smith3c228b12006-06-05 23:59:37 +00003571
3572 /* All the stat structures have matching fields upto the ndata field,
3573 so we can use any of them for the type cast */
3574 size = ((DB_BTREE_STAT*)sp)->bt_ndata;
3575
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003576 if (err)
3577 return -1;
3578
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003579 free(sp);
3580 return size;
3581}
3582
3583
3584PyObject* DB_subscript(DBObject* self, PyObject* keyobj)
3585{
3586 int err;
3587 PyObject* retval;
3588 DBT key;
3589 DBT data;
3590
3591 CHECK_DB_NOT_CLOSED(self);
3592 if (!make_key_dbt(self, keyobj, &key, NULL))
3593 return NULL;
3594
3595 CLEAR_DBT(data);
3596 if (CHECK_DBFLAG(self, DB_THREAD)) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00003597 /* Tell Berkeley DB to malloc the return value (thread safe) */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003598 data.flags = DB_DBT_MALLOC;
3599 }
3600 MYDB_BEGIN_ALLOW_THREADS;
3601 err = self->db->get(self->db, NULL, &key, &data, 0);
3602 MYDB_END_ALLOW_THREADS;
3603 if (err == DB_NOTFOUND || err == DB_KEYEMPTY) {
3604 PyErr_SetObject(PyExc_KeyError, keyobj);
3605 retval = NULL;
3606 }
3607 else if (makeDBError(err)) {
3608 retval = NULL;
3609 }
3610 else {
Jesus Ceaef9764f2008-05-13 18:45:46 +00003611 retval = Build_PyString(data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003612 FREE_DBT(data);
3613 }
3614
3615 FREE_DBT(key);
3616 return retval;
3617}
3618
3619
3620static int
3621DB_ass_sub(DBObject* self, PyObject* keyobj, PyObject* dataobj)
3622{
3623 DBT key, data;
3624 int retval;
3625 int flags = 0;
3626
3627 if (self->db == NULL) {
Thomas Woutersb3153832006-03-08 01:47:19 +00003628 PyObject *t = Py_BuildValue("(is)", 0, "DB object has been closed");
Jesus Ceac5a11fa2008-07-23 11:38:42 +00003629 if (t) {
3630 PyErr_SetObject(DBError, t);
3631 Py_DECREF(t);
3632 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003633 return -1;
3634 }
3635
3636 if (!make_key_dbt(self, keyobj, &key, NULL))
3637 return -1;
3638
3639 if (dataobj != NULL) {
3640 if (!make_dbt(dataobj, &data))
3641 retval = -1;
3642 else {
3643 if (self->setflags & (DB_DUP|DB_DUPSORT))
Barry Warsaw9a0d7792002-12-30 20:53:52 +00003644 /* dictionaries shouldn't have duplicate keys */
3645 flags = DB_NOOVERWRITE;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003646 retval = _DB_put(self, NULL, &key, &data, flags);
3647
3648 if ((retval == -1) && (self->setflags & (DB_DUP|DB_DUPSORT))) {
Barry Warsaw9a0d7792002-12-30 20:53:52 +00003649 /* try deleting any old record that matches and then PUT it
3650 * again... */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003651 _DB_delete(self, NULL, &key, 0);
3652 PyErr_Clear();
3653 retval = _DB_put(self, NULL, &key, &data, flags);
3654 }
3655 }
3656 }
3657 else {
3658 /* dataobj == NULL, so delete the key */
3659 retval = _DB_delete(self, NULL, &key, 0);
3660 }
3661 FREE_DBT(key);
3662 return retval;
3663}
3664
3665
3666static PyObject*
Jesus Cea6557aac2010-03-22 14:22:26 +00003667_DB_has_key(DBObject* self, PyObject* keyobj, PyObject* txnobj)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003668{
3669 int err;
Jesus Cea6557aac2010-03-22 14:22:26 +00003670 DBT key;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003671 DB_TXN *txn = NULL;
Jesus Cea4907d272008-08-31 14:00:51 +00003672
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003673 CHECK_DB_NOT_CLOSED(self);
3674 if (!make_key_dbt(self, keyobj, &key, NULL))
3675 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00003676 if (!checkTxnObj(txnobj, &txn)) {
3677 FREE_DBT(key);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003678 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00003679 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003680
Jesus Cea6557aac2010-03-22 14:22:26 +00003681#if (DBVER < 46)
Gregory P. Smith8b7e9172004-12-13 09:51:23 +00003682 /* This causes DB_BUFFER_SMALL to be returned when the db has the key because
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003683 it has a record but can't allocate a buffer for the data. This saves
3684 having to deal with data we won't be using.
3685 */
Jesus Cea6557aac2010-03-22 14:22:26 +00003686 {
3687 DBT data ;
3688 CLEAR_DBT(data);
3689 data.flags = DB_DBT_USERMEM;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003690
Jesus Cea6557aac2010-03-22 14:22:26 +00003691 MYDB_BEGIN_ALLOW_THREADS;
3692 err = self->db->get(self->db, txn, &key, &data, 0);
3693 MYDB_END_ALLOW_THREADS;
3694 }
3695#else
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003696 MYDB_BEGIN_ALLOW_THREADS;
Jesus Cea6557aac2010-03-22 14:22:26 +00003697 err = self->db->exists(self->db, txn, &key, 0);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003698 MYDB_END_ALLOW_THREADS;
Jesus Cea6557aac2010-03-22 14:22:26 +00003699#endif
3700
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003701 FREE_DBT(key);
Gregory P. Smithe9477062005-06-04 06:46:59 +00003702
Jesus Cea6557aac2010-03-22 14:22:26 +00003703 /*
3704 ** DB_BUFFER_SMALL is only used if we use "get".
3705 ** We can drop it when we only use "exists",
Martin Panter8d496ad2016-06-02 10:35:44 +00003706 ** when we drop support for Berkeley DB < 4.6.
Jesus Cea6557aac2010-03-22 14:22:26 +00003707 */
Gregory P. Smithe9477062005-06-04 06:46:59 +00003708 if (err == DB_BUFFER_SMALL || err == 0) {
Jesus Cea6557aac2010-03-22 14:22:26 +00003709 Py_INCREF(Py_True);
3710 return Py_True;
Gregory P. Smithe9477062005-06-04 06:46:59 +00003711 } else if (err == DB_NOTFOUND || err == DB_KEYEMPTY) {
Jesus Cea6557aac2010-03-22 14:22:26 +00003712 Py_INCREF(Py_False);
3713 return Py_False;
Gregory P. Smithe9477062005-06-04 06:46:59 +00003714 }
3715
3716 makeDBError(err);
3717 return NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003718}
3719
Jesus Cea6557aac2010-03-22 14:22:26 +00003720static PyObject*
3721DB_has_key(DBObject* self, PyObject* args, PyObject* kwargs)
3722{
3723 PyObject* keyobj;
3724 PyObject* txnobj = NULL;
3725 static char* kwnames[] = {"key","txn", NULL};
3726
3727 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O:has_key", kwnames,
3728 &keyobj, &txnobj))
3729 return NULL;
3730
3731 return _DB_has_key(self, keyobj, txnobj);
3732}
3733
3734
3735static int DB_contains(DBObject* self, PyObject* keyobj)
3736{
3737 PyObject* result;
3738 int result2 = 0;
3739
3740 result = _DB_has_key(self, keyobj, NULL) ;
3741 if (result == NULL) {
3742 return -1; /* Propague exception */
3743 }
3744 if (result != Py_False) {
3745 result2 = 1;
3746 }
3747
3748 Py_DECREF(result);
3749 return result2;
3750}
3751
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003752
3753#define _KEYS_LIST 1
3754#define _VALUES_LIST 2
3755#define _ITEMS_LIST 3
3756
3757static PyObject*
3758_DB_make_list(DBObject* self, DB_TXN* txn, int type)
3759{
3760 int err, dbtype;
3761 DBT key;
3762 DBT data;
3763 DBC *cursor;
3764 PyObject* list;
3765 PyObject* item = NULL;
3766
3767 CHECK_DB_NOT_CLOSED(self);
3768 CLEAR_DBT(key);
3769 CLEAR_DBT(data);
3770
3771 dbtype = _DB_get_type(self);
3772 if (dbtype == -1)
3773 return NULL;
3774
3775 list = PyList_New(0);
Thomas Woutersb3153832006-03-08 01:47:19 +00003776 if (list == NULL)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003777 return NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003778
3779 /* get a cursor */
3780 MYDB_BEGIN_ALLOW_THREADS;
Gregory P. Smith442c9fc2004-09-04 01:36:59 +00003781 err = self->db->cursor(self->db, txn, &cursor, 0);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003782 MYDB_END_ALLOW_THREADS;
Thomas Woutersb3153832006-03-08 01:47:19 +00003783 if (makeDBError(err)) {
3784 Py_DECREF(list);
3785 return NULL;
3786 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003787
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003788 while (1) { /* use the cursor to traverse the DB, collecting items */
3789 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00003790 err = _DBC_get(cursor, &key, &data, DB_NEXT);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003791 MYDB_END_ALLOW_THREADS;
3792
3793 if (err) {
3794 /* for any error, break out of the loop */
3795 break;
3796 }
3797
3798 switch (type) {
3799 case _KEYS_LIST:
3800 switch(dbtype) {
3801 case DB_BTREE:
3802 case DB_HASH:
3803 default:
Jesus Ceaef9764f2008-05-13 18:45:46 +00003804 item = Build_PyString(key.data, key.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003805 break;
3806 case DB_RECNO:
3807 case DB_QUEUE:
Jesus Ceac5a11fa2008-07-23 11:38:42 +00003808 item = NUMBER_FromLong(*((db_recno_t*)key.data));
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003809 break;
3810 }
3811 break;
3812
3813 case _VALUES_LIST:
Jesus Ceaef9764f2008-05-13 18:45:46 +00003814 item = Build_PyString(data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003815 break;
3816
3817 case _ITEMS_LIST:
3818 switch(dbtype) {
3819 case DB_BTREE:
3820 case DB_HASH:
3821 default:
Jesus Ceaef9764f2008-05-13 18:45:46 +00003822 item = BuildValue_SS(key.data, key.size, data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003823 break;
3824 case DB_RECNO:
3825 case DB_QUEUE:
Jesus Ceaef9764f2008-05-13 18:45:46 +00003826 item = BuildValue_IS(*((db_recno_t*)key.data), data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003827 break;
3828 }
3829 break;
Thomas Woutersb3153832006-03-08 01:47:19 +00003830 default:
3831 PyErr_Format(PyExc_ValueError, "Unknown key type 0x%x", type);
3832 item = NULL;
3833 break;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003834 }
3835 if (item == NULL) {
3836 Py_DECREF(list);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003837 list = NULL;
3838 goto done;
3839 }
Jesus Ceac5a11fa2008-07-23 11:38:42 +00003840 if (PyList_Append(list, item)) {
3841 Py_DECREF(list);
3842 Py_DECREF(item);
3843 list = NULL;
3844 goto done;
3845 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003846 Py_DECREF(item);
3847 }
3848
Gregory P. Smithe9477062005-06-04 06:46:59 +00003849 /* DB_NOTFOUND || DB_KEYEMPTY is okay, it means we got to the end */
3850 if (err != DB_NOTFOUND && err != DB_KEYEMPTY && makeDBError(err)) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003851 Py_DECREF(list);
3852 list = NULL;
3853 }
3854
3855 done:
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003856 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00003857 _DBC_close(cursor);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003858 MYDB_END_ALLOW_THREADS;
3859 return list;
3860}
3861
3862
3863static PyObject*
3864DB_keys(DBObject* self, PyObject* args)
3865{
3866 PyObject* txnobj = NULL;
3867 DB_TXN *txn = NULL;
3868
Georg Brandl96a8c392006-05-29 21:04:52 +00003869 if (!PyArg_UnpackTuple(args, "keys", 0, 1, &txnobj))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003870 return NULL;
3871 if (!checkTxnObj(txnobj, &txn))
3872 return NULL;
3873 return _DB_make_list(self, txn, _KEYS_LIST);
3874}
3875
3876
3877static PyObject*
3878DB_items(DBObject* self, PyObject* args)
3879{
3880 PyObject* txnobj = NULL;
3881 DB_TXN *txn = NULL;
3882
Georg Brandl96a8c392006-05-29 21:04:52 +00003883 if (!PyArg_UnpackTuple(args, "items", 0, 1, &txnobj))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003884 return NULL;
3885 if (!checkTxnObj(txnobj, &txn))
3886 return NULL;
3887 return _DB_make_list(self, txn, _ITEMS_LIST);
3888}
3889
3890
3891static PyObject*
3892DB_values(DBObject* self, PyObject* args)
3893{
3894 PyObject* txnobj = NULL;
3895 DB_TXN *txn = NULL;
3896
Georg Brandl96a8c392006-05-29 21:04:52 +00003897 if (!PyArg_UnpackTuple(args, "values", 0, 1, &txnobj))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003898 return NULL;
3899 if (!checkTxnObj(txnobj, &txn))
3900 return NULL;
3901 return _DB_make_list(self, txn, _VALUES_LIST);
3902}
3903
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00003904/* --------------------------------------------------------------------- */
Jesus Cea6557aac2010-03-22 14:22:26 +00003905/* DBLogCursor methods */
3906
3907
3908static PyObject*
3909DBLogCursor_close_internal(DBLogCursorObject* self)
3910{
3911 int err = 0;
3912
3913 if (self->logc != NULL) {
3914 EXTRACT_FROM_DOUBLE_LINKED_LIST(self);
3915
3916 MYDB_BEGIN_ALLOW_THREADS;
3917 err = self->logc->close(self->logc, 0);
3918 MYDB_END_ALLOW_THREADS;
3919 self->logc = NULL;
3920 }
3921 RETURN_IF_ERR();
3922 RETURN_NONE();
3923}
3924
3925static PyObject*
3926DBLogCursor_close(DBLogCursorObject* self)
3927{
3928 return DBLogCursor_close_internal(self);
3929}
3930
3931
3932static PyObject*
3933_DBLogCursor_get(DBLogCursorObject* self, int flag, DB_LSN *lsn2)
3934{
3935 int err;
3936 DBT data;
3937 DB_LSN lsn = {0, 0};
3938 PyObject *dummy, *retval;
3939
3940 CLEAR_DBT(data);
3941 data.flags = DB_DBT_MALLOC; /* Berkeley DB must do the malloc */
3942
3943 CHECK_LOGCURSOR_NOT_CLOSED(self);
3944
3945 if (lsn2)
3946 lsn = *lsn2;
3947
3948 MYDB_BEGIN_ALLOW_THREADS;
3949 err = self->logc->get(self->logc, &lsn, &data, flag);
3950 MYDB_END_ALLOW_THREADS;
3951
3952 if (err == DB_NOTFOUND) {
3953 Py_INCREF(Py_None);
3954 retval = Py_None;
3955 }
3956 else if (makeDBError(err)) {
3957 retval = NULL;
3958 }
3959 else {
3960 retval = dummy = BuildValue_S(data.data, data.size);
3961 if (dummy) {
3962 retval = Py_BuildValue("(ii)O", lsn.file, lsn.offset, dummy);
3963 Py_DECREF(dummy);
3964 }
3965 }
3966
3967 FREE_DBT(data);
3968 return retval;
3969}
3970
3971static PyObject*
3972DBLogCursor_current(DBLogCursorObject* self)
3973{
3974 return _DBLogCursor_get(self, DB_CURRENT, NULL);
3975}
3976
3977static PyObject*
3978DBLogCursor_first(DBLogCursorObject* self)
3979{
3980 return _DBLogCursor_get(self, DB_FIRST, NULL);
3981}
3982
3983static PyObject*
3984DBLogCursor_last(DBLogCursorObject* self)
3985{
3986 return _DBLogCursor_get(self, DB_LAST, NULL);
3987}
3988
3989static PyObject*
3990DBLogCursor_next(DBLogCursorObject* self)
3991{
3992 return _DBLogCursor_get(self, DB_NEXT, NULL);
3993}
3994
3995static PyObject*
3996DBLogCursor_prev(DBLogCursorObject* self)
3997{
3998 return _DBLogCursor_get(self, DB_PREV, NULL);
3999}
4000
4001static PyObject*
4002DBLogCursor_set(DBLogCursorObject* self, PyObject* args)
4003{
4004 DB_LSN lsn;
4005
4006 if (!PyArg_ParseTuple(args, "(ii):set", &lsn.file, &lsn.offset))
4007 return NULL;
4008
4009 return _DBLogCursor_get(self, DB_SET, &lsn);
4010}
4011
4012
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07004013/* --------------------------------------------------------------------- */
4014/* DBSite methods */
4015
4016
4017#if (DBVER >= 52)
4018static PyObject*
4019DBSite_close_internal(DBSiteObject* self)
4020{
4021 int err = 0;
4022
4023 if (self->site != NULL) {
4024 EXTRACT_FROM_DOUBLE_LINKED_LIST(self);
4025
4026 MYDB_BEGIN_ALLOW_THREADS;
4027 err = self->site->close(self->site);
4028 MYDB_END_ALLOW_THREADS;
4029 self->site = NULL;
4030 }
4031 RETURN_IF_ERR();
4032 RETURN_NONE();
4033}
4034
4035static PyObject*
4036DBSite_close(DBSiteObject* self)
4037{
4038 return DBSite_close_internal(self);
4039}
4040
4041static PyObject*
4042DBSite_remove(DBSiteObject* self)
4043{
4044 int err = 0;
4045
4046 CHECK_SITE_NOT_CLOSED(self);
4047
4048 MYDB_BEGIN_ALLOW_THREADS;
4049 err = self->site->remove(self->site);
4050 MYDB_END_ALLOW_THREADS;
4051
4052 RETURN_IF_ERR();
4053 RETURN_NONE();
4054}
4055
4056static PyObject*
4057DBSite_get_eid(DBSiteObject* self)
4058{
4059 int err = 0;
4060 int eid;
4061
4062 CHECK_SITE_NOT_CLOSED(self);
4063
4064 MYDB_BEGIN_ALLOW_THREADS;
4065 err = self->site->get_eid(self->site, &eid);
4066 MYDB_END_ALLOW_THREADS;
4067
4068 RETURN_IF_ERR();
4069 return NUMBER_FromLong(eid);
4070}
4071
4072static PyObject*
4073DBSite_get_address(DBSiteObject* self)
4074{
4075 int err = 0;
4076 const char *host;
4077 u_int port;
4078
4079 CHECK_SITE_NOT_CLOSED(self);
4080
4081 MYDB_BEGIN_ALLOW_THREADS;
4082 err = self->site->get_address(self->site, &host, &port);
4083 MYDB_END_ALLOW_THREADS;
4084
4085 RETURN_IF_ERR();
4086
4087 return Py_BuildValue("(sI)", host, port);
4088}
4089
4090static PyObject*
4091DBSite_get_config(DBSiteObject* self, PyObject* args, PyObject* kwargs)
4092{
4093 int err = 0;
4094 u_int32_t which, value;
4095 static char* kwnames[] = { "which", NULL };
4096
4097 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i:get_config", kwnames,
4098 &which))
4099 return NULL;
4100
4101 CHECK_SITE_NOT_CLOSED(self);
4102
4103 MYDB_BEGIN_ALLOW_THREADS;
4104 err = self->site->get_config(self->site, which, &value);
4105 MYDB_END_ALLOW_THREADS;
4106
4107 RETURN_IF_ERR();
4108
4109 if (value) {
4110 Py_INCREF(Py_True);
4111 return Py_True;
4112 } else {
4113 Py_INCREF(Py_False);
4114 return Py_False;
4115 }
4116}
4117
4118static PyObject*
4119DBSite_set_config(DBSiteObject* self, PyObject* args, PyObject* kwargs)
4120{
4121 int err = 0;
4122 u_int32_t which, value;
4123 PyObject *valueO;
4124 static char* kwnames[] = { "which", "value", NULL };
4125
4126 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "iO:set_config", kwnames,
4127 &which, &valueO))
4128 return NULL;
4129
4130 CHECK_SITE_NOT_CLOSED(self);
4131
4132 value = PyObject_IsTrue(valueO);
4133
4134 MYDB_BEGIN_ALLOW_THREADS;
4135 err = self->site->set_config(self->site, which, value);
4136 MYDB_END_ALLOW_THREADS;
4137
4138 RETURN_IF_ERR();
4139 RETURN_NONE();
4140}
4141#endif
4142
Jesus Cea6557aac2010-03-22 14:22:26 +00004143
4144/* --------------------------------------------------------------------- */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004145/* DBCursor methods */
4146
4147
4148static PyObject*
Jesus Ceaef9764f2008-05-13 18:45:46 +00004149DBC_close_internal(DBCursorObject* self)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004150{
4151 int err = 0;
4152
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004153 if (self->dbc != NULL) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00004154 EXTRACT_FROM_DOUBLE_LINKED_LIST(self);
4155 if (self->txn) {
4156 EXTRACT_FROM_DOUBLE_LINKED_LIST_TXN(self);
4157 self->txn=NULL;
4158 }
4159
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004160 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004161 err = _DBC_close(self->dbc);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004162 MYDB_END_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004163 self->dbc = NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004164 }
4165 RETURN_IF_ERR();
4166 RETURN_NONE();
4167}
4168
Jesus Ceaef9764f2008-05-13 18:45:46 +00004169static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00004170DBC_close(DBCursorObject* self)
Jesus Ceaef9764f2008-05-13 18:45:46 +00004171{
Jesus Ceaef9764f2008-05-13 18:45:46 +00004172 return DBC_close_internal(self);
4173}
4174
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004175
4176static PyObject*
4177DBC_count(DBCursorObject* self, PyObject* args)
4178{
4179 int err = 0;
4180 db_recno_t count;
4181 int flags = 0;
4182
4183 if (!PyArg_ParseTuple(args, "|i:count", &flags))
4184 return NULL;
4185
4186 CHECK_CURSOR_NOT_CLOSED(self);
4187
4188 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004189 err = _DBC_count(self->dbc, &count, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004190 MYDB_END_ALLOW_THREADS;
4191 RETURN_IF_ERR();
4192
Jesus Ceac5a11fa2008-07-23 11:38:42 +00004193 return NUMBER_FromLong(count);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004194}
4195
4196
4197static PyObject*
4198DBC_current(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4199{
4200 return _DBCursor_get(self,DB_CURRENT,args,kwargs,"|iii:current");
4201}
4202
4203
4204static PyObject*
4205DBC_delete(DBCursorObject* self, PyObject* args)
4206{
4207 int err, flags=0;
4208
4209 if (!PyArg_ParseTuple(args, "|i:delete", &flags))
4210 return NULL;
4211
4212 CHECK_CURSOR_NOT_CLOSED(self);
4213
4214 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004215 err = _DBC_del(self->dbc, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004216 MYDB_END_ALLOW_THREADS;
4217 RETURN_IF_ERR();
4218
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004219 RETURN_NONE();
4220}
4221
4222
4223static PyObject*
4224DBC_dup(DBCursorObject* self, PyObject* args)
4225{
4226 int err, flags =0;
4227 DBC* dbc = NULL;
4228
4229 if (!PyArg_ParseTuple(args, "|i:dup", &flags))
4230 return NULL;
4231
4232 CHECK_CURSOR_NOT_CLOSED(self);
4233
4234 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004235 err = _DBC_dup(self->dbc, &dbc, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004236 MYDB_END_ALLOW_THREADS;
4237 RETURN_IF_ERR();
4238
Jesus Ceaef9764f2008-05-13 18:45:46 +00004239 return (PyObject*) newDBCursorObject(dbc, self->txn, self->mydb);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004240}
4241
4242static PyObject*
4243DBC_first(DBCursorObject* self, PyObject* args, PyObject* kwargs)
4244{
4245 return _DBCursor_get(self,DB_FIRST,args,kwargs,"|iii:first");
4246}
4247
4248
4249static PyObject*
4250DBC_get(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4251{
Martin v. Löwisb2c7aff2002-11-23 11:26:07 +00004252 int err, flags=0;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004253 PyObject* keyobj = NULL;
4254 PyObject* dataobj = NULL;
4255 PyObject* retval = NULL;
4256 int dlen = -1;
4257 int doff = -1;
4258 DBT key, data;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00004259 static char* kwnames[] = { "key","data", "flags", "dlen", "doff",
Jeremy Hyltonaf68c872005-12-10 18:50:16 +00004260 NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004261
4262 CLEAR_DBT(key);
4263 CLEAR_DBT(data);
4264 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|ii:get", &kwnames[2],
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004265 &flags, &dlen, &doff))
Barry Warsaw9a0d7792002-12-30 20:53:52 +00004266 {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004267 PyErr_Clear();
Barry Warsaw9a0d7792002-12-30 20:53:52 +00004268 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Oi|ii:get",
Jesus Cea4907d272008-08-31 14:00:51 +00004269 &kwnames[1],
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004270 &keyobj, &flags, &dlen, &doff))
Barry Warsaw9a0d7792002-12-30 20:53:52 +00004271 {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004272 PyErr_Clear();
Barry Warsaw9a0d7792002-12-30 20:53:52 +00004273 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OOi|ii:get",
4274 kwnames, &keyobj, &dataobj,
4275 &flags, &dlen, &doff))
4276 {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004277 return NULL;
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004278 }
4279 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004280 }
4281
4282 CHECK_CURSOR_NOT_CLOSED(self);
4283
4284 if (keyobj && !make_key_dbt(self->mydb, keyobj, &key, NULL))
4285 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004286 if ( (dataobj && !make_dbt(dataobj, &data)) ||
4287 (!add_partial_dbt(&data, dlen, doff)) )
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 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004291 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004292
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004293 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004294 err = _DBC_get(self->dbc, &key, &data, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004295 MYDB_END_ALLOW_THREADS;
4296
Gregory P. Smithe9477062005-06-04 06:46:59 +00004297 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004298 && self->mydb->moduleFlags.getReturnsNone) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004299 Py_INCREF(Py_None);
4300 retval = Py_None;
4301 }
4302 else if (makeDBError(err)) {
4303 retval = NULL;
4304 }
4305 else {
4306 switch (_DB_get_type(self->mydb)) {
4307 case -1:
4308 retval = NULL;
4309 break;
4310 case DB_BTREE:
4311 case DB_HASH:
4312 default:
Jesus Ceaef9764f2008-05-13 18:45:46 +00004313 retval = BuildValue_SS(key.data, key.size, data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004314 break;
4315 case DB_RECNO:
4316 case DB_QUEUE:
Jesus Ceaef9764f2008-05-13 18:45:46 +00004317 retval = BuildValue_IS(*((db_recno_t*)key.data), data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004318 break;
4319 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004320 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00004321 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004322 return retval;
4323}
4324
Gregory P. Smith19699a92004-06-28 04:06:49 +00004325static PyObject*
4326DBC_pget(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4327{
4328 int err, flags=0;
4329 PyObject* keyobj = NULL;
4330 PyObject* dataobj = NULL;
4331 PyObject* retval = NULL;
4332 int dlen = -1;
4333 int doff = -1;
4334 DBT key, pkey, data;
Gregory P. Smith372b5832006-06-05 18:48:21 +00004335 static char* kwnames_keyOnly[] = { "key", "flags", "dlen", "doff", NULL };
4336 static char* kwnames[] = { "key", "data", "flags", "dlen", "doff", NULL };
Gregory P. Smith19699a92004-06-28 04:06:49 +00004337
4338 CLEAR_DBT(key);
4339 CLEAR_DBT(data);
4340 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|ii:pget", &kwnames[2],
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004341 &flags, &dlen, &doff))
Gregory P. Smith19699a92004-06-28 04:06:49 +00004342 {
4343 PyErr_Clear();
4344 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "Oi|ii:pget",
Jesus Cea6557aac2010-03-22 14:22:26 +00004345 kwnames_keyOnly,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004346 &keyobj, &flags, &dlen, &doff))
Gregory P. Smith19699a92004-06-28 04:06:49 +00004347 {
4348 PyErr_Clear();
4349 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OOi|ii:pget",
4350 kwnames, &keyobj, &dataobj,
4351 &flags, &dlen, &doff))
4352 {
4353 return NULL;
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004354 }
4355 }
Gregory P. Smith19699a92004-06-28 04:06:49 +00004356 }
4357
4358 CHECK_CURSOR_NOT_CLOSED(self);
4359
4360 if (keyobj && !make_key_dbt(self->mydb, keyobj, &key, NULL))
4361 return NULL;
4362 if ( (dataobj && !make_dbt(dataobj, &data)) ||
4363 (!add_partial_dbt(&data, dlen, doff)) ) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00004364 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Gregory P. Smith19699a92004-06-28 04:06:49 +00004365 return NULL;
4366 }
4367
Gregory P. Smith19699a92004-06-28 04:06:49 +00004368 CLEAR_DBT(pkey);
4369 pkey.flags = DB_DBT_MALLOC;
4370
4371 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004372 err = _DBC_pget(self->dbc, &key, &pkey, &data, flags);
Gregory P. Smith19699a92004-06-28 04:06:49 +00004373 MYDB_END_ALLOW_THREADS;
4374
Gregory P. Smithe9477062005-06-04 06:46:59 +00004375 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004376 && self->mydb->moduleFlags.getReturnsNone) {
Gregory P. Smith19699a92004-06-28 04:06:49 +00004377 Py_INCREF(Py_None);
4378 retval = Py_None;
4379 }
4380 else if (makeDBError(err)) {
4381 retval = NULL;
4382 }
4383 else {
4384 PyObject *pkeyObj;
4385 PyObject *dataObj;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004386 dataObj = Build_PyString(data.data, data.size);
Gregory P. Smith19699a92004-06-28 04:06:49 +00004387
4388 if (self->mydb->primaryDBType == DB_RECNO ||
4389 self->mydb->primaryDBType == DB_QUEUE)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00004390 pkeyObj = NUMBER_FromLong(*(int *)pkey.data);
Gregory P. Smith19699a92004-06-28 04:06:49 +00004391 else
Jesus Ceaef9764f2008-05-13 18:45:46 +00004392 pkeyObj = Build_PyString(pkey.data, pkey.size);
Gregory P. Smith19699a92004-06-28 04:06:49 +00004393
Gregory P. Smith4e414d82006-01-24 19:55:02 +00004394 if (key.data && key.size) /* return key, pkey and data */
Gregory P. Smith19699a92004-06-28 04:06:49 +00004395 {
4396 PyObject *keyObj;
4397 int type = _DB_get_type(self->mydb);
4398 if (type == DB_RECNO || type == DB_QUEUE)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00004399 keyObj = NUMBER_FromLong(*(int *)key.data);
Gregory P. Smith19699a92004-06-28 04:06:49 +00004400 else
Jesus Ceaef9764f2008-05-13 18:45:46 +00004401 keyObj = Build_PyString(key.data, key.size);
Gregory P. Smith4e414d82006-01-24 19:55:02 +00004402 retval = PyTuple_Pack(3, keyObj, pkeyObj, dataObj);
Thomas Woutersb3153832006-03-08 01:47:19 +00004403 Py_DECREF(keyObj);
Jesus Ceaef9764f2008-05-13 18:45:46 +00004404 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Gregory P. Smith19699a92004-06-28 04:06:49 +00004405 }
4406 else /* return just the pkey and data */
4407 {
Gregory P. Smith4e414d82006-01-24 19:55:02 +00004408 retval = PyTuple_Pack(2, pkeyObj, dataObj);
Gregory P. Smith19699a92004-06-28 04:06:49 +00004409 }
Thomas Woutersb3153832006-03-08 01:47:19 +00004410 Py_DECREF(dataObj);
4411 Py_DECREF(pkeyObj);
Gregory P. Smith19699a92004-06-28 04:06:49 +00004412 FREE_DBT(pkey);
Gregory P. Smith19699a92004-06-28 04:06:49 +00004413 }
4414 /* the only time REALLOC should be set is if we used an integer
4415 * key that make_key_dbt malloc'd for us. always free these. */
Jesus Ceaef9764f2008-05-13 18:45:46 +00004416 if (key.flags & DB_DBT_REALLOC) { /* 'make_key_dbt' could do a 'malloc' */
Gregory P. Smith19699a92004-06-28 04:06:49 +00004417 FREE_DBT(key);
4418 }
4419 return retval;
4420}
4421
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004422
4423static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00004424DBC_get_recno(DBCursorObject* self)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004425{
4426 int err;
4427 db_recno_t recno;
4428 DBT key;
4429 DBT data;
4430
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004431 CHECK_CURSOR_NOT_CLOSED(self);
4432
4433 CLEAR_DBT(key);
4434 CLEAR_DBT(data);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004435
4436 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004437 err = _DBC_get(self->dbc, &key, &data, DB_GET_RECNO);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004438 MYDB_END_ALLOW_THREADS;
4439 RETURN_IF_ERR();
4440
4441 recno = *((db_recno_t*)data.data);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00004442 return NUMBER_FromLong(recno);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004443}
4444
4445
4446static PyObject*
4447DBC_last(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4448{
4449 return _DBCursor_get(self,DB_LAST,args,kwargs,"|iii:last");
4450}
4451
4452
4453static PyObject*
4454DBC_next(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4455{
4456 return _DBCursor_get(self,DB_NEXT,args,kwargs,"|iii:next");
4457}
4458
4459
4460static PyObject*
4461DBC_prev(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4462{
4463 return _DBCursor_get(self,DB_PREV,args,kwargs,"|iii:prev");
4464}
4465
4466
4467static PyObject*
4468DBC_put(DBCursorObject* self, PyObject* args, PyObject* kwargs)
4469{
4470 int err, flags = 0;
4471 PyObject* keyobj, *dataobj;
4472 DBT key, data;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00004473 static char* kwnames[] = { "key", "data", "flags", "dlen", "doff",
Jeremy Hyltonaf68c872005-12-10 18:50:16 +00004474 NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004475 int dlen = -1;
4476 int doff = -1;
4477
4478 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|iii:put", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004479 &keyobj, &dataobj, &flags, &dlen, &doff))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004480 return NULL;
4481
4482 CHECK_CURSOR_NOT_CLOSED(self);
4483
4484 if (!make_key_dbt(self->mydb, keyobj, &key, NULL))
4485 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004486 if (!make_dbt(dataobj, &data) ||
4487 !add_partial_dbt(&data, dlen, doff) )
4488 {
Jesus Ceaef9764f2008-05-13 18:45:46 +00004489 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004490 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004491 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004492
4493 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004494 err = _DBC_put(self->dbc, &key, &data, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004495 MYDB_END_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004496 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004497 RETURN_IF_ERR();
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004498 RETURN_NONE();
4499}
4500
4501
4502static PyObject*
4503DBC_set(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4504{
4505 int err, flags = 0;
4506 DBT key, data;
4507 PyObject* retval, *keyobj;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00004508 static char* kwnames[] = { "key", "flags", "dlen", "doff", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004509 int dlen = -1;
4510 int doff = -1;
4511
4512 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|iii:set", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004513 &keyobj, &flags, &dlen, &doff))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004514 return NULL;
4515
4516 CHECK_CURSOR_NOT_CLOSED(self);
4517
4518 if (!make_key_dbt(self->mydb, keyobj, &key, NULL))
4519 return NULL;
4520
4521 CLEAR_DBT(data);
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004522 if (!add_partial_dbt(&data, dlen, doff)) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00004523 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004524 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004525 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004526
4527 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004528 err = _DBC_get(self->dbc, &key, &data, flags|DB_SET);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004529 MYDB_END_ALLOW_THREADS;
Gregory P. Smithe9477062005-06-04 06:46:59 +00004530 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004531 && self->mydb->moduleFlags.cursorSetReturnsNone) {
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004532 Py_INCREF(Py_None);
4533 retval = Py_None;
4534 }
4535 else if (makeDBError(err)) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004536 retval = NULL;
4537 }
4538 else {
4539 switch (_DB_get_type(self->mydb)) {
4540 case -1:
4541 retval = NULL;
4542 break;
4543 case DB_BTREE:
4544 case DB_HASH:
4545 default:
Jesus Ceaef9764f2008-05-13 18:45:46 +00004546 retval = BuildValue_SS(key.data, key.size, data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004547 break;
4548 case DB_RECNO:
4549 case DB_QUEUE:
Jesus Ceaef9764f2008-05-13 18:45:46 +00004550 retval = BuildValue_IS(*((db_recno_t*)key.data), data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004551 break;
4552 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00004553 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004554 }
Gregory P. Smith19699a92004-06-28 04:06:49 +00004555 /* the only time REALLOC should be set is if we used an integer
4556 * key that make_key_dbt malloc'd for us. always free these. */
4557 if (key.flags & DB_DBT_REALLOC) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00004558 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Gregory P. Smith19699a92004-06-28 04:06:49 +00004559 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004560
4561 return retval;
4562}
4563
4564
4565static PyObject*
4566DBC_set_range(DBCursorObject* self, PyObject* args, PyObject* kwargs)
4567{
4568 int err, flags = 0;
4569 DBT key, data;
4570 PyObject* retval, *keyobj;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00004571 static char* kwnames[] = { "key", "flags", "dlen", "doff", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004572 int dlen = -1;
4573 int doff = -1;
4574
4575 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|iii:set_range", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004576 &keyobj, &flags, &dlen, &doff))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004577 return NULL;
4578
4579 CHECK_CURSOR_NOT_CLOSED(self);
4580
4581 if (!make_key_dbt(self->mydb, keyobj, &key, NULL))
4582 return NULL;
4583
4584 CLEAR_DBT(data);
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004585 if (!add_partial_dbt(&data, dlen, doff)) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00004586 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004587 return NULL;
4588 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004589 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004590 err = _DBC_get(self->dbc, &key, &data, flags|DB_SET_RANGE);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004591 MYDB_END_ALLOW_THREADS;
Gregory P. Smithe9477062005-06-04 06:46:59 +00004592 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004593 && self->mydb->moduleFlags.cursorSetReturnsNone) {
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004594 Py_INCREF(Py_None);
4595 retval = Py_None;
4596 }
4597 else if (makeDBError(err)) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004598 retval = NULL;
4599 }
4600 else {
4601 switch (_DB_get_type(self->mydb)) {
4602 case -1:
4603 retval = NULL;
4604 break;
4605 case DB_BTREE:
4606 case DB_HASH:
4607 default:
Jesus Ceaef9764f2008-05-13 18:45:46 +00004608 retval = BuildValue_SS(key.data, key.size, data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004609 break;
4610 case DB_RECNO:
4611 case DB_QUEUE:
Jesus Ceaef9764f2008-05-13 18:45:46 +00004612 retval = BuildValue_IS(*((db_recno_t*)key.data), data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004613 break;
4614 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00004615 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004616 }
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004617 /* the only time REALLOC should be set is if we used an integer
Gregory P. Smith19699a92004-06-28 04:06:49 +00004618 * key that make_key_dbt malloc'd for us. always free these. */
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004619 if (key.flags & DB_DBT_REALLOC) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00004620 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004621 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004622
4623 return retval;
4624}
4625
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004626static PyObject*
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004627_DBC_get_set_both(DBCursorObject* self, PyObject* keyobj, PyObject* dataobj,
4628 int flags, unsigned int returnsNone)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004629{
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004630 int err;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004631 DBT key, data;
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004632 PyObject* retval;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004633
Gregory P. Smith7441e652003-11-03 21:35:31 +00004634 /* the caller did this: CHECK_CURSOR_NOT_CLOSED(self); */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004635 if (!make_key_dbt(self->mydb, keyobj, &key, NULL))
4636 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004637 if (!make_dbt(dataobj, &data)) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00004638 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004639 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004640 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004641
4642 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004643 err = _DBC_get(self->dbc, &key, &data, flags|DB_GET_BOTH);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004644 MYDB_END_ALLOW_THREADS;
Gregory P. Smithe9477062005-06-04 06:46:59 +00004645 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY) && returnsNone) {
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004646 Py_INCREF(Py_None);
4647 retval = Py_None;
4648 }
4649 else if (makeDBError(err)) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004650 retval = NULL;
4651 }
4652 else {
4653 switch (_DB_get_type(self->mydb)) {
4654 case -1:
4655 retval = NULL;
4656 break;
4657 case DB_BTREE:
4658 case DB_HASH:
4659 default:
Jesus Ceaef9764f2008-05-13 18:45:46 +00004660 retval = BuildValue_SS(key.data, key.size, data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004661 break;
4662 case DB_RECNO:
4663 case DB_QUEUE:
Jesus Ceaef9764f2008-05-13 18:45:46 +00004664 retval = BuildValue_IS(*((db_recno_t*)key.data), data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004665 break;
4666 }
4667 }
4668
Jesus Ceaef9764f2008-05-13 18:45:46 +00004669 FREE_DBT(key); /* 'make_key_dbt' could do a 'malloc' */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004670 return retval;
4671}
4672
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004673static PyObject*
4674DBC_get_both(DBCursorObject* self, PyObject* args)
4675{
4676 int flags=0;
4677 PyObject *keyobj, *dataobj;
4678
4679 if (!PyArg_ParseTuple(args, "OO|i:get_both", &keyobj, &dataobj, &flags))
4680 return NULL;
4681
Gregory P. Smith7441e652003-11-03 21:35:31 +00004682 /* if the cursor is closed, self->mydb may be invalid */
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004683 CHECK_CURSOR_NOT_CLOSED(self);
4684
4685 return _DBC_get_set_both(self, keyobj, dataobj, flags,
4686 self->mydb->moduleFlags.getReturnsNone);
4687}
4688
Gregory P. Smithbe0db8b2003-10-01 06:48:51 +00004689/* Return size of entry */
4690static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00004691DBC_get_current_size(DBCursorObject* self)
Gregory P. Smithbe0db8b2003-10-01 06:48:51 +00004692{
4693 int err, flags=DB_CURRENT;
4694 PyObject* retval = NULL;
4695 DBT key, data;
4696
Gregory P. Smithbe0db8b2003-10-01 06:48:51 +00004697 CHECK_CURSOR_NOT_CLOSED(self);
4698 CLEAR_DBT(key);
4699 CLEAR_DBT(data);
4700
Gregory P. Smith8b7e9172004-12-13 09:51:23 +00004701 /* We don't allocate any memory, forcing a DB_BUFFER_SMALL error and thus
Gregory P. Smithbe0db8b2003-10-01 06:48:51 +00004702 getting the record size. */
4703 data.flags = DB_DBT_USERMEM;
4704 data.ulen = 0;
4705 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004706 err = _DBC_get(self->dbc, &key, &data, flags);
Gregory P. Smithbe0db8b2003-10-01 06:48:51 +00004707 MYDB_END_ALLOW_THREADS;
Gregory P. Smith8b7e9172004-12-13 09:51:23 +00004708 if (err == DB_BUFFER_SMALL || !err) {
4709 /* DB_BUFFER_SMALL means positive size, !err means zero length value */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00004710 retval = NUMBER_FromLong((long)data.size);
Gregory P. Smithbe0db8b2003-10-01 06:48:51 +00004711 err = 0;
4712 }
4713
Gregory P. Smithbe0db8b2003-10-01 06:48:51 +00004714 RETURN_IF_ERR();
4715 return retval;
4716}
4717
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004718static PyObject*
4719DBC_set_both(DBCursorObject* self, PyObject* args)
4720{
4721 int flags=0;
4722 PyObject *keyobj, *dataobj;
4723
4724 if (!PyArg_ParseTuple(args, "OO|i:set_both", &keyobj, &dataobj, &flags))
4725 return NULL;
4726
Gregory P. Smith7441e652003-11-03 21:35:31 +00004727 /* if the cursor is closed, self->mydb may be invalid */
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004728 CHECK_CURSOR_NOT_CLOSED(self);
4729
4730 return _DBC_get_set_both(self, keyobj, dataobj, flags,
4731 self->mydb->moduleFlags.cursorSetReturnsNone);
4732}
4733
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004734
4735static PyObject*
4736DBC_set_recno(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4737{
4738 int err, irecno, flags=0;
4739 db_recno_t recno;
4740 DBT key, data;
4741 PyObject* retval;
4742 int dlen = -1;
4743 int doff = -1;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00004744 static char* kwnames[] = { "recno","flags", "dlen", "doff", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004745
4746 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|iii:set_recno", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004747 &irecno, &flags, &dlen, &doff))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004748 return NULL;
4749
4750 CHECK_CURSOR_NOT_CLOSED(self);
4751
4752 CLEAR_DBT(key);
4753 recno = (db_recno_t) irecno;
Barry Warsaw9a0d7792002-12-30 20:53:52 +00004754 /* use allocated space so DB will be able to realloc room for the real
4755 * key */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004756 key.data = malloc(sizeof(db_recno_t));
4757 if (key.data == NULL) {
4758 PyErr_SetString(PyExc_MemoryError, "Key memory allocation failed");
4759 return NULL;
4760 }
4761 key.size = sizeof(db_recno_t);
4762 key.ulen = key.size;
4763 memcpy(key.data, &recno, sizeof(db_recno_t));
4764 key.flags = DB_DBT_REALLOC;
4765
4766 CLEAR_DBT(data);
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004767 if (!add_partial_dbt(&data, dlen, doff)) {
4768 FREE_DBT(key);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004769 return NULL;
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004770 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004771
4772 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004773 err = _DBC_get(self->dbc, &key, &data, flags|DB_SET_RECNO);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004774 MYDB_END_ALLOW_THREADS;
Gregory P. Smithe9477062005-06-04 06:46:59 +00004775 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004776 && self->mydb->moduleFlags.cursorSetReturnsNone) {
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004777 Py_INCREF(Py_None);
4778 retval = Py_None;
4779 }
4780 else if (makeDBError(err)) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004781 retval = NULL;
4782 }
4783 else { /* Can only be used for BTrees, so no need to return int key */
Jesus Ceaef9764f2008-05-13 18:45:46 +00004784 retval = BuildValue_SS(key.data, key.size, data.data, data.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004785 }
Gregory P. Smithdc5af702004-06-27 23:32:34 +00004786 FREE_DBT(key);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004787
4788 return retval;
4789}
4790
4791
4792static PyObject*
4793DBC_consume(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4794{
4795 return _DBCursor_get(self,DB_CONSUME,args,kwargs,"|iii:consume");
4796}
4797
4798
4799static PyObject*
4800DBC_next_dup(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4801{
4802 return _DBCursor_get(self,DB_NEXT_DUP,args,kwargs,"|iii:next_dup");
4803}
4804
4805
4806static PyObject*
4807DBC_next_nodup(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4808{
4809 return _DBCursor_get(self,DB_NEXT_NODUP,args,kwargs,"|iii:next_nodup");
4810}
4811
Jesus Cea6557aac2010-03-22 14:22:26 +00004812#if (DBVER >= 46)
4813static PyObject*
4814DBC_prev_dup(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4815{
4816 return _DBCursor_get(self,DB_PREV_DUP,args,kwargs,"|iii:prev_dup");
4817}
4818#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004819
4820static PyObject*
4821DBC_prev_nodup(DBCursorObject* self, PyObject* args, PyObject *kwargs)
4822{
4823 return _DBCursor_get(self,DB_PREV_NODUP,args,kwargs,"|iii:prev_nodup");
4824}
4825
4826
4827static PyObject*
4828DBC_join_item(DBCursorObject* self, PyObject* args)
4829{
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004830 int err, flags=0;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004831 DBT key, data;
4832 PyObject* retval;
4833
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004834 if (!PyArg_ParseTuple(args, "|i:join_item", &flags))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004835 return NULL;
4836
4837 CHECK_CURSOR_NOT_CLOSED(self);
4838
4839 CLEAR_DBT(key);
4840 CLEAR_DBT(data);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004841
4842 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00004843 err = _DBC_get(self->dbc, &key, &data, flags | DB_JOIN_ITEM);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004844 MYDB_END_ALLOW_THREADS;
Gregory P. Smithe9477062005-06-04 06:46:59 +00004845 if ((err == DB_NOTFOUND || err == DB_KEYEMPTY)
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004846 && self->mydb->moduleFlags.getReturnsNone) {
Gregory P. Smith455d46f2003-07-09 04:45:59 +00004847 Py_INCREF(Py_None);
4848 retval = Py_None;
4849 }
4850 else if (makeDBError(err)) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004851 retval = NULL;
4852 }
4853 else {
Jesus Ceaef9764f2008-05-13 18:45:46 +00004854 retval = BuildValue_S(key.data, key.size);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004855 }
4856
4857 return retval;
4858}
4859
4860
Jesus Cea6557aac2010-03-22 14:22:26 +00004861#if (DBVER >= 46)
4862static PyObject*
4863DBC_set_priority(DBCursorObject* self, PyObject* args, PyObject* kwargs)
4864{
4865 int err, priority;
4866 static char* kwnames[] = { "priority", NULL };
4867
4868 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i:set_priority", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00004869 &priority))
Jesus Cea6557aac2010-03-22 14:22:26 +00004870 return NULL;
4871
4872 CHECK_CURSOR_NOT_CLOSED(self);
4873
4874 MYDB_BEGIN_ALLOW_THREADS;
4875 err = self->dbc->set_priority(self->dbc, priority);
4876 MYDB_END_ALLOW_THREADS;
4877 RETURN_IF_ERR();
4878 RETURN_NONE();
4879}
4880
4881
4882static PyObject*
4883DBC_get_priority(DBCursorObject* self)
4884{
4885 int err;
4886 DB_CACHE_PRIORITY priority;
4887
4888 CHECK_CURSOR_NOT_CLOSED(self);
4889
4890 MYDB_BEGIN_ALLOW_THREADS;
4891 err = self->dbc->get_priority(self->dbc, &priority);
4892 MYDB_END_ALLOW_THREADS;
4893 RETURN_IF_ERR();
4894 return NUMBER_FromLong(priority);
4895}
4896#endif
4897
4898
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004899
4900/* --------------------------------------------------------------------- */
4901/* DBEnv methods */
4902
4903
4904static PyObject*
Jesus Ceaef9764f2008-05-13 18:45:46 +00004905DBEnv_close_internal(DBEnvObject* self, int flags)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004906{
Jesus Ceaef9764f2008-05-13 18:45:46 +00004907 PyObject *dummy;
4908 int err;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004909
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004910 if (!self->closed) { /* Don't close more than once */
Jesus Ceaef9764f2008-05-13 18:45:46 +00004911 while(self->children_txns) {
Jesus Cea6557aac2010-03-22 14:22:26 +00004912 dummy = DBTxn_abort_discard_internal(self->children_txns, 0);
4913 Py_XDECREF(dummy);
Jesus Ceaef9764f2008-05-13 18:45:46 +00004914 }
4915 while(self->children_dbs) {
Jesus Cea6557aac2010-03-22 14:22:26 +00004916 dummy = DB_close_internal(self->children_dbs, 0, 0);
4917 Py_XDECREF(dummy);
4918 }
4919 while(self->children_logcursors) {
4920 dummy = DBLogCursor_close_internal(self->children_logcursors);
4921 Py_XDECREF(dummy);
Jesus Ceaef9764f2008-05-13 18:45:46 +00004922 }
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07004923#if (DBVER >= 52)
4924 while(self->children_sites) {
4925 dummy = DBSite_close_internal(self->children_sites);
4926 Py_XDECREF(dummy);
4927 }
4928#endif
Jesus Ceaac25fab2008-09-03 17:50:32 +00004929 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00004930
Jesus Ceaac25fab2008-09-03 17:50:32 +00004931 self->closed = 1;
4932 if (self->db_env) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004933 MYDB_BEGIN_ALLOW_THREADS;
4934 err = self->db_env->close(self->db_env, flags);
4935 MYDB_END_ALLOW_THREADS;
4936 /* after calling DBEnv->close, regardless of error, this DBEnv
Jesus Ceaef9764f2008-05-13 18:45:46 +00004937 * may not be accessed again (Berkeley DB docs). */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004938 self->db_env = NULL;
4939 RETURN_IF_ERR();
4940 }
4941 RETURN_NONE();
4942}
4943
Jesus Ceaef9764f2008-05-13 18:45:46 +00004944static PyObject*
4945DBEnv_close(DBEnvObject* self, PyObject* args)
4946{
4947 int flags = 0;
4948
4949 if (!PyArg_ParseTuple(args, "|i:close", &flags))
4950 return NULL;
Jesus Cea5cd5f122008-09-23 18:54:08 +00004951 return DBEnv_close_internal(self, flags);
Jesus Ceaef9764f2008-05-13 18:45:46 +00004952}
4953
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00004954
4955static PyObject*
4956DBEnv_open(DBEnvObject* self, PyObject* args)
4957{
4958 int err, flags=0, mode=0660;
4959 char *db_home;
4960
4961 if (!PyArg_ParseTuple(args, "z|ii:open", &db_home, &flags, &mode))
4962 return NULL;
4963
4964 CHECK_ENV_NOT_CLOSED(self);
4965
4966 MYDB_BEGIN_ALLOW_THREADS;
4967 err = self->db_env->open(self->db_env, db_home, flags, mode);
4968 MYDB_END_ALLOW_THREADS;
4969 RETURN_IF_ERR();
4970 self->closed = 0;
4971 self->flags = flags;
4972 RETURN_NONE();
4973}
4974
4975
4976static PyObject*
Jesus Cea6557aac2010-03-22 14:22:26 +00004977DBEnv_memp_stat(DBEnvObject* self, PyObject* args, PyObject *kwargs)
4978{
4979 int err;
4980 DB_MPOOL_STAT *gsp;
4981 DB_MPOOL_FSTAT **fsp, **fsp2;
4982 PyObject* d = NULL, *d2, *d3, *r;
4983 u_int32_t flags = 0;
4984 static char* kwnames[] = { "flags", NULL };
4985
4986 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:memp_stat",
4987 kwnames, &flags))
4988 return NULL;
4989
4990 CHECK_ENV_NOT_CLOSED(self);
4991
4992 MYDB_BEGIN_ALLOW_THREADS;
4993 err = self->db_env->memp_stat(self->db_env, &gsp, &fsp, flags);
4994 MYDB_END_ALLOW_THREADS;
4995 RETURN_IF_ERR();
4996
4997 /* Turn the stat structure into a dictionary */
4998 d = PyDict_New();
4999 if (d == NULL) {
5000 if (gsp)
5001 free(gsp);
5002 return NULL;
5003 }
5004
5005#define MAKE_ENTRY(name) _addIntToDict(d, #name, gsp->st_##name)
5006
5007 MAKE_ENTRY(gbytes);
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07005008 MAKE_ENTRY(bytes);
Jesus Cea6557aac2010-03-22 14:22:26 +00005009 MAKE_ENTRY(ncache);
5010#if (DBVER >= 46)
5011 MAKE_ENTRY(max_ncache);
5012#endif
5013 MAKE_ENTRY(regsize);
Jesus Cea6557aac2010-03-22 14:22:26 +00005014 MAKE_ENTRY(mmapsize);
5015 MAKE_ENTRY(maxopenfd);
5016 MAKE_ENTRY(maxwrite);
5017 MAKE_ENTRY(maxwrite_sleep);
Jesus Cea6557aac2010-03-22 14:22:26 +00005018 MAKE_ENTRY(map);
5019 MAKE_ENTRY(cache_hit);
5020 MAKE_ENTRY(cache_miss);
5021 MAKE_ENTRY(page_create);
5022 MAKE_ENTRY(page_in);
5023 MAKE_ENTRY(page_out);
5024 MAKE_ENTRY(ro_evict);
5025 MAKE_ENTRY(rw_evict);
5026 MAKE_ENTRY(page_trickle);
5027 MAKE_ENTRY(pages);
5028 MAKE_ENTRY(page_clean);
5029 MAKE_ENTRY(page_dirty);
5030 MAKE_ENTRY(hash_buckets);
5031 MAKE_ENTRY(hash_searches);
5032 MAKE_ENTRY(hash_longest);
5033 MAKE_ENTRY(hash_examined);
5034 MAKE_ENTRY(hash_nowait);
5035 MAKE_ENTRY(hash_wait);
5036#if (DBVER >= 45)
5037 MAKE_ENTRY(hash_max_nowait);
5038#endif
5039 MAKE_ENTRY(hash_max_wait);
5040 MAKE_ENTRY(region_wait);
5041 MAKE_ENTRY(region_nowait);
5042#if (DBVER >= 45)
5043 MAKE_ENTRY(mvcc_frozen);
5044 MAKE_ENTRY(mvcc_thawed);
5045 MAKE_ENTRY(mvcc_freed);
5046#endif
5047 MAKE_ENTRY(alloc);
5048 MAKE_ENTRY(alloc_buckets);
5049 MAKE_ENTRY(alloc_max_buckets);
5050 MAKE_ENTRY(alloc_pages);
5051 MAKE_ENTRY(alloc_max_pages);
5052#if (DBVER >= 45)
5053 MAKE_ENTRY(io_wait);
5054#endif
5055#if (DBVER >= 48)
5056 MAKE_ENTRY(sync_interrupted);
5057#endif
5058
5059#undef MAKE_ENTRY
5060 free(gsp);
5061
5062 d2 = PyDict_New();
5063 if (d2 == NULL) {
5064 Py_DECREF(d);
5065 if (fsp)
5066 free(fsp);
5067 return NULL;
5068 }
5069#define MAKE_ENTRY(name) _addIntToDict(d3, #name, (*fsp2)->st_##name)
5070 for(fsp2=fsp;*fsp2; fsp2++) {
5071 d3 = PyDict_New();
5072 if (d3 == NULL) {
5073 Py_DECREF(d);
5074 Py_DECREF(d2);
5075 if (fsp)
5076 free(fsp);
5077 return NULL;
5078 }
5079 MAKE_ENTRY(pagesize);
5080 MAKE_ENTRY(cache_hit);
5081 MAKE_ENTRY(cache_miss);
5082 MAKE_ENTRY(map);
5083 MAKE_ENTRY(page_create);
5084 MAKE_ENTRY(page_in);
5085 MAKE_ENTRY(page_out);
5086 if(PyDict_SetItemString(d2, (*fsp2)->file_name, d3)) {
5087 Py_DECREF(d);
5088 Py_DECREF(d2);
5089 Py_DECREF(d3);
5090 if (fsp)
5091 free(fsp);
5092 return NULL;
5093 }
5094 Py_DECREF(d3);
5095 }
5096
5097#undef MAKE_ENTRY
5098 free(fsp);
5099
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07005100 r = PyTuple_Pack(2, d, d2);
Jesus Cea6557aac2010-03-22 14:22:26 +00005101 Py_DECREF(d);
5102 Py_DECREF(d2);
5103 return r;
5104}
5105
Jesus Cea6557aac2010-03-22 14:22:26 +00005106static PyObject*
5107DBEnv_memp_stat_print(DBEnvObject* self, PyObject* args, PyObject *kwargs)
5108{
5109 int err;
5110 int flags=0;
5111 static char* kwnames[] = { "flags", NULL };
5112
5113 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:memp_stat_print",
5114 kwnames, &flags))
5115 {
5116 return NULL;
5117 }
5118 CHECK_ENV_NOT_CLOSED(self);
5119 MYDB_BEGIN_ALLOW_THREADS;
5120 err = self->db_env->memp_stat_print(self->db_env, flags);
5121 MYDB_END_ALLOW_THREADS;
5122 RETURN_IF_ERR();
5123 RETURN_NONE();
5124}
Jesus Cea6557aac2010-03-22 14:22:26 +00005125
5126
5127static PyObject*
5128DBEnv_memp_trickle(DBEnvObject* self, PyObject* args)
5129{
5130 int err, percent, nwrotep;
5131
5132 if (!PyArg_ParseTuple(args, "i:memp_trickle", &percent))
5133 return NULL;
5134 CHECK_ENV_NOT_CLOSED(self);
5135 MYDB_BEGIN_ALLOW_THREADS;
5136 err = self->db_env->memp_trickle(self->db_env, percent, &nwrotep);
5137 MYDB_END_ALLOW_THREADS;
5138 RETURN_IF_ERR();
5139 return NUMBER_FromLong(nwrotep);
5140}
5141
5142static PyObject*
5143DBEnv_memp_sync(DBEnvObject* self, PyObject* args)
5144{
5145 int err;
5146 DB_LSN lsn = {0, 0};
5147 DB_LSN *lsn_p = NULL;
5148
5149 if (!PyArg_ParseTuple(args, "|(ii):memp_sync", &lsn.file, &lsn.offset))
5150 return NULL;
5151 if ((lsn.file!=0) || (lsn.offset!=0)) {
5152 lsn_p = &lsn;
5153 }
5154 CHECK_ENV_NOT_CLOSED(self);
5155 MYDB_BEGIN_ALLOW_THREADS;
5156 err = self->db_env->memp_sync(self->db_env, lsn_p);
5157 MYDB_END_ALLOW_THREADS;
5158 RETURN_IF_ERR();
5159 RETURN_NONE();
5160}
5161
5162static PyObject*
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005163DBEnv_remove(DBEnvObject* self, PyObject* args)
5164{
5165 int err, flags=0;
5166 char *db_home;
5167
5168 if (!PyArg_ParseTuple(args, "s|i:remove", &db_home, &flags))
5169 return NULL;
5170 CHECK_ENV_NOT_CLOSED(self);
5171 MYDB_BEGIN_ALLOW_THREADS;
5172 err = self->db_env->remove(self->db_env, db_home, flags);
5173 MYDB_END_ALLOW_THREADS;
5174 RETURN_IF_ERR();
5175 RETURN_NONE();
5176}
5177
Barry Warsaw9a0d7792002-12-30 20:53:52 +00005178static PyObject*
5179DBEnv_dbremove(DBEnvObject* self, PyObject* args, PyObject* kwargs)
5180{
5181 int err;
5182 u_int32_t flags=0;
5183 char *file = NULL;
5184 char *database = NULL;
5185 PyObject *txnobj = NULL;
5186 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00005187 static char* kwnames[] = { "file", "database", "txn", "flags",
Jeremy Hyltonaf68c872005-12-10 18:50:16 +00005188 NULL };
Barry Warsaw9a0d7792002-12-30 20:53:52 +00005189
Gregory P. Smith641cddf2006-07-28 01:35:25 +00005190 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|zOi:dbremove", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00005191 &file, &database, &txnobj, &flags)) {
5192 return NULL;
Barry Warsaw9a0d7792002-12-30 20:53:52 +00005193 }
5194 if (!checkTxnObj(txnobj, &txn)) {
5195 return NULL;
5196 }
5197 CHECK_ENV_NOT_CLOSED(self);
5198 MYDB_BEGIN_ALLOW_THREADS;
5199 err = self->db_env->dbremove(self->db_env, txn, file, database, flags);
5200 MYDB_END_ALLOW_THREADS;
5201 RETURN_IF_ERR();
5202 RETURN_NONE();
5203}
5204
5205static PyObject*
5206DBEnv_dbrename(DBEnvObject* self, PyObject* args, PyObject* kwargs)
5207{
5208 int err;
5209 u_int32_t flags=0;
5210 char *file = NULL;
5211 char *database = NULL;
5212 char *newname = NULL;
5213 PyObject *txnobj = NULL;
5214 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00005215 static char* kwnames[] = { "file", "database", "newname", "txn",
Jeremy Hyltonaf68c872005-12-10 18:50:16 +00005216 "flags", NULL };
Barry Warsaw9a0d7792002-12-30 20:53:52 +00005217
Gregory P. Smith641cddf2006-07-28 01:35:25 +00005218 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "szs|Oi:dbrename", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00005219 &file, &database, &newname, &txnobj, &flags)) {
5220 return NULL;
Barry Warsaw9a0d7792002-12-30 20:53:52 +00005221 }
5222 if (!checkTxnObj(txnobj, &txn)) {
5223 return NULL;
5224 }
5225 CHECK_ENV_NOT_CLOSED(self);
5226 MYDB_BEGIN_ALLOW_THREADS;
5227 err = self->db_env->dbrename(self->db_env, txn, file, database, newname,
5228 flags);
5229 MYDB_END_ALLOW_THREADS;
5230 RETURN_IF_ERR();
5231 RETURN_NONE();
5232}
5233
Jesus Cea6557aac2010-03-22 14:22:26 +00005234
5235
Barry Warsaw9a0d7792002-12-30 20:53:52 +00005236static PyObject*
5237DBEnv_set_encrypt(DBEnvObject* self, PyObject* args, PyObject* kwargs)
5238{
5239 int err;
5240 u_int32_t flags=0;
5241 char *passwd = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00005242 static char* kwnames[] = { "passwd", "flags", NULL };
Barry Warsaw9a0d7792002-12-30 20:53:52 +00005243
5244 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|i:set_encrypt", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00005245 &passwd, &flags)) {
5246 return NULL;
Barry Warsaw9a0d7792002-12-30 20:53:52 +00005247 }
5248
5249 MYDB_BEGIN_ALLOW_THREADS;
5250 err = self->db_env->set_encrypt(self->db_env, passwd, flags);
5251 MYDB_END_ALLOW_THREADS;
5252
5253 RETURN_IF_ERR();
5254 RETURN_NONE();
5255}
Jesus Cea6557aac2010-03-22 14:22:26 +00005256
Jesus Cea6557aac2010-03-22 14:22:26 +00005257static PyObject*
5258DBEnv_get_encrypt_flags(DBEnvObject* self)
5259{
5260 int err;
5261 u_int32_t flags;
5262
5263 CHECK_ENV_NOT_CLOSED(self);
5264
5265 MYDB_BEGIN_ALLOW_THREADS;
5266 err = self->db_env->get_encrypt_flags(self->db_env, &flags);
5267 MYDB_END_ALLOW_THREADS;
5268
5269 RETURN_IF_ERR();
5270
5271 return NUMBER_FromLong(flags);
5272}
5273
5274static PyObject*
5275DBEnv_get_timeout(DBEnvObject* self, PyObject* args, PyObject* kwargs)
5276{
5277 int err;
5278 int flag;
5279 u_int32_t timeout;
5280 static char* kwnames[] = {"flag", NULL };
5281
5282 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i:get_timeout", kwnames,
5283 &flag)) {
5284 return NULL;
5285 }
5286 CHECK_ENV_NOT_CLOSED(self);
5287
5288 MYDB_BEGIN_ALLOW_THREADS;
5289 err = self->db_env->get_timeout(self->db_env, &timeout, flag);
5290 MYDB_END_ALLOW_THREADS;
5291 RETURN_IF_ERR();
5292 return NUMBER_FromLong(timeout);
5293}
Jesus Cea6557aac2010-03-22 14:22:26 +00005294
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005295
Gregory P. Smithfe11d3e2003-03-27 17:23:29 +00005296static PyObject*
5297DBEnv_set_timeout(DBEnvObject* self, PyObject* args, PyObject* kwargs)
5298{
5299 int err;
5300 u_int32_t flags=0;
5301 u_int32_t timeout = 0;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00005302 static char* kwnames[] = { "timeout", "flags", NULL };
Gregory P. Smithfe11d3e2003-03-27 17:23:29 +00005303
5304 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ii:set_timeout", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00005305 &timeout, &flags)) {
5306 return NULL;
Gregory P. Smithfe11d3e2003-03-27 17:23:29 +00005307 }
5308
5309 MYDB_BEGIN_ALLOW_THREADS;
5310 err = self->db_env->set_timeout(self->db_env, (db_timeout_t)timeout, flags);
5311 MYDB_END_ALLOW_THREADS;
5312
5313 RETURN_IF_ERR();
5314 RETURN_NONE();
5315}
Gregory P. Smithfe11d3e2003-03-27 17:23:29 +00005316
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005317static PyObject*
Gregory P. Smith6676f6e2003-08-28 21:50:30 +00005318DBEnv_set_shm_key(DBEnvObject* self, PyObject* args)
5319{
5320 int err;
5321 long shm_key = 0;
5322
5323 if (!PyArg_ParseTuple(args, "l:set_shm_key", &shm_key))
5324 return NULL;
5325 CHECK_ENV_NOT_CLOSED(self);
5326
5327 err = self->db_env->set_shm_key(self->db_env, shm_key);
5328 RETURN_IF_ERR();
5329 RETURN_NONE();
5330}
5331
Jesus Cea6557aac2010-03-22 14:22:26 +00005332static PyObject*
5333DBEnv_get_shm_key(DBEnvObject* self)
5334{
5335 int err;
5336 long shm_key;
5337
5338 CHECK_ENV_NOT_CLOSED(self);
5339
5340 MYDB_BEGIN_ALLOW_THREADS;
5341 err = self->db_env->get_shm_key(self->db_env, &shm_key);
5342 MYDB_END_ALLOW_THREADS;
5343
5344 RETURN_IF_ERR();
5345
5346 return NUMBER_FromLong(shm_key);
5347}
Jesus Cea6557aac2010-03-22 14:22:26 +00005348
5349#if (DBVER >= 46)
5350static PyObject*
5351DBEnv_set_cache_max(DBEnvObject* self, PyObject* args)
5352{
5353 int err, gbytes, bytes;
5354
5355 if (!PyArg_ParseTuple(args, "ii:set_cache_max",
5356 &gbytes, &bytes))
5357 return NULL;
5358 CHECK_ENV_NOT_CLOSED(self);
5359
5360 MYDB_BEGIN_ALLOW_THREADS;
5361 err = self->db_env->set_cache_max(self->db_env, gbytes, bytes);
5362 MYDB_END_ALLOW_THREADS;
5363 RETURN_IF_ERR();
5364 RETURN_NONE();
5365}
5366
5367static PyObject*
5368DBEnv_get_cache_max(DBEnvObject* self)
5369{
5370 int err;
5371 u_int32_t gbytes, bytes;
5372
5373 CHECK_ENV_NOT_CLOSED(self);
5374
5375 MYDB_BEGIN_ALLOW_THREADS;
5376 err = self->db_env->get_cache_max(self->db_env, &gbytes, &bytes);
5377 MYDB_END_ALLOW_THREADS;
5378
5379 RETURN_IF_ERR();
5380
5381 return Py_BuildValue("(ii)", gbytes, bytes);
5382}
5383#endif
5384
5385#if (DBVER >= 46)
5386static PyObject*
5387DBEnv_set_thread_count(DBEnvObject* self, PyObject* args)
5388{
5389 int err;
5390 u_int32_t count;
5391
5392 if (!PyArg_ParseTuple(args, "i:set_thread_count", &count))
5393 return NULL;
5394 CHECK_ENV_NOT_CLOSED(self);
5395
5396 MYDB_BEGIN_ALLOW_THREADS;
5397 err = self->db_env->set_thread_count(self->db_env, count);
5398 MYDB_END_ALLOW_THREADS;
5399 RETURN_IF_ERR();
5400 RETURN_NONE();
5401}
5402
5403static PyObject*
5404DBEnv_get_thread_count(DBEnvObject* self)
5405{
5406 int err;
5407 u_int32_t count;
5408
5409 CHECK_ENV_NOT_CLOSED(self);
5410
5411 MYDB_BEGIN_ALLOW_THREADS;
5412 err = self->db_env->get_thread_count(self->db_env, &count);
5413 MYDB_END_ALLOW_THREADS;
5414 RETURN_IF_ERR();
5415 return NUMBER_FromLong(count);
5416}
5417#endif
5418
Gregory P. Smith6676f6e2003-08-28 21:50:30 +00005419static PyObject*
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005420DBEnv_set_cachesize(DBEnvObject* self, PyObject* args)
5421{
5422 int err, gbytes=0, bytes=0, ncache=0;
5423
5424 if (!PyArg_ParseTuple(args, "ii|i:set_cachesize",
5425 &gbytes, &bytes, &ncache))
5426 return NULL;
5427 CHECK_ENV_NOT_CLOSED(self);
5428
5429 MYDB_BEGIN_ALLOW_THREADS;
5430 err = self->db_env->set_cachesize(self->db_env, gbytes, bytes, ncache);
5431 MYDB_END_ALLOW_THREADS;
5432 RETURN_IF_ERR();
5433 RETURN_NONE();
5434}
5435
Jesus Cea6557aac2010-03-22 14:22:26 +00005436static PyObject*
5437DBEnv_get_cachesize(DBEnvObject* self)
5438{
5439 int err;
5440 u_int32_t gbytes, bytes;
5441 int ncache;
5442
5443 CHECK_ENV_NOT_CLOSED(self);
5444
5445 MYDB_BEGIN_ALLOW_THREADS;
5446 err = self->db_env->get_cachesize(self->db_env, &gbytes, &bytes, &ncache);
5447 MYDB_END_ALLOW_THREADS;
5448
5449 RETURN_IF_ERR();
5450
5451 return Py_BuildValue("(iii)", gbytes, bytes, ncache);
5452}
Jesus Cea6557aac2010-03-22 14:22:26 +00005453
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005454
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005455static PyObject*
5456DBEnv_set_flags(DBEnvObject* self, PyObject* args)
5457{
5458 int err, flags=0, onoff=0;
5459
5460 if (!PyArg_ParseTuple(args, "ii:set_flags",
5461 &flags, &onoff))
5462 return NULL;
5463 CHECK_ENV_NOT_CLOSED(self);
5464
5465 MYDB_BEGIN_ALLOW_THREADS;
5466 err = self->db_env->set_flags(self->db_env, flags, onoff);
5467 MYDB_END_ALLOW_THREADS;
5468 RETURN_IF_ERR();
5469 RETURN_NONE();
5470}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005471
Jesus Cea6557aac2010-03-22 14:22:26 +00005472static PyObject*
5473DBEnv_get_flags(DBEnvObject* self)
5474{
5475 int err;
5476 u_int32_t flags;
5477
5478 CHECK_ENV_NOT_CLOSED(self);
5479
5480 MYDB_BEGIN_ALLOW_THREADS;
5481 err = self->db_env->get_flags(self->db_env, &flags);
5482 MYDB_END_ALLOW_THREADS;
5483 RETURN_IF_ERR();
5484 return NUMBER_FromLong(flags);
5485}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005486
Jesus Ceaca3939c2008-05-22 15:27:38 +00005487#if (DBVER >= 47)
5488static PyObject*
5489DBEnv_log_set_config(DBEnvObject* self, PyObject* args)
5490{
5491 int err, flags, onoff;
5492
5493 if (!PyArg_ParseTuple(args, "ii:log_set_config",
5494 &flags, &onoff))
5495 return NULL;
5496 CHECK_ENV_NOT_CLOSED(self);
5497
5498 MYDB_BEGIN_ALLOW_THREADS;
5499 err = self->db_env->log_set_config(self->db_env, flags, onoff);
5500 MYDB_END_ALLOW_THREADS;
5501 RETURN_IF_ERR();
5502 RETURN_NONE();
5503}
Jesus Cea6557aac2010-03-22 14:22:26 +00005504
5505static PyObject*
5506DBEnv_log_get_config(DBEnvObject* self, PyObject* args)
5507{
5508 int err, flag, onoff;
5509
5510 if (!PyArg_ParseTuple(args, "i:log_get_config", &flag))
5511 return NULL;
5512 CHECK_ENV_NOT_CLOSED(self);
5513
5514 MYDB_BEGIN_ALLOW_THREADS;
5515 err = self->db_env->log_get_config(self->db_env, flag, &onoff);
5516 MYDB_END_ALLOW_THREADS;
5517 RETURN_IF_ERR();
5518 return PyBool_FromLong(onoff);
5519}
Jesus Ceaca3939c2008-05-22 15:27:38 +00005520#endif /* DBVER >= 47 */
5521
Jesus Cea6557aac2010-03-22 14:22:26 +00005522#if (DBVER >= 44)
5523static PyObject*
5524DBEnv_mutex_set_max(DBEnvObject* self, PyObject* args)
5525{
5526 int err;
5527 int value;
5528
5529 if (!PyArg_ParseTuple(args, "i:mutex_set_max", &value))
5530 return NULL;
5531
5532 CHECK_ENV_NOT_CLOSED(self);
5533
5534 MYDB_BEGIN_ALLOW_THREADS;
5535 err = self->db_env->mutex_set_max(self->db_env, value);
5536 MYDB_END_ALLOW_THREADS;
5537
5538 RETURN_IF_ERR();
5539 RETURN_NONE();
5540}
5541
5542static PyObject*
5543DBEnv_mutex_get_max(DBEnvObject* self)
5544{
5545 int err;
5546 u_int32_t value;
5547
5548 CHECK_ENV_NOT_CLOSED(self);
5549
5550 MYDB_BEGIN_ALLOW_THREADS;
5551 err = self->db_env->mutex_get_max(self->db_env, &value);
5552 MYDB_END_ALLOW_THREADS;
5553
5554 RETURN_IF_ERR();
5555
5556 return NUMBER_FromLong(value);
5557}
5558
5559static PyObject*
5560DBEnv_mutex_set_align(DBEnvObject* self, PyObject* args)
5561{
5562 int err;
5563 int align;
5564
5565 if (!PyArg_ParseTuple(args, "i:mutex_set_align", &align))
5566 return NULL;
5567
5568 CHECK_ENV_NOT_CLOSED(self);
5569
5570 MYDB_BEGIN_ALLOW_THREADS;
5571 err = self->db_env->mutex_set_align(self->db_env, align);
5572 MYDB_END_ALLOW_THREADS;
5573
5574 RETURN_IF_ERR();
5575 RETURN_NONE();
5576}
5577
5578static PyObject*
5579DBEnv_mutex_get_align(DBEnvObject* self)
5580{
5581 int err;
5582 u_int32_t align;
5583
5584 CHECK_ENV_NOT_CLOSED(self);
5585
5586 MYDB_BEGIN_ALLOW_THREADS;
5587 err = self->db_env->mutex_get_align(self->db_env, &align);
5588 MYDB_END_ALLOW_THREADS;
5589
5590 RETURN_IF_ERR();
5591
5592 return NUMBER_FromLong(align);
5593}
5594
5595static PyObject*
5596DBEnv_mutex_set_increment(DBEnvObject* self, PyObject* args)
5597{
5598 int err;
5599 int increment;
5600
5601 if (!PyArg_ParseTuple(args, "i:mutex_set_increment", &increment))
5602 return NULL;
5603
5604 CHECK_ENV_NOT_CLOSED(self);
5605
5606 MYDB_BEGIN_ALLOW_THREADS;
5607 err = self->db_env->mutex_set_increment(self->db_env, increment);
5608 MYDB_END_ALLOW_THREADS;
5609
5610 RETURN_IF_ERR();
5611 RETURN_NONE();
5612}
5613
5614static PyObject*
5615DBEnv_mutex_get_increment(DBEnvObject* self)
5616{
5617 int err;
5618 u_int32_t increment;
5619
5620 CHECK_ENV_NOT_CLOSED(self);
5621
5622 MYDB_BEGIN_ALLOW_THREADS;
5623 err = self->db_env->mutex_get_increment(self->db_env, &increment);
5624 MYDB_END_ALLOW_THREADS;
5625
5626 RETURN_IF_ERR();
5627
5628 return NUMBER_FromLong(increment);
5629}
5630
5631static PyObject*
5632DBEnv_mutex_set_tas_spins(DBEnvObject* self, PyObject* args)
5633{
5634 int err;
5635 int tas_spins;
5636
5637 if (!PyArg_ParseTuple(args, "i:mutex_set_tas_spins", &tas_spins))
5638 return NULL;
5639
5640 CHECK_ENV_NOT_CLOSED(self);
5641
5642 MYDB_BEGIN_ALLOW_THREADS;
5643 err = self->db_env->mutex_set_tas_spins(self->db_env, tas_spins);
5644 MYDB_END_ALLOW_THREADS;
5645
5646 RETURN_IF_ERR();
5647 RETURN_NONE();
5648}
5649
5650static PyObject*
5651DBEnv_mutex_get_tas_spins(DBEnvObject* self)
5652{
5653 int err;
5654 u_int32_t tas_spins;
5655
5656 CHECK_ENV_NOT_CLOSED(self);
5657
5658 MYDB_BEGIN_ALLOW_THREADS;
5659 err = self->db_env->mutex_get_tas_spins(self->db_env, &tas_spins);
5660 MYDB_END_ALLOW_THREADS;
5661
5662 RETURN_IF_ERR();
5663
5664 return NUMBER_FromLong(tas_spins);
5665}
5666#endif
Jesus Ceaca3939c2008-05-22 15:27:38 +00005667
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005668static PyObject*
5669DBEnv_set_data_dir(DBEnvObject* self, PyObject* args)
5670{
5671 int err;
5672 char *dir;
5673
5674 if (!PyArg_ParseTuple(args, "s:set_data_dir", &dir))
5675 return NULL;
5676 CHECK_ENV_NOT_CLOSED(self);
5677
5678 MYDB_BEGIN_ALLOW_THREADS;
5679 err = self->db_env->set_data_dir(self->db_env, dir);
5680 MYDB_END_ALLOW_THREADS;
5681 RETURN_IF_ERR();
5682 RETURN_NONE();
5683}
5684
Jesus Cea6557aac2010-03-22 14:22:26 +00005685static PyObject*
5686DBEnv_get_data_dirs(DBEnvObject* self)
5687{
5688 int err;
5689 PyObject *tuple;
5690 PyObject *item;
5691 const char **dirpp;
5692 int size, i;
5693
5694 CHECK_ENV_NOT_CLOSED(self);
5695
5696 MYDB_BEGIN_ALLOW_THREADS;
5697 err = self->db_env->get_data_dirs(self->db_env, &dirpp);
5698 MYDB_END_ALLOW_THREADS;
5699
5700 RETURN_IF_ERR();
5701
5702 /*
5703 ** Calculate size. Python C API
5704 ** actually allows for tuple resizing,
5705 ** but this is simple enough.
5706 */
5707 for (size=0; *(dirpp+size) ; size++);
5708
5709 tuple = PyTuple_New(size);
5710 if (!tuple)
5711 return NULL;
5712
5713 for (i=0; i<size; i++) {
5714 item = PyBytes_FromString (*(dirpp+i));
5715 if (item == NULL) {
5716 Py_DECREF(tuple);
5717 tuple = NULL;
5718 break;
5719 }
5720 PyTuple_SET_ITEM(tuple, i, item);
5721 }
5722 return tuple;
5723}
Jesus Cea6557aac2010-03-22 14:22:26 +00005724
5725#if (DBVER >= 44)
5726static PyObject*
5727DBEnv_set_lg_filemode(DBEnvObject* self, PyObject* args)
5728{
5729 int err, filemode;
5730
5731 if (!PyArg_ParseTuple(args, "i:set_lg_filemode", &filemode))
5732 return NULL;
5733 CHECK_ENV_NOT_CLOSED(self);
5734
5735 MYDB_BEGIN_ALLOW_THREADS;
5736 err = self->db_env->set_lg_filemode(self->db_env, filemode);
5737 MYDB_END_ALLOW_THREADS;
5738 RETURN_IF_ERR();
5739 RETURN_NONE();
5740}
5741
5742static PyObject*
5743DBEnv_get_lg_filemode(DBEnvObject* self)
5744{
5745 int err, filemode;
5746
5747 CHECK_ENV_NOT_CLOSED(self);
5748
5749 MYDB_BEGIN_ALLOW_THREADS;
5750 err = self->db_env->get_lg_filemode(self->db_env, &filemode);
5751 MYDB_END_ALLOW_THREADS;
5752 RETURN_IF_ERR();
5753 return NUMBER_FromLong(filemode);
5754}
5755#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005756
5757static PyObject*
5758DBEnv_set_lg_bsize(DBEnvObject* self, PyObject* args)
5759{
5760 int err, lg_bsize;
5761
5762 if (!PyArg_ParseTuple(args, "i:set_lg_bsize", &lg_bsize))
5763 return NULL;
5764 CHECK_ENV_NOT_CLOSED(self);
5765
5766 MYDB_BEGIN_ALLOW_THREADS;
5767 err = self->db_env->set_lg_bsize(self->db_env, lg_bsize);
5768 MYDB_END_ALLOW_THREADS;
5769 RETURN_IF_ERR();
5770 RETURN_NONE();
5771}
5772
Jesus Cea6557aac2010-03-22 14:22:26 +00005773static PyObject*
5774DBEnv_get_lg_bsize(DBEnvObject* self)
5775{
5776 int err;
5777 u_int32_t lg_bsize;
5778
5779 CHECK_ENV_NOT_CLOSED(self);
5780
5781 MYDB_BEGIN_ALLOW_THREADS;
5782 err = self->db_env->get_lg_bsize(self->db_env, &lg_bsize);
5783 MYDB_END_ALLOW_THREADS;
5784 RETURN_IF_ERR();
5785 return NUMBER_FromLong(lg_bsize);
5786}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005787
5788static PyObject*
5789DBEnv_set_lg_dir(DBEnvObject* self, PyObject* args)
5790{
5791 int err;
5792 char *dir;
5793
5794 if (!PyArg_ParseTuple(args, "s:set_lg_dir", &dir))
5795 return NULL;
5796 CHECK_ENV_NOT_CLOSED(self);
5797
5798 MYDB_BEGIN_ALLOW_THREADS;
5799 err = self->db_env->set_lg_dir(self->db_env, dir);
5800 MYDB_END_ALLOW_THREADS;
5801 RETURN_IF_ERR();
5802 RETURN_NONE();
5803}
5804
Jesus Cea6557aac2010-03-22 14:22:26 +00005805static PyObject*
5806DBEnv_get_lg_dir(DBEnvObject* self)
5807{
5808 int err;
5809 const char *dirp;
5810
5811 CHECK_ENV_NOT_CLOSED(self);
5812
5813 MYDB_BEGIN_ALLOW_THREADS;
5814 err = self->db_env->get_lg_dir(self->db_env, &dirp);
5815 MYDB_END_ALLOW_THREADS;
5816 RETURN_IF_ERR();
5817 return PyBytes_FromString(dirp);
5818}
Jesus Cea6557aac2010-03-22 14:22:26 +00005819
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005820static PyObject*
5821DBEnv_set_lg_max(DBEnvObject* self, PyObject* args)
5822{
5823 int err, lg_max;
5824
5825 if (!PyArg_ParseTuple(args, "i:set_lg_max", &lg_max))
5826 return NULL;
5827 CHECK_ENV_NOT_CLOSED(self);
5828
5829 MYDB_BEGIN_ALLOW_THREADS;
5830 err = self->db_env->set_lg_max(self->db_env, lg_max);
5831 MYDB_END_ALLOW_THREADS;
5832 RETURN_IF_ERR();
5833 RETURN_NONE();
5834}
5835
Jesus Ceaef9764f2008-05-13 18:45:46 +00005836static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00005837DBEnv_get_lg_max(DBEnvObject* self)
Jesus Ceaef9764f2008-05-13 18:45:46 +00005838{
5839 int err;
5840 u_int32_t lg_max;
5841
Jesus Ceaef9764f2008-05-13 18:45:46 +00005842 CHECK_ENV_NOT_CLOSED(self);
5843
5844 MYDB_BEGIN_ALLOW_THREADS;
5845 err = self->db_env->get_lg_max(self->db_env, &lg_max);
5846 MYDB_END_ALLOW_THREADS;
5847 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00005848 return NUMBER_FromLong(lg_max);
Jesus Ceaef9764f2008-05-13 18:45:46 +00005849}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005850
5851static PyObject*
Gregory P. Smithe9477062005-06-04 06:46:59 +00005852DBEnv_set_lg_regionmax(DBEnvObject* self, PyObject* args)
5853{
5854 int err, lg_max;
5855
5856 if (!PyArg_ParseTuple(args, "i:set_lg_regionmax", &lg_max))
5857 return NULL;
5858 CHECK_ENV_NOT_CLOSED(self);
5859
5860 MYDB_BEGIN_ALLOW_THREADS;
5861 err = self->db_env->set_lg_regionmax(self->db_env, lg_max);
5862 MYDB_END_ALLOW_THREADS;
5863 RETURN_IF_ERR();
5864 RETURN_NONE();
5865}
5866
Jesus Cea6557aac2010-03-22 14:22:26 +00005867static PyObject*
5868DBEnv_get_lg_regionmax(DBEnvObject* self)
5869{
5870 int err;
5871 u_int32_t lg_regionmax;
5872
5873 CHECK_ENV_NOT_CLOSED(self);
5874
5875 MYDB_BEGIN_ALLOW_THREADS;
5876 err = self->db_env->get_lg_regionmax(self->db_env, &lg_regionmax);
5877 MYDB_END_ALLOW_THREADS;
5878 RETURN_IF_ERR();
5879 return NUMBER_FromLong(lg_regionmax);
5880}
Jesus Cea6557aac2010-03-22 14:22:26 +00005881
5882#if (DBVER >= 47)
5883static PyObject*
5884DBEnv_set_lk_partitions(DBEnvObject* self, PyObject* args)
5885{
5886 int err, lk_partitions;
5887
5888 if (!PyArg_ParseTuple(args, "i:set_lk_partitions", &lk_partitions))
5889 return NULL;
5890 CHECK_ENV_NOT_CLOSED(self);
5891
5892 MYDB_BEGIN_ALLOW_THREADS;
5893 err = self->db_env->set_lk_partitions(self->db_env, lk_partitions);
5894 MYDB_END_ALLOW_THREADS;
5895 RETURN_IF_ERR();
5896 RETURN_NONE();
5897}
5898
5899static PyObject*
5900DBEnv_get_lk_partitions(DBEnvObject* self)
5901{
5902 int err;
5903 u_int32_t lk_partitions;
5904
5905 CHECK_ENV_NOT_CLOSED(self);
5906
5907 MYDB_BEGIN_ALLOW_THREADS;
5908 err = self->db_env->get_lk_partitions(self->db_env, &lk_partitions);
5909 MYDB_END_ALLOW_THREADS;
5910 RETURN_IF_ERR();
5911 return NUMBER_FromLong(lk_partitions);
5912}
5913#endif
Gregory P. Smithe9477062005-06-04 06:46:59 +00005914
5915static PyObject*
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005916DBEnv_set_lk_detect(DBEnvObject* self, PyObject* args)
5917{
5918 int err, lk_detect;
5919
5920 if (!PyArg_ParseTuple(args, "i:set_lk_detect", &lk_detect))
5921 return NULL;
5922 CHECK_ENV_NOT_CLOSED(self);
5923
5924 MYDB_BEGIN_ALLOW_THREADS;
5925 err = self->db_env->set_lk_detect(self->db_env, lk_detect);
5926 MYDB_END_ALLOW_THREADS;
5927 RETURN_IF_ERR();
5928 RETURN_NONE();
5929}
5930
Jesus Cea6557aac2010-03-22 14:22:26 +00005931static PyObject*
5932DBEnv_get_lk_detect(DBEnvObject* self)
5933{
5934 int err;
5935 u_int32_t lk_detect;
5936
5937 CHECK_ENV_NOT_CLOSED(self);
5938
5939 MYDB_BEGIN_ALLOW_THREADS;
5940 err = self->db_env->get_lk_detect(self->db_env, &lk_detect);
5941 MYDB_END_ALLOW_THREADS;
5942 RETURN_IF_ERR();
5943 return NUMBER_FromLong(lk_detect);
5944}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005945
Gregory P. Smith8b96a352007-01-05 01:59:42 +00005946#if (DBVER < 45)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005947static PyObject*
5948DBEnv_set_lk_max(DBEnvObject* self, PyObject* args)
5949{
5950 int err, max;
5951
5952 if (!PyArg_ParseTuple(args, "i:set_lk_max", &max))
5953 return NULL;
5954 CHECK_ENV_NOT_CLOSED(self);
5955
5956 MYDB_BEGIN_ALLOW_THREADS;
5957 err = self->db_env->set_lk_max(self->db_env, max);
5958 MYDB_END_ALLOW_THREADS;
5959 RETURN_IF_ERR();
5960 RETURN_NONE();
5961}
Gregory P. Smith8b96a352007-01-05 01:59:42 +00005962#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005963
5964
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005965
5966static PyObject*
5967DBEnv_set_lk_max_locks(DBEnvObject* self, PyObject* args)
5968{
5969 int err, max;
5970
5971 if (!PyArg_ParseTuple(args, "i:set_lk_max_locks", &max))
5972 return NULL;
5973 CHECK_ENV_NOT_CLOSED(self);
5974
5975 MYDB_BEGIN_ALLOW_THREADS;
5976 err = self->db_env->set_lk_max_locks(self->db_env, max);
5977 MYDB_END_ALLOW_THREADS;
5978 RETURN_IF_ERR();
5979 RETURN_NONE();
5980}
5981
Jesus Cea6557aac2010-03-22 14:22:26 +00005982static PyObject*
5983DBEnv_get_lk_max_locks(DBEnvObject* self)
5984{
5985 int err;
5986 u_int32_t lk_max;
5987
5988 CHECK_ENV_NOT_CLOSED(self);
5989
5990 MYDB_BEGIN_ALLOW_THREADS;
5991 err = self->db_env->get_lk_max_locks(self->db_env, &lk_max);
5992 MYDB_END_ALLOW_THREADS;
5993 RETURN_IF_ERR();
5994 return NUMBER_FromLong(lk_max);
5995}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00005996
5997static PyObject*
5998DBEnv_set_lk_max_lockers(DBEnvObject* self, PyObject* args)
5999{
6000 int err, max;
6001
6002 if (!PyArg_ParseTuple(args, "i:set_lk_max_lockers", &max))
6003 return NULL;
6004 CHECK_ENV_NOT_CLOSED(self);
6005
6006 MYDB_BEGIN_ALLOW_THREADS;
6007 err = self->db_env->set_lk_max_lockers(self->db_env, max);
6008 MYDB_END_ALLOW_THREADS;
6009 RETURN_IF_ERR();
6010 RETURN_NONE();
6011}
6012
Jesus Cea6557aac2010-03-22 14:22:26 +00006013static PyObject*
6014DBEnv_get_lk_max_lockers(DBEnvObject* self)
6015{
6016 int err;
6017 u_int32_t lk_max;
6018
6019 CHECK_ENV_NOT_CLOSED(self);
6020
6021 MYDB_BEGIN_ALLOW_THREADS;
6022 err = self->db_env->get_lk_max_lockers(self->db_env, &lk_max);
6023 MYDB_END_ALLOW_THREADS;
6024 RETURN_IF_ERR();
6025 return NUMBER_FromLong(lk_max);
6026}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006027
6028static PyObject*
6029DBEnv_set_lk_max_objects(DBEnvObject* self, PyObject* args)
6030{
6031 int err, max;
6032
6033 if (!PyArg_ParseTuple(args, "i:set_lk_max_objects", &max))
6034 return NULL;
6035 CHECK_ENV_NOT_CLOSED(self);
6036
6037 MYDB_BEGIN_ALLOW_THREADS;
6038 err = self->db_env->set_lk_max_objects(self->db_env, max);
6039 MYDB_END_ALLOW_THREADS;
6040 RETURN_IF_ERR();
6041 RETURN_NONE();
6042}
6043
Jesus Cea6557aac2010-03-22 14:22:26 +00006044static PyObject*
6045DBEnv_get_lk_max_objects(DBEnvObject* self)
6046{
6047 int err;
6048 u_int32_t lk_max;
6049
6050 CHECK_ENV_NOT_CLOSED(self);
6051
6052 MYDB_BEGIN_ALLOW_THREADS;
6053 err = self->db_env->get_lk_max_objects(self->db_env, &lk_max);
6054 MYDB_END_ALLOW_THREADS;
6055 RETURN_IF_ERR();
6056 return NUMBER_FromLong(lk_max);
6057}
Jesus Cea6557aac2010-03-22 14:22:26 +00006058
Jesus Cea6557aac2010-03-22 14:22:26 +00006059static PyObject*
6060DBEnv_get_mp_mmapsize(DBEnvObject* self)
6061{
6062 int err;
6063 size_t mmapsize;
6064
6065 CHECK_ENV_NOT_CLOSED(self);
6066
6067 MYDB_BEGIN_ALLOW_THREADS;
6068 err = self->db_env->get_mp_mmapsize(self->db_env, &mmapsize);
6069 MYDB_END_ALLOW_THREADS;
6070 RETURN_IF_ERR();
6071 return NUMBER_FromLong(mmapsize);
6072}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006073
6074static PyObject*
6075DBEnv_set_mp_mmapsize(DBEnvObject* self, PyObject* args)
6076{
6077 int err, mp_mmapsize;
6078
6079 if (!PyArg_ParseTuple(args, "i:set_mp_mmapsize", &mp_mmapsize))
6080 return NULL;
6081 CHECK_ENV_NOT_CLOSED(self);
6082
6083 MYDB_BEGIN_ALLOW_THREADS;
6084 err = self->db_env->set_mp_mmapsize(self->db_env, mp_mmapsize);
6085 MYDB_END_ALLOW_THREADS;
6086 RETURN_IF_ERR();
6087 RETURN_NONE();
6088}
6089
6090
6091static PyObject*
6092DBEnv_set_tmp_dir(DBEnvObject* self, PyObject* args)
6093{
6094 int err;
6095 char *dir;
6096
6097 if (!PyArg_ParseTuple(args, "s:set_tmp_dir", &dir))
6098 return NULL;
6099 CHECK_ENV_NOT_CLOSED(self);
6100
6101 MYDB_BEGIN_ALLOW_THREADS;
6102 err = self->db_env->set_tmp_dir(self->db_env, dir);
6103 MYDB_END_ALLOW_THREADS;
6104 RETURN_IF_ERR();
6105 RETURN_NONE();
6106}
6107
Jesus Cea6557aac2010-03-22 14:22:26 +00006108static PyObject*
6109DBEnv_get_tmp_dir(DBEnvObject* self)
6110{
6111 int err;
6112 const char *dirpp;
6113
6114 CHECK_ENV_NOT_CLOSED(self);
6115
6116 MYDB_BEGIN_ALLOW_THREADS;
6117 err = self->db_env->get_tmp_dir(self->db_env, &dirpp);
6118 MYDB_END_ALLOW_THREADS;
6119
6120 RETURN_IF_ERR();
6121
6122 return PyBytes_FromString(dirpp);
6123}
Jesus Cea6557aac2010-03-22 14:22:26 +00006124
Jesus Ceaef9764f2008-05-13 18:45:46 +00006125static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00006126DBEnv_txn_recover(DBEnvObject* self)
Jesus Ceaef9764f2008-05-13 18:45:46 +00006127{
6128 int flags = DB_FIRST;
6129 int err, i;
6130 PyObject *list, *tuple, *gid;
6131 DBTxnObject *txn;
6132#define PREPLIST_LEN 16
6133 DB_PREPLIST preplist[PREPLIST_LEN];
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07006134#if (DBVER < 48) || (DBVER >= 52)
Jesus Ceaef9764f2008-05-13 18:45:46 +00006135 long retp;
Matthias Klose54cc5392010-03-15 12:46:18 +00006136#else
6137 u_int32_t retp;
6138#endif
Jesus Ceaef9764f2008-05-13 18:45:46 +00006139
Jesus Ceaef9764f2008-05-13 18:45:46 +00006140 CHECK_ENV_NOT_CLOSED(self);
6141
6142 list=PyList_New(0);
6143 if (!list)
6144 return NULL;
6145 while (!0) {
6146 MYDB_BEGIN_ALLOW_THREADS
6147 err=self->db_env->txn_recover(self->db_env,
6148 preplist, PREPLIST_LEN, &retp, flags);
6149#undef PREPLIST_LEN
6150 MYDB_END_ALLOW_THREADS
6151 if (err) {
6152 Py_DECREF(list);
6153 RETURN_IF_ERR();
6154 }
6155 if (!retp) break;
6156 flags=DB_NEXT; /* Prepare for next loop pass */
6157 for (i=0; i<retp; i++) {
Christian Heimes593daf52008-05-26 12:51:38 +00006158 gid=PyBytes_FromStringAndSize((char *)(preplist[i].gid),
Matthias Klose54cc5392010-03-15 12:46:18 +00006159 DB_GID_SIZE);
Jesus Ceaef9764f2008-05-13 18:45:46 +00006160 if (!gid) {
6161 Py_DECREF(list);
6162 return NULL;
6163 }
Jesus Cea6557aac2010-03-22 14:22:26 +00006164 txn=newDBTxnObject(self, NULL, preplist[i].txn, 0);
Jesus Ceaef9764f2008-05-13 18:45:46 +00006165 if (!txn) {
6166 Py_DECREF(list);
6167 Py_DECREF(gid);
6168 return NULL;
6169 }
6170 txn->flag_prepare=1; /* Recover state */
6171 tuple=PyTuple_New(2);
6172 if (!tuple) {
6173 Py_DECREF(list);
6174 Py_DECREF(gid);
6175 Py_DECREF(txn);
6176 return NULL;
6177 }
6178 if (PyTuple_SetItem(tuple, 0, gid)) {
6179 Py_DECREF(list);
6180 Py_DECREF(gid);
6181 Py_DECREF(txn);
6182 Py_DECREF(tuple);
6183 return NULL;
6184 }
6185 if (PyTuple_SetItem(tuple, 1, (PyObject *)txn)) {
6186 Py_DECREF(list);
6187 Py_DECREF(txn);
6188 Py_DECREF(tuple); /* This delete the "gid" also */
6189 return NULL;
6190 }
6191 if (PyList_Append(list, tuple)) {
6192 Py_DECREF(list);
6193 Py_DECREF(tuple);/* This delete the "gid" and the "txn" also */
6194 return NULL;
6195 }
6196 Py_DECREF(tuple);
6197 }
6198 }
6199 return list;
6200}
Jesus Ceaef9764f2008-05-13 18:45:46 +00006201
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006202static PyObject*
6203DBEnv_txn_begin(DBEnvObject* self, PyObject* args, PyObject* kwargs)
6204{
6205 int flags = 0;
6206 PyObject* txnobj = NULL;
6207 DB_TXN *txn = NULL;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00006208 static char* kwnames[] = { "parent", "flags", NULL };
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006209
6210 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Oi:txn_begin", kwnames,
6211 &txnobj, &flags))
6212 return NULL;
6213
6214 if (!checkTxnObj(txnobj, &txn))
6215 return NULL;
6216 CHECK_ENV_NOT_CLOSED(self);
6217
Jesus Ceaef9764f2008-05-13 18:45:46 +00006218 return (PyObject*)newDBTxnObject(self, (DBTxnObject *)txnobj, NULL, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006219}
6220
6221
6222static PyObject*
6223DBEnv_txn_checkpoint(DBEnvObject* self, PyObject* args)
6224{
6225 int err, kbyte=0, min=0, flags=0;
6226
6227 if (!PyArg_ParseTuple(args, "|iii:txn_checkpoint", &kbyte, &min, &flags))
6228 return NULL;
6229 CHECK_ENV_NOT_CLOSED(self);
6230
6231 MYDB_BEGIN_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006232 err = self->db_env->txn_checkpoint(self->db_env, kbyte, min, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006233 MYDB_END_ALLOW_THREADS;
6234 RETURN_IF_ERR();
6235 RETURN_NONE();
6236}
6237
Jesus Cea6557aac2010-03-22 14:22:26 +00006238static PyObject*
6239DBEnv_get_tx_max(DBEnvObject* self)
6240{
6241 int err;
6242 u_int32_t max;
6243
6244 CHECK_ENV_NOT_CLOSED(self);
6245
6246 MYDB_BEGIN_ALLOW_THREADS;
6247 err = self->db_env->get_tx_max(self->db_env, &max);
6248 MYDB_END_ALLOW_THREADS;
6249 RETURN_IF_ERR();
6250 return PyLong_FromUnsignedLong(max);
6251}
Jesus Cea6557aac2010-03-22 14:22:26 +00006252
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006253static PyObject*
6254DBEnv_set_tx_max(DBEnvObject* self, PyObject* args)
6255{
6256 int err, max;
6257
6258 if (!PyArg_ParseTuple(args, "i:set_tx_max", &max))
6259 return NULL;
6260 CHECK_ENV_NOT_CLOSED(self);
6261
Jesus Cea6557aac2010-03-22 14:22:26 +00006262 MYDB_BEGIN_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006263 err = self->db_env->set_tx_max(self->db_env, max);
Jesus Cea6557aac2010-03-22 14:22:26 +00006264 MYDB_END_ALLOW_THREADS;
Gregory P. Smith8a474042006-01-27 07:05:40 +00006265 RETURN_IF_ERR();
6266 RETURN_NONE();
6267}
6268
Jesus Cea6557aac2010-03-22 14:22:26 +00006269static PyObject*
6270DBEnv_get_tx_timestamp(DBEnvObject* self)
6271{
6272 int err;
6273 time_t timestamp;
6274
6275 CHECK_ENV_NOT_CLOSED(self);
6276
6277 MYDB_BEGIN_ALLOW_THREADS;
6278 err = self->db_env->get_tx_timestamp(self->db_env, &timestamp);
6279 MYDB_END_ALLOW_THREADS;
6280 RETURN_IF_ERR();
6281 return NUMBER_FromLong(timestamp);
6282}
Jesus Cea6557aac2010-03-22 14:22:26 +00006283
Gregory P. Smith8a474042006-01-27 07:05:40 +00006284static PyObject*
6285DBEnv_set_tx_timestamp(DBEnvObject* self, PyObject* args)
6286{
6287 int err;
Thomas Wouters9d63cca2006-03-01 01:01:55 +00006288 long stamp;
6289 time_t timestamp;
Gregory P. Smith8a474042006-01-27 07:05:40 +00006290
Thomas Wouters9d63cca2006-03-01 01:01:55 +00006291 if (!PyArg_ParseTuple(args, "l:set_tx_timestamp", &stamp))
Gregory P. Smith8a474042006-01-27 07:05:40 +00006292 return NULL;
6293 CHECK_ENV_NOT_CLOSED(self);
Thomas Wouters9d63cca2006-03-01 01:01:55 +00006294 timestamp = (time_t)stamp;
Jesus Cea6557aac2010-03-22 14:22:26 +00006295 MYDB_BEGIN_ALLOW_THREADS;
Thomas Wouters9d63cca2006-03-01 01:01:55 +00006296 err = self->db_env->set_tx_timestamp(self->db_env, &timestamp);
Jesus Cea6557aac2010-03-22 14:22:26 +00006297 MYDB_END_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006298 RETURN_IF_ERR();
6299 RETURN_NONE();
6300}
6301
6302
6303static PyObject*
6304DBEnv_lock_detect(DBEnvObject* self, PyObject* args)
6305{
6306 int err, atype, flags=0;
6307 int aborted = 0;
6308
6309 if (!PyArg_ParseTuple(args, "i|i:lock_detect", &atype, &flags))
6310 return NULL;
6311 CHECK_ENV_NOT_CLOSED(self);
6312
6313 MYDB_BEGIN_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006314 err = self->db_env->lock_detect(self->db_env, flags, atype, &aborted);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006315 MYDB_END_ALLOW_THREADS;
6316 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00006317 return NUMBER_FromLong(aborted);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006318}
6319
6320
6321static PyObject*
6322DBEnv_lock_get(DBEnvObject* self, PyObject* args)
6323{
6324 int flags=0;
6325 int locker, lock_mode;
6326 DBT obj;
6327 PyObject* objobj;
6328
6329 if (!PyArg_ParseTuple(args, "iOi|i:lock_get", &locker, &objobj, &lock_mode, &flags))
6330 return NULL;
6331
6332
6333 if (!make_dbt(objobj, &obj))
6334 return NULL;
6335
6336 return (PyObject*)newDBLockObject(self, locker, &obj, lock_mode, flags);
6337}
6338
6339
6340static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00006341DBEnv_lock_id(DBEnvObject* self)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006342{
6343 int err;
6344 u_int32_t theID;
6345
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006346 CHECK_ENV_NOT_CLOSED(self);
6347 MYDB_BEGIN_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006348 err = self->db_env->lock_id(self->db_env, &theID);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006349 MYDB_END_ALLOW_THREADS;
6350 RETURN_IF_ERR();
6351
Jesus Ceac5a11fa2008-07-23 11:38:42 +00006352 return NUMBER_FromLong((long)theID);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006353}
6354
Gregory P. Smithac11e022007-11-05 02:56:31 +00006355static PyObject*
6356DBEnv_lock_id_free(DBEnvObject* self, PyObject* args)
6357{
6358 int err;
6359 u_int32_t theID;
6360
6361 if (!PyArg_ParseTuple(args, "I:lock_id_free", &theID))
6362 return NULL;
6363
6364 CHECK_ENV_NOT_CLOSED(self);
6365 MYDB_BEGIN_ALLOW_THREADS;
6366 err = self->db_env->lock_id_free(self->db_env, theID);
6367 MYDB_END_ALLOW_THREADS;
6368 RETURN_IF_ERR();
6369 RETURN_NONE();
6370}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006371
6372static PyObject*
6373DBEnv_lock_put(DBEnvObject* self, PyObject* args)
6374{
6375 int err;
6376 DBLockObject* dblockobj;
6377
6378 if (!PyArg_ParseTuple(args, "O!:lock_put", &DBLock_Type, &dblockobj))
6379 return NULL;
6380
6381 CHECK_ENV_NOT_CLOSED(self);
6382 MYDB_BEGIN_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006383 err = self->db_env->lock_put(self->db_env, &dblockobj->lock);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006384 MYDB_END_ALLOW_THREADS;
6385 RETURN_IF_ERR();
6386 RETURN_NONE();
6387}
6388
Gregory P. Smithdb8a8072006-06-05 01:56:15 +00006389#if (DBVER >= 44)
6390static PyObject*
Jesus Cea6557aac2010-03-22 14:22:26 +00006391DBEnv_fileid_reset(DBEnvObject* self, PyObject* args, PyObject* kwargs)
6392{
6393 int err;
6394 char *file;
6395 u_int32_t flags = 0;
6396 static char* kwnames[] = { "file", "flags", NULL};
6397
6398 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "z|i:fileid_reset", kwnames,
6399 &file, &flags))
6400 return NULL;
6401 CHECK_ENV_NOT_CLOSED(self);
6402
6403 MYDB_BEGIN_ALLOW_THREADS;
6404 err = self->db_env->fileid_reset(self->db_env, file, flags);
6405 MYDB_END_ALLOW_THREADS;
6406 RETURN_IF_ERR();
6407 RETURN_NONE();
6408}
6409
6410static PyObject*
Gregory P. Smithdb8a8072006-06-05 01:56:15 +00006411DBEnv_lsn_reset(DBEnvObject* self, PyObject* args, PyObject* kwargs)
6412{
6413 int err;
6414 char *file;
6415 u_int32_t flags = 0;
6416 static char* kwnames[] = { "file", "flags", NULL};
6417
6418 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "z|i:lsn_reset", kwnames,
6419 &file, &flags))
6420 return NULL;
6421 CHECK_ENV_NOT_CLOSED(self);
6422
6423 MYDB_BEGIN_ALLOW_THREADS;
6424 err = self->db_env->lsn_reset(self->db_env, file, flags);
6425 MYDB_END_ALLOW_THREADS;
6426 RETURN_IF_ERR();
6427 RETURN_NONE();
6428}
6429#endif /* DBVER >= 4.4 */
6430
Jesus Cea6557aac2010-03-22 14:22:26 +00006431
Jesus Cea6557aac2010-03-22 14:22:26 +00006432static PyObject*
6433DBEnv_stat_print(DBEnvObject* self, PyObject* args, PyObject *kwargs)
6434{
6435 int err;
6436 int flags=0;
6437 static char* kwnames[] = { "flags", NULL };
6438
6439 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:stat_print",
6440 kwnames, &flags))
6441 {
6442 return NULL;
6443 }
6444 CHECK_ENV_NOT_CLOSED(self);
6445 MYDB_BEGIN_ALLOW_THREADS;
6446 err = self->db_env->stat_print(self->db_env, flags);
6447 MYDB_END_ALLOW_THREADS;
6448 RETURN_IF_ERR();
6449 RETURN_NONE();
6450}
Jesus Cea6557aac2010-03-22 14:22:26 +00006451
6452
Gregory P. Smith76a82e82006-06-05 01:39:52 +00006453static PyObject*
6454DBEnv_log_stat(DBEnvObject* self, PyObject* args)
6455{
6456 int err;
6457 DB_LOG_STAT* statp = NULL;
6458 PyObject* d = NULL;
6459 u_int32_t flags = 0;
6460
6461 if (!PyArg_ParseTuple(args, "|i:log_stat", &flags))
6462 return NULL;
6463 CHECK_ENV_NOT_CLOSED(self);
6464
6465 MYDB_BEGIN_ALLOW_THREADS;
6466 err = self->db_env->log_stat(self->db_env, &statp, flags);
6467 MYDB_END_ALLOW_THREADS;
6468 RETURN_IF_ERR();
6469
6470 /* Turn the stat structure into a dictionary */
6471 d = PyDict_New();
6472 if (d == NULL) {
6473 if (statp)
6474 free(statp);
6475 return NULL;
6476 }
6477
6478#define MAKE_ENTRY(name) _addIntToDict(d, #name, statp->st_##name)
6479
6480 MAKE_ENTRY(magic);
6481 MAKE_ENTRY(version);
6482 MAKE_ENTRY(mode);
6483 MAKE_ENTRY(lg_bsize);
6484#if (DBVER >= 44)
6485 MAKE_ENTRY(lg_size);
6486 MAKE_ENTRY(record);
6487#endif
Gregory P. Smith76a82e82006-06-05 01:39:52 +00006488 MAKE_ENTRY(w_mbytes);
6489 MAKE_ENTRY(w_bytes);
6490 MAKE_ENTRY(wc_mbytes);
6491 MAKE_ENTRY(wc_bytes);
6492 MAKE_ENTRY(wcount);
6493 MAKE_ENTRY(wcount_fill);
6494#if (DBVER >= 44)
6495 MAKE_ENTRY(rcount);
6496#endif
6497 MAKE_ENTRY(scount);
6498 MAKE_ENTRY(cur_file);
6499 MAKE_ENTRY(cur_offset);
6500 MAKE_ENTRY(disk_file);
6501 MAKE_ENTRY(disk_offset);
6502 MAKE_ENTRY(maxcommitperflush);
6503 MAKE_ENTRY(mincommitperflush);
6504 MAKE_ENTRY(regsize);
6505 MAKE_ENTRY(region_wait);
6506 MAKE_ENTRY(region_nowait);
6507
6508#undef MAKE_ENTRY
6509 free(statp);
6510 return d;
6511} /* DBEnv_log_stat */
Gregory P. Smith76a82e82006-06-05 01:39:52 +00006512
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006513
Jesus Cea6557aac2010-03-22 14:22:26 +00006514static PyObject*
6515DBEnv_log_stat_print(DBEnvObject* self, PyObject* args, PyObject *kwargs)
6516{
6517 int err;
6518 int flags=0;
6519 static char* kwnames[] = { "flags", NULL };
6520
6521 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:log_stat_print",
6522 kwnames, &flags))
6523 {
6524 return NULL;
6525 }
6526 CHECK_ENV_NOT_CLOSED(self);
6527 MYDB_BEGIN_ALLOW_THREADS;
6528 err = self->db_env->log_stat_print(self->db_env, flags);
6529 MYDB_END_ALLOW_THREADS;
6530 RETURN_IF_ERR();
6531 RETURN_NONE();
6532}
Jesus Cea6557aac2010-03-22 14:22:26 +00006533
6534
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006535static PyObject*
6536DBEnv_lock_stat(DBEnvObject* self, PyObject* args)
6537{
6538 int err;
6539 DB_LOCK_STAT* sp;
6540 PyObject* d = NULL;
Martin v. Löwisb2c7aff2002-11-23 11:26:07 +00006541 u_int32_t flags = 0;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006542
6543 if (!PyArg_ParseTuple(args, "|i:lock_stat", &flags))
6544 return NULL;
6545 CHECK_ENV_NOT_CLOSED(self);
6546
6547 MYDB_BEGIN_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006548 err = self->db_env->lock_stat(self->db_env, &sp, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006549 MYDB_END_ALLOW_THREADS;
6550 RETURN_IF_ERR();
6551
6552 /* Turn the stat structure into a dictionary */
6553 d = PyDict_New();
6554 if (d == NULL) {
6555 free(sp);
6556 return NULL;
6557 }
6558
6559#define MAKE_ENTRY(name) _addIntToDict(d, #name, sp->st_##name)
6560
Jesus Ceaef9764f2008-05-13 18:45:46 +00006561 MAKE_ENTRY(id);
6562 MAKE_ENTRY(cur_maxid);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006563 MAKE_ENTRY(nmodes);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006564 MAKE_ENTRY(maxlocks);
6565 MAKE_ENTRY(maxlockers);
6566 MAKE_ENTRY(maxobjects);
6567 MAKE_ENTRY(nlocks);
6568 MAKE_ENTRY(maxnlocks);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006569 MAKE_ENTRY(nlockers);
6570 MAKE_ENTRY(maxnlockers);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006571 MAKE_ENTRY(nobjects);
6572 MAKE_ENTRY(maxnobjects);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006573 MAKE_ENTRY(nrequests);
6574 MAKE_ENTRY(nreleases);
Jesus Ceaef9764f2008-05-13 18:45:46 +00006575#if (DBVER >= 44)
6576 MAKE_ENTRY(nupgrade);
6577 MAKE_ENTRY(ndowngrade);
6578#endif
Gregory P. Smith29602d22006-01-24 09:46:48 +00006579#if (DBVER < 44)
6580 MAKE_ENTRY(nnowaits); /* these were renamed in 4.4 */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006581 MAKE_ENTRY(nconflicts);
Gregory P. Smith29602d22006-01-24 09:46:48 +00006582#else
6583 MAKE_ENTRY(lock_nowait);
6584 MAKE_ENTRY(lock_wait);
6585#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006586 MAKE_ENTRY(ndeadlocks);
Jesus Ceaef9764f2008-05-13 18:45:46 +00006587 MAKE_ENTRY(locktimeout);
6588 MAKE_ENTRY(txntimeout);
Jesus Ceaef9764f2008-05-13 18:45:46 +00006589 MAKE_ENTRY(nlocktimeouts);
6590 MAKE_ENTRY(ntxntimeouts);
Jesus Ceaef9764f2008-05-13 18:45:46 +00006591#if (DBVER >= 46)
6592 MAKE_ENTRY(objs_wait);
6593 MAKE_ENTRY(objs_nowait);
6594 MAKE_ENTRY(lockers_wait);
6595 MAKE_ENTRY(lockers_nowait);
Jesus Ceaca3939c2008-05-22 15:27:38 +00006596#if (DBVER >= 47)
6597 MAKE_ENTRY(lock_wait);
6598 MAKE_ENTRY(lock_nowait);
6599#else
Jesus Ceaef9764f2008-05-13 18:45:46 +00006600 MAKE_ENTRY(locks_wait);
6601 MAKE_ENTRY(locks_nowait);
Jesus Ceaca3939c2008-05-22 15:27:38 +00006602#endif
Jesus Ceaef9764f2008-05-13 18:45:46 +00006603 MAKE_ENTRY(hash_len);
6604#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006605 MAKE_ENTRY(regsize);
6606 MAKE_ENTRY(region_wait);
6607 MAKE_ENTRY(region_nowait);
6608
6609#undef MAKE_ENTRY
6610 free(sp);
6611 return d;
6612}
6613
Jesus Cea6557aac2010-03-22 14:22:26 +00006614static PyObject*
6615DBEnv_lock_stat_print(DBEnvObject* self, PyObject* args, PyObject *kwargs)
6616{
6617 int err;
6618 int flags=0;
6619 static char* kwnames[] = { "flags", NULL };
6620
6621 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:lock_stat_print",
6622 kwnames, &flags))
6623 {
6624 return NULL;
6625 }
6626 CHECK_ENV_NOT_CLOSED(self);
6627 MYDB_BEGIN_ALLOW_THREADS;
6628 err = self->db_env->lock_stat_print(self->db_env, flags);
6629 MYDB_END_ALLOW_THREADS;
6630 RETURN_IF_ERR();
6631 RETURN_NONE();
6632}
Jesus Cea6557aac2010-03-22 14:22:26 +00006633
6634
6635static PyObject*
6636DBEnv_log_cursor(DBEnvObject* self)
6637{
6638 int err;
6639 DB_LOGC* dblogc;
6640
6641 CHECK_ENV_NOT_CLOSED(self);
6642
6643 MYDB_BEGIN_ALLOW_THREADS;
6644 err = self->db_env->log_cursor(self->db_env, &dblogc, 0);
6645 MYDB_END_ALLOW_THREADS;
6646 RETURN_IF_ERR();
6647 return (PyObject*) newDBLogCursorObject(dblogc, self);
6648}
6649
6650
Jesus Ceaef9764f2008-05-13 18:45:46 +00006651static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00006652DBEnv_log_flush(DBEnvObject* self)
Jesus Ceaef9764f2008-05-13 18:45:46 +00006653{
6654 int err;
6655
Jesus Ceaef9764f2008-05-13 18:45:46 +00006656 CHECK_ENV_NOT_CLOSED(self);
6657
6658 MYDB_BEGIN_ALLOW_THREADS
6659 err = self->db_env->log_flush(self->db_env, NULL);
6660 MYDB_END_ALLOW_THREADS
6661
6662 RETURN_IF_ERR();
6663 RETURN_NONE();
6664}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006665
6666static PyObject*
Jesus Cea6557aac2010-03-22 14:22:26 +00006667DBEnv_log_file(DBEnvObject* self, PyObject* args)
6668{
6669 int err;
6670 DB_LSN lsn = {0, 0};
6671 int size = 20;
6672 char *name = NULL;
6673 PyObject *retval;
6674
6675 if (!PyArg_ParseTuple(args, "(ii):log_file", &lsn.file, &lsn.offset))
6676 return NULL;
6677
6678 CHECK_ENV_NOT_CLOSED(self);
6679
6680 do {
6681 name = malloc(size);
6682 if (!name) {
6683 PyErr_NoMemory();
6684 return NULL;
6685 }
6686 MYDB_BEGIN_ALLOW_THREADS;
6687 err = self->db_env->log_file(self->db_env, &lsn, name, size);
6688 MYDB_END_ALLOW_THREADS;
6689 if (err == EINVAL) {
6690 free(name);
6691 size *= 2;
6692 } else if (err) {
6693 free(name);
6694 RETURN_IF_ERR();
6695 assert(0); /* Unreachable... supposely */
6696 return NULL;
6697 }
6698/*
6699** If the final buffer we try is too small, we will
6700** get this exception:
6701** DBInvalidArgError:
6702** (22, 'Invalid argument -- DB_ENV->log_file: name buffer is too short')
6703*/
6704 } while ((err == EINVAL) && (size<(1<<17)));
6705
6706 RETURN_IF_ERR(); /* Maybe the size is not the problem */
6707
6708 retval = Py_BuildValue("s", name);
6709 free(name);
6710 return retval;
6711}
6712
6713
6714#if (DBVER >= 44)
6715static PyObject*
6716DBEnv_log_printf(DBEnvObject* self, PyObject* args, PyObject *kwargs)
6717{
6718 int err;
6719 char *string;
6720 PyObject *txnobj = NULL;
6721 DB_TXN *txn = NULL;
6722 static char* kwnames[] = {"string", "txn", NULL };
6723
6724 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|O:log_printf", kwnames,
6725 &string, &txnobj))
6726 return NULL;
6727
6728 CHECK_ENV_NOT_CLOSED(self);
6729
6730 if (!checkTxnObj(txnobj, &txn))
6731 return NULL;
6732
6733 /*
6734 ** Do not use the format string directly, to avoid attacks.
6735 */
6736 MYDB_BEGIN_ALLOW_THREADS;
6737 err = self->db_env->log_printf(self->db_env, txn, "%s", string);
6738 MYDB_END_ALLOW_THREADS;
6739
6740 RETURN_IF_ERR();
6741 RETURN_NONE();
6742}
6743#endif
6744
6745
6746static PyObject*
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006747DBEnv_log_archive(DBEnvObject* self, PyObject* args)
6748{
6749 int flags=0;
6750 int err;
Gregory P. Smith3dd20022006-06-05 00:31:01 +00006751 char **log_list = NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006752 PyObject* list;
6753 PyObject* item = NULL;
6754
6755 if (!PyArg_ParseTuple(args, "|i:log_archive", &flags))
6756 return NULL;
6757
6758 CHECK_ENV_NOT_CLOSED(self);
6759 MYDB_BEGIN_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006760 err = self->db_env->log_archive(self->db_env, &log_list, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006761 MYDB_END_ALLOW_THREADS;
6762 RETURN_IF_ERR();
6763
Gregory P. Smithbad47452006-06-05 00:33:35 +00006764 list = PyList_New(0);
6765 if (list == NULL) {
6766 if (log_list)
6767 free(log_list);
6768 return NULL;
6769 }
6770
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006771 if (log_list) {
Gregory P. Smith3dd20022006-06-05 00:31:01 +00006772 char **log_list_start;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006773 for (log_list_start = log_list; *log_list != NULL; ++log_list) {
Christian Heimes593daf52008-05-26 12:51:38 +00006774 item = PyBytes_FromString (*log_list);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006775 if (item == NULL) {
6776 Py_DECREF(list);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006777 list = NULL;
6778 break;
6779 }
Jesus Ceac5a11fa2008-07-23 11:38:42 +00006780 if (PyList_Append(list, item)) {
6781 Py_DECREF(list);
6782 list = NULL;
6783 Py_DECREF(item);
6784 break;
6785 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006786 Py_DECREF(item);
6787 }
6788 free(log_list_start);
6789 }
6790 return list;
6791}
6792
6793
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07006794#if (DBVER >= 52)
6795static PyObject*
6796DBEnv_repmgr_site(DBEnvObject* self, PyObject* args, PyObject *kwargs)
6797{
6798 int err;
6799 DB_SITE* site;
6800 char *host;
6801 u_int port;
6802 static char* kwnames[] = {"host", "port", NULL};
6803
6804 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "si:repmgr_site", kwnames,
6805 &host, &port))
6806 return NULL;
6807
6808 CHECK_ENV_NOT_CLOSED(self);
6809
6810 MYDB_BEGIN_ALLOW_THREADS;
6811 err = self->db_env->repmgr_site(self->db_env, host, port, &site, 0);
6812 MYDB_END_ALLOW_THREADS;
6813 RETURN_IF_ERR();
6814 return (PyObject*) newDBSiteObject(site, self);
6815}
6816
6817static PyObject*
6818DBEnv_repmgr_site_by_eid(DBEnvObject* self, PyObject* args, PyObject *kwargs)
6819{
6820 int err;
6821 DB_SITE* site;
6822 int eid;
6823 static char* kwnames[] = {"eid", NULL};
6824
6825 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i:repmgr_site_by_eid",
6826 kwnames, &eid))
6827 return NULL;
6828
6829 CHECK_ENV_NOT_CLOSED(self);
6830
6831 MYDB_BEGIN_ALLOW_THREADS;
6832 err = self->db_env->repmgr_site_by_eid(self->db_env, eid, &site);
6833 MYDB_END_ALLOW_THREADS;
6834 RETURN_IF_ERR();
6835 return (PyObject*) newDBSiteObject(site, self);
6836}
6837#endif
6838
6839
Jesus Cea6557aac2010-03-22 14:22:26 +00006840#if (DBVER >= 44)
6841static PyObject*
6842DBEnv_mutex_stat(DBEnvObject* self, PyObject* args)
6843{
6844 int err;
6845 DB_MUTEX_STAT* statp = NULL;
6846 PyObject* d = NULL;
6847 u_int32_t flags = 0;
6848
6849 if (!PyArg_ParseTuple(args, "|i:mutex_stat", &flags))
6850 return NULL;
6851 CHECK_ENV_NOT_CLOSED(self);
6852
6853 MYDB_BEGIN_ALLOW_THREADS;
6854 err = self->db_env->mutex_stat(self->db_env, &statp, flags);
6855 MYDB_END_ALLOW_THREADS;
6856 RETURN_IF_ERR();
6857
6858 /* Turn the stat structure into a dictionary */
6859 d = PyDict_New();
6860 if (d == NULL) {
6861 if (statp)
6862 free(statp);
6863 return NULL;
6864 }
6865
6866#define MAKE_ENTRY(name) _addIntToDict(d, #name, statp->st_##name)
6867
6868 MAKE_ENTRY(mutex_align);
6869 MAKE_ENTRY(mutex_tas_spins);
6870 MAKE_ENTRY(mutex_cnt);
6871 MAKE_ENTRY(mutex_free);
6872 MAKE_ENTRY(mutex_inuse);
6873 MAKE_ENTRY(mutex_inuse_max);
6874 MAKE_ENTRY(regsize);
6875 MAKE_ENTRY(region_wait);
6876 MAKE_ENTRY(region_nowait);
6877
6878#undef MAKE_ENTRY
6879 free(statp);
6880 return d;
6881}
6882#endif
6883
6884
6885#if (DBVER >= 44)
6886static PyObject*
6887DBEnv_mutex_stat_print(DBEnvObject* self, PyObject* args, PyObject *kwargs)
6888{
6889 int err;
6890 int flags=0;
6891 static char* kwnames[] = { "flags", NULL };
6892
6893 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:mutex_stat_print",
6894 kwnames, &flags))
6895 {
6896 return NULL;
6897 }
6898 CHECK_ENV_NOT_CLOSED(self);
6899 MYDB_BEGIN_ALLOW_THREADS;
6900 err = self->db_env->mutex_stat_print(self->db_env, flags);
6901 MYDB_END_ALLOW_THREADS;
6902 RETURN_IF_ERR();
6903 RETURN_NONE();
6904}
6905#endif
6906
6907
Jesus Cea6557aac2010-03-22 14:22:26 +00006908static PyObject*
6909DBEnv_txn_stat_print(DBEnvObject* self, PyObject* args, PyObject *kwargs)
6910{
6911 int err;
6912 int flags=0;
6913 static char* kwnames[] = { "flags", NULL };
6914
6915 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:stat_print",
6916 kwnames, &flags))
6917 {
6918 return NULL;
6919 }
6920
6921 CHECK_ENV_NOT_CLOSED(self);
6922
6923 MYDB_BEGIN_ALLOW_THREADS;
6924 err = self->db_env->txn_stat_print(self->db_env, flags);
6925 MYDB_END_ALLOW_THREADS;
6926 RETURN_IF_ERR();
6927 RETURN_NONE();
6928}
Jesus Cea6557aac2010-03-22 14:22:26 +00006929
6930
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006931static PyObject*
6932DBEnv_txn_stat(DBEnvObject* self, PyObject* args)
6933{
6934 int err;
6935 DB_TXN_STAT* sp;
6936 PyObject* d = NULL;
Martin v. Löwisb2c7aff2002-11-23 11:26:07 +00006937 u_int32_t flags=0;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006938
6939 if (!PyArg_ParseTuple(args, "|i:txn_stat", &flags))
6940 return NULL;
6941 CHECK_ENV_NOT_CLOSED(self);
6942
6943 MYDB_BEGIN_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006944 err = self->db_env->txn_stat(self->db_env, &sp, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006945 MYDB_END_ALLOW_THREADS;
6946 RETURN_IF_ERR();
6947
6948 /* Turn the stat structure into a dictionary */
6949 d = PyDict_New();
6950 if (d == NULL) {
6951 free(sp);
6952 return NULL;
6953 }
6954
Jesus Ceaef9764f2008-05-13 18:45:46 +00006955#define MAKE_ENTRY(name) _addIntToDict(d, #name, sp->st_##name)
6956#define MAKE_TIME_T_ENTRY(name) _addTimeTToDict(d, #name, sp->st_##name)
6957#define MAKE_DB_LSN_ENTRY(name) _addDB_lsnToDict(d, #name, sp->st_##name)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006958
Jesus Ceaef9764f2008-05-13 18:45:46 +00006959 MAKE_DB_LSN_ENTRY(last_ckp);
Kristján Valur Jónssonbd77c032007-04-26 15:24:54 +00006960 MAKE_TIME_T_ENTRY(time_ckp);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006961 MAKE_ENTRY(last_txnid);
6962 MAKE_ENTRY(maxtxns);
6963 MAKE_ENTRY(nactive);
6964 MAKE_ENTRY(maxnactive);
Jesus Ceaef9764f2008-05-13 18:45:46 +00006965#if (DBVER >= 45)
6966 MAKE_ENTRY(nsnapshot);
6967 MAKE_ENTRY(maxnsnapshot);
6968#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006969 MAKE_ENTRY(nbegins);
6970 MAKE_ENTRY(naborts);
6971 MAKE_ENTRY(ncommits);
Jesus Ceaef9764f2008-05-13 18:45:46 +00006972 MAKE_ENTRY(nrestores);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006973 MAKE_ENTRY(regsize);
6974 MAKE_ENTRY(region_wait);
6975 MAKE_ENTRY(region_nowait);
6976
Jesus Ceaef9764f2008-05-13 18:45:46 +00006977#undef MAKE_DB_LSN_ENTRY
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006978#undef MAKE_ENTRY
Kristján Valur Jónssonbd77c032007-04-26 15:24:54 +00006979#undef MAKE_TIME_T_ENTRY
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006980 free(sp);
6981 return d;
6982}
6983
6984
6985static PyObject*
6986DBEnv_set_get_returns_none(DBEnvObject* self, PyObject* args)
6987{
6988 int flags=0;
Gregory P. Smith455d46f2003-07-09 04:45:59 +00006989 int oldValue=0;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00006990
6991 if (!PyArg_ParseTuple(args,"i:set_get_returns_none", &flags))
6992 return NULL;
6993 CHECK_ENV_NOT_CLOSED(self);
6994
Gregory P. Smith455d46f2003-07-09 04:45:59 +00006995 if (self->moduleFlags.getReturnsNone)
6996 ++oldValue;
6997 if (self->moduleFlags.cursorSetReturnsNone)
6998 ++oldValue;
6999 self->moduleFlags.getReturnsNone = (flags >= 1);
7000 self->moduleFlags.cursorSetReturnsNone = (flags >= 2);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007001 return NUMBER_FromLong(oldValue);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00007002}
7003
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007004static PyObject*
7005DBEnv_get_private(DBEnvObject* self)
7006{
7007 /* We can give out the private field even if dbenv is closed */
Jesus Cea4907d272008-08-31 14:00:51 +00007008 Py_INCREF(self->private_obj);
7009 return self->private_obj;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007010}
7011
7012static PyObject*
Jesus Cea4907d272008-08-31 14:00:51 +00007013DBEnv_set_private(DBEnvObject* self, PyObject* private_obj)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007014{
7015 /* We can set the private field even if dbenv is closed */
Jesus Cea4907d272008-08-31 14:00:51 +00007016 Py_INCREF(private_obj);
Serhiy Storchaka763a61c2016-04-10 18:05:12 +03007017 Py_SETREF(self->private_obj, private_obj);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007018 RETURN_NONE();
7019}
7020
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07007021#if (DBVER >= 47)
7022static PyObject*
7023DBEnv_set_intermediate_dir_mode(DBEnvObject* self, PyObject* args)
7024{
7025 int err;
7026 const char *mode;
7027
7028 if (!PyArg_ParseTuple(args,"s:set_intermediate_dir_mode", &mode))
7029 return NULL;
7030
7031 CHECK_ENV_NOT_CLOSED(self);
7032
7033 MYDB_BEGIN_ALLOW_THREADS;
7034 err = self->db_env->set_intermediate_dir_mode(self->db_env, mode);
7035 MYDB_END_ALLOW_THREADS;
7036 RETURN_IF_ERR();
7037 RETURN_NONE();
7038}
7039
7040static PyObject*
7041DBEnv_get_intermediate_dir_mode(DBEnvObject* self)
7042{
7043 int err;
7044 const char *mode;
7045
7046 CHECK_ENV_NOT_CLOSED(self);
7047
7048 MYDB_BEGIN_ALLOW_THREADS;
7049 err = self->db_env->get_intermediate_dir_mode(self->db_env, &mode);
7050 MYDB_END_ALLOW_THREADS;
7051 RETURN_IF_ERR();
7052 return Py_BuildValue("s", mode);
7053}
7054#endif
7055
7056#if (DBVER < 47)
7057static PyObject*
7058DBEnv_set_intermediate_dir(DBEnvObject* self, PyObject* args)
7059{
7060 int err;
7061 int mode;
7062 u_int32_t flags;
7063
7064 if (!PyArg_ParseTuple(args, "iI:set_intermediate_dir", &mode, &flags))
7065 return NULL;
7066
7067 CHECK_ENV_NOT_CLOSED(self);
7068
7069 MYDB_BEGIN_ALLOW_THREADS;
7070 err = self->db_env->set_intermediate_dir(self->db_env, mode, flags);
7071 MYDB_END_ALLOW_THREADS;
7072 RETURN_IF_ERR();
7073 RETURN_NONE();
7074}
7075#endif
7076
7077static PyObject*
7078DBEnv_get_open_flags(DBEnvObject* self)
7079{
7080 int err;
7081 unsigned int flags;
7082
7083 CHECK_ENV_NOT_CLOSED(self);
7084
7085 MYDB_BEGIN_ALLOW_THREADS;
7086 err = self->db_env->get_open_flags(self->db_env, &flags);
7087 MYDB_END_ALLOW_THREADS;
7088 RETURN_IF_ERR();
7089 return NUMBER_FromLong(flags);
7090}
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007091
Matthias Klose54cc5392010-03-15 12:46:18 +00007092#if (DBVER < 48)
Jesus Ceaef9764f2008-05-13 18:45:46 +00007093static PyObject*
Jesus Ceaca3939c2008-05-22 15:27:38 +00007094DBEnv_set_rpc_server(DBEnvObject* self, PyObject* args, PyObject* kwargs)
7095{
7096 int err;
7097 char *host;
7098 long cl_timeout=0, sv_timeout=0;
7099
7100 static char* kwnames[] = { "host", "cl_timeout", "sv_timeout", NULL};
7101
7102 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|ll:set_rpc_server", kwnames,
7103 &host, &cl_timeout, &sv_timeout))
7104 return NULL;
7105 CHECK_ENV_NOT_CLOSED(self);
7106
7107 MYDB_BEGIN_ALLOW_THREADS;
7108 err = self->db_env->set_rpc_server(self->db_env, NULL, host, cl_timeout,
7109 sv_timeout, 0);
7110 MYDB_END_ALLOW_THREADS;
7111 RETURN_IF_ERR();
7112 RETURN_NONE();
7113}
Matthias Klose54cc5392010-03-15 12:46:18 +00007114#endif
Jesus Ceaca3939c2008-05-22 15:27:38 +00007115
Jesus Cea6557aac2010-03-22 14:22:26 +00007116static PyObject*
7117DBEnv_set_mp_max_openfd(DBEnvObject* self, PyObject* args)
7118{
7119 int err;
7120 int maxopenfd;
7121
7122 if (!PyArg_ParseTuple(args, "i:set_mp_max_openfd", &maxopenfd)) {
7123 return NULL;
7124 }
7125 CHECK_ENV_NOT_CLOSED(self);
7126 MYDB_BEGIN_ALLOW_THREADS;
7127 err = self->db_env->set_mp_max_openfd(self->db_env, maxopenfd);
7128 MYDB_END_ALLOW_THREADS;
7129 RETURN_IF_ERR();
7130 RETURN_NONE();
7131}
7132
7133static PyObject*
7134DBEnv_get_mp_max_openfd(DBEnvObject* self)
7135{
7136 int err;
7137 int maxopenfd;
7138
7139 CHECK_ENV_NOT_CLOSED(self);
7140
7141 MYDB_BEGIN_ALLOW_THREADS;
7142 err = self->db_env->get_mp_max_openfd(self->db_env, &maxopenfd);
7143 MYDB_END_ALLOW_THREADS;
7144 RETURN_IF_ERR();
7145 return NUMBER_FromLong(maxopenfd);
7146}
7147
7148
7149static PyObject*
7150DBEnv_set_mp_max_write(DBEnvObject* self, PyObject* args)
7151{
7152 int err;
7153 int maxwrite, maxwrite_sleep;
7154
7155 if (!PyArg_ParseTuple(args, "ii:set_mp_max_write", &maxwrite,
7156 &maxwrite_sleep)) {
7157 return NULL;
7158 }
7159 CHECK_ENV_NOT_CLOSED(self);
7160 MYDB_BEGIN_ALLOW_THREADS;
7161 err = self->db_env->set_mp_max_write(self->db_env, maxwrite,
7162 maxwrite_sleep);
7163 MYDB_END_ALLOW_THREADS;
7164 RETURN_IF_ERR();
7165 RETURN_NONE();
7166}
7167
7168static PyObject*
7169DBEnv_get_mp_max_write(DBEnvObject* self)
7170{
7171 int err;
7172 int maxwrite;
7173#if (DBVER >= 46)
7174 db_timeout_t maxwrite_sleep;
7175#else
7176 int maxwrite_sleep;
7177#endif
7178
7179 CHECK_ENV_NOT_CLOSED(self);
7180
7181 MYDB_BEGIN_ALLOW_THREADS;
7182 err = self->db_env->get_mp_max_write(self->db_env, &maxwrite,
7183 &maxwrite_sleep);
7184 MYDB_END_ALLOW_THREADS;
7185 RETURN_IF_ERR();
7186
7187 return Py_BuildValue("(ii)", maxwrite, (int)maxwrite_sleep);
7188}
Jesus Cea6557aac2010-03-22 14:22:26 +00007189
7190
Jesus Ceaca3939c2008-05-22 15:27:38 +00007191static PyObject*
Jesus Ceaef9764f2008-05-13 18:45:46 +00007192DBEnv_set_verbose(DBEnvObject* self, PyObject* args)
7193{
7194 int err;
7195 int which, onoff;
7196
7197 if (!PyArg_ParseTuple(args, "ii:set_verbose", &which, &onoff)) {
7198 return NULL;
7199 }
7200 CHECK_ENV_NOT_CLOSED(self);
7201 MYDB_BEGIN_ALLOW_THREADS;
7202 err = self->db_env->set_verbose(self->db_env, which, onoff);
7203 MYDB_END_ALLOW_THREADS;
7204 RETURN_IF_ERR();
7205 RETURN_NONE();
7206}
7207
Jesus Ceaef9764f2008-05-13 18:45:46 +00007208static PyObject*
7209DBEnv_get_verbose(DBEnvObject* self, PyObject* args)
7210{
7211 int err;
7212 int which;
7213 int verbose;
7214
7215 if (!PyArg_ParseTuple(args, "i:get_verbose", &which)) {
7216 return NULL;
7217 }
7218 CHECK_ENV_NOT_CLOSED(self);
7219 MYDB_BEGIN_ALLOW_THREADS;
7220 err = self->db_env->get_verbose(self->db_env, which, &verbose);
7221 MYDB_END_ALLOW_THREADS;
7222 RETURN_IF_ERR();
7223 return PyBool_FromLong(verbose);
7224}
Jesus Ceaef9764f2008-05-13 18:45:46 +00007225
7226#if (DBVER >= 45)
7227static void
7228_dbenv_event_notifyCallback(DB_ENV* db_env, u_int32_t event, void *event_info)
7229{
7230 DBEnvObject *dbenv;
7231 PyObject* callback;
7232 PyObject* args;
7233 PyObject* result = NULL;
7234
7235 MYDB_BEGIN_BLOCK_THREADS;
7236 dbenv = (DBEnvObject *)db_env->app_private;
7237 callback = dbenv->event_notifyCallback;
7238 if (callback) {
7239 if (event == DB_EVENT_REP_NEWMASTER) {
7240 args = Py_BuildValue("(Oii)", dbenv, event, *((int *)event_info));
7241 } else {
7242 args = Py_BuildValue("(OiO)", dbenv, event, Py_None);
7243 }
7244 if (args) {
7245 result = PyEval_CallObject(callback, args);
7246 }
7247 if ((!args) || (!result)) {
7248 PyErr_Print();
7249 }
7250 Py_XDECREF(args);
7251 Py_XDECREF(result);
7252 }
7253 MYDB_END_BLOCK_THREADS;
7254}
7255#endif
7256
7257#if (DBVER >= 45)
7258static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007259DBEnv_set_event_notify(DBEnvObject* self, PyObject* notifyFunc)
Jesus Ceaef9764f2008-05-13 18:45:46 +00007260{
7261 int err;
Jesus Ceaef9764f2008-05-13 18:45:46 +00007262
7263 CHECK_ENV_NOT_CLOSED(self);
7264
7265 if (!PyCallable_Check(notifyFunc)) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00007266 makeTypeError("Callable", notifyFunc);
7267 return NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00007268 }
7269
Jesus Ceaef9764f2008-05-13 18:45:46 +00007270 Py_INCREF(notifyFunc);
Serhiy Storchakabc62af12016-04-06 09:51:18 +03007271 Py_XSETREF(self->event_notifyCallback, notifyFunc);
Jesus Ceaef9764f2008-05-13 18:45:46 +00007272
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007273 /* This is to workaround a problem with un-initialized threads (see
7274 comment in DB_associate) */
7275#ifdef WITH_THREAD
7276 PyEval_InitThreads();
7277#endif
7278
Jesus Ceaef9764f2008-05-13 18:45:46 +00007279 MYDB_BEGIN_ALLOW_THREADS;
7280 err = self->db_env->set_event_notify(self->db_env, _dbenv_event_notifyCallback);
7281 MYDB_END_ALLOW_THREADS;
7282
7283 if (err) {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00007284 Py_DECREF(notifyFunc);
7285 self->event_notifyCallback = NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00007286 }
7287
7288 RETURN_IF_ERR();
7289 RETURN_NONE();
7290}
7291#endif
7292
7293
7294/* --------------------------------------------------------------------- */
7295/* REPLICATION METHODS: Base Replication */
7296
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007297
7298static PyObject*
7299DBEnv_rep_process_message(DBEnvObject* self, PyObject* args)
7300{
7301 int err;
7302 PyObject *control_py, *rec_py;
7303 DBT control, rec;
7304 int envid;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007305 DB_LSN lsn;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007306
7307 if (!PyArg_ParseTuple(args, "OOi:rep_process_message", &control_py,
7308 &rec_py, &envid))
7309 return NULL;
7310 CHECK_ENV_NOT_CLOSED(self);
7311
7312 if (!make_dbt(control_py, &control))
7313 return NULL;
7314 if (!make_dbt(rec_py, &rec))
7315 return NULL;
7316
7317 MYDB_BEGIN_ALLOW_THREADS;
7318#if (DBVER >= 46)
7319 err = self->db_env->rep_process_message(self->db_env, &control, &rec,
7320 envid, &lsn);
7321#else
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007322 err = self->db_env->rep_process_message(self->db_env, &control, &rec,
7323 &envid, &lsn);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007324#endif
7325 MYDB_END_ALLOW_THREADS;
7326 switch (err) {
7327 case DB_REP_NEWMASTER :
7328 return Py_BuildValue("(iO)", envid, Py_None);
7329 break;
7330
7331 case DB_REP_DUPMASTER :
7332 case DB_REP_HOLDELECTION :
7333#if (DBVER >= 44)
7334 case DB_REP_IGNORE :
7335 case DB_REP_JOIN_FAILURE :
7336#endif
7337 return Py_BuildValue("(iO)", err, Py_None);
7338 break;
7339 case DB_REP_NEWSITE :
Jesus Cea4907d272008-08-31 14:00:51 +00007340 {
7341 PyObject *tmp, *r;
7342
7343 if (!(tmp = PyBytes_FromStringAndSize(rec.data, rec.size))) {
7344 return NULL;
7345 }
7346
7347 r = Py_BuildValue("(iO)", err, tmp);
7348 Py_DECREF(tmp);
7349 return r;
7350 break;
7351 }
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007352 case DB_REP_NOTPERM :
7353 case DB_REP_ISPERM :
7354 return Py_BuildValue("(i(ll))", err, lsn.file, lsn.offset);
7355 break;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007356 }
7357 RETURN_IF_ERR();
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07007358 return PyTuple_Pack(2, Py_None, Py_None);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007359}
7360
7361static int
7362_DBEnv_rep_transportCallback(DB_ENV* db_env, const DBT* control, const DBT* rec,
7363 const DB_LSN *lsn, int envid, u_int32_t flags)
7364{
7365 DBEnvObject *dbenv;
7366 PyObject* rep_transport;
7367 PyObject* args;
Jesus Cea4907d272008-08-31 14:00:51 +00007368 PyObject *a, *b;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007369 PyObject* result = NULL;
7370 int ret=0;
7371
7372 MYDB_BEGIN_BLOCK_THREADS;
7373 dbenv = (DBEnvObject *)db_env->app_private;
7374 rep_transport = dbenv->rep_transport;
7375
Jesus Cea4907d272008-08-31 14:00:51 +00007376 /*
7377 ** The errors in 'a' or 'b' are detected in "Py_BuildValue".
7378 */
7379 a = PyBytes_FromStringAndSize(control->data, control->size);
7380 b = PyBytes_FromStringAndSize(rec->data, rec->size);
7381
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007382 args = Py_BuildValue(
Jesus Cea4907d272008-08-31 14:00:51 +00007383 "(OOO(ll)iI)",
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007384 dbenv,
Jesus Cea4907d272008-08-31 14:00:51 +00007385 a, b,
7386 lsn->file, lsn->offset, envid, flags);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007387 if (args) {
7388 result = PyEval_CallObject(rep_transport, args);
7389 }
7390
7391 if ((!args) || (!result)) {
7392 PyErr_Print();
7393 ret = -1;
7394 }
Jesus Cea4907d272008-08-31 14:00:51 +00007395 Py_XDECREF(a);
7396 Py_XDECREF(b);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007397 Py_XDECREF(args);
7398 Py_XDECREF(result);
7399 MYDB_END_BLOCK_THREADS;
7400 return ret;
7401}
7402
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007403static PyObject*
7404DBEnv_rep_set_transport(DBEnvObject* self, PyObject* args)
7405{
7406 int err;
7407 int envid;
7408 PyObject *rep_transport;
7409
7410 if (!PyArg_ParseTuple(args, "iO:rep_set_transport", &envid, &rep_transport))
7411 return NULL;
7412 CHECK_ENV_NOT_CLOSED(self);
7413 if (!PyCallable_Check(rep_transport)) {
7414 makeTypeError("Callable", rep_transport);
7415 return NULL;
7416 }
7417
7418 MYDB_BEGIN_ALLOW_THREADS;
7419#if (DBVER >=45)
7420 err = self->db_env->rep_set_transport(self->db_env, envid,
7421 &_DBEnv_rep_transportCallback);
7422#else
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007423 err = self->db_env->set_rep_transport(self->db_env, envid,
7424 &_DBEnv_rep_transportCallback);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007425#endif
7426 MYDB_END_ALLOW_THREADS;
7427 RETURN_IF_ERR();
7428
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007429 Py_INCREF(rep_transport);
Serhiy Storchaka763a61c2016-04-10 18:05:12 +03007430 Py_SETREF(self->rep_transport, rep_transport);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007431 RETURN_NONE();
7432}
7433
7434#if (DBVER >= 47)
7435static PyObject*
7436DBEnv_rep_set_request(DBEnvObject* self, PyObject* args)
7437{
7438 int err;
7439 unsigned int minimum, maximum;
7440
7441 if (!PyArg_ParseTuple(args,"II:rep_set_request", &minimum, &maximum))
7442 return NULL;
7443 CHECK_ENV_NOT_CLOSED(self);
7444
7445 MYDB_BEGIN_ALLOW_THREADS;
7446 err = self->db_env->rep_set_request(self->db_env, minimum, maximum);
7447 MYDB_END_ALLOW_THREADS;
7448 RETURN_IF_ERR();
7449 RETURN_NONE();
7450}
7451
7452static PyObject*
7453DBEnv_rep_get_request(DBEnvObject* self)
7454{
7455 int err;
7456 u_int32_t minimum, maximum;
7457
7458 CHECK_ENV_NOT_CLOSED(self);
7459 MYDB_BEGIN_ALLOW_THREADS;
7460 err = self->db_env->rep_get_request(self->db_env, &minimum, &maximum);
7461 MYDB_END_ALLOW_THREADS;
7462 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007463 return Py_BuildValue("II", minimum, maximum);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007464}
7465#endif
7466
7467#if (DBVER >= 45)
7468static PyObject*
7469DBEnv_rep_set_limit(DBEnvObject* self, PyObject* args)
7470{
7471 int err;
7472 int limit;
7473
7474 if (!PyArg_ParseTuple(args,"i:rep_set_limit", &limit))
7475 return NULL;
7476 CHECK_ENV_NOT_CLOSED(self);
7477
7478 MYDB_BEGIN_ALLOW_THREADS;
7479 err = self->db_env->rep_set_limit(self->db_env, 0, limit);
7480 MYDB_END_ALLOW_THREADS;
7481 RETURN_IF_ERR();
7482 RETURN_NONE();
7483}
7484
7485static PyObject*
7486DBEnv_rep_get_limit(DBEnvObject* self)
7487{
7488 int err;
7489 u_int32_t gbytes, bytes;
7490
7491 CHECK_ENV_NOT_CLOSED(self);
7492 MYDB_BEGIN_ALLOW_THREADS;
7493 err = self->db_env->rep_get_limit(self->db_env, &gbytes, &bytes);
7494 MYDB_END_ALLOW_THREADS;
7495 RETURN_IF_ERR();
7496 return NUMBER_FromLong(bytes);
7497}
7498#endif
7499
7500#if (DBVER >= 44)
7501static PyObject*
7502DBEnv_rep_set_config(DBEnvObject* self, PyObject* args)
7503{
7504 int err;
7505 int which;
7506 int onoff;
7507
7508 if (!PyArg_ParseTuple(args,"ii:rep_set_config", &which, &onoff))
7509 return NULL;
7510 CHECK_ENV_NOT_CLOSED(self);
7511
7512 MYDB_BEGIN_ALLOW_THREADS;
7513 err = self->db_env->rep_set_config(self->db_env, which, onoff);
7514 MYDB_END_ALLOW_THREADS;
7515 RETURN_IF_ERR();
7516 RETURN_NONE();
7517}
7518
7519static PyObject*
7520DBEnv_rep_get_config(DBEnvObject* self, PyObject* args)
7521{
7522 int err;
7523 int which;
7524 int onoff;
7525
7526 if (!PyArg_ParseTuple(args, "i:rep_get_config", &which)) {
7527 return NULL;
7528 }
7529 CHECK_ENV_NOT_CLOSED(self);
7530 MYDB_BEGIN_ALLOW_THREADS;
7531 err = self->db_env->rep_get_config(self->db_env, which, &onoff);
7532 MYDB_END_ALLOW_THREADS;
7533 RETURN_IF_ERR();
7534 return PyBool_FromLong(onoff);
7535}
7536#endif
7537
7538#if (DBVER >= 46)
7539static PyObject*
7540DBEnv_rep_elect(DBEnvObject* self, PyObject* args)
7541{
7542 int err;
7543 u_int32_t nsites, nvotes;
7544
7545 if (!PyArg_ParseTuple(args, "II:rep_elect", &nsites, &nvotes)) {
7546 return NULL;
7547 }
7548 CHECK_ENV_NOT_CLOSED(self);
7549 MYDB_BEGIN_ALLOW_THREADS;
Jesus Cea2ab4a912012-01-16 23:57:34 +01007550 err = self->db_env->rep_elect(self->db_env, nsites, nvotes, 0);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007551 MYDB_END_ALLOW_THREADS;
7552 RETURN_IF_ERR();
7553 RETURN_NONE();
7554}
7555#endif
7556
7557static PyObject*
7558DBEnv_rep_start(DBEnvObject* self, PyObject* args, PyObject* kwargs)
7559{
7560 int err;
7561 PyObject *cdata_py = Py_None;
7562 DBT cdata;
7563 int flags;
7564 static char* kwnames[] = {"flags","cdata", NULL};
7565
7566 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
7567 "i|O:rep_start", kwnames, &flags, &cdata_py))
7568 {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00007569 return NULL;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007570 }
7571 CHECK_ENV_NOT_CLOSED(self);
7572
7573 if (!make_dbt(cdata_py, &cdata))
7574 return NULL;
7575
7576 MYDB_BEGIN_ALLOW_THREADS;
7577 err = self->db_env->rep_start(self->db_env, cdata.size ? &cdata : NULL,
7578 flags);
7579 MYDB_END_ALLOW_THREADS;
7580 RETURN_IF_ERR();
7581 RETURN_NONE();
7582}
7583
7584#if (DBVER >= 44)
7585static PyObject*
7586DBEnv_rep_sync(DBEnvObject* self)
7587{
7588 int err;
7589
7590 CHECK_ENV_NOT_CLOSED(self);
7591 MYDB_BEGIN_ALLOW_THREADS;
7592 err = self->db_env->rep_sync(self->db_env, 0);
7593 MYDB_END_ALLOW_THREADS;
7594 RETURN_IF_ERR();
7595 RETURN_NONE();
7596}
7597#endif
7598
7599
Jesus Ceaef9764f2008-05-13 18:45:46 +00007600#if (DBVER >= 45)
7601static PyObject*
7602DBEnv_rep_set_nsites(DBEnvObject* self, PyObject* args)
7603{
7604 int err;
7605 int nsites;
7606
7607 if (!PyArg_ParseTuple(args, "i:rep_set_nsites", &nsites)) {
7608 return NULL;
7609 }
7610 CHECK_ENV_NOT_CLOSED(self);
7611 MYDB_BEGIN_ALLOW_THREADS;
7612 err = self->db_env->rep_set_nsites(self->db_env, nsites);
7613 MYDB_END_ALLOW_THREADS;
7614 RETURN_IF_ERR();
7615 RETURN_NONE();
7616}
7617
7618static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007619DBEnv_rep_get_nsites(DBEnvObject* self)
Jesus Ceaef9764f2008-05-13 18:45:46 +00007620{
7621 int err;
Jesus Ceaca3939c2008-05-22 15:27:38 +00007622#if (DBVER >= 47)
7623 u_int32_t nsites;
7624#else
Jesus Ceaef9764f2008-05-13 18:45:46 +00007625 int nsites;
Jesus Ceaca3939c2008-05-22 15:27:38 +00007626#endif
Jesus Ceaef9764f2008-05-13 18:45:46 +00007627
Jesus Ceaef9764f2008-05-13 18:45:46 +00007628 CHECK_ENV_NOT_CLOSED(self);
7629 MYDB_BEGIN_ALLOW_THREADS;
7630 err = self->db_env->rep_get_nsites(self->db_env, &nsites);
7631 MYDB_END_ALLOW_THREADS;
7632 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007633 return NUMBER_FromLong(nsites);
Jesus Ceaef9764f2008-05-13 18:45:46 +00007634}
7635
7636static PyObject*
7637DBEnv_rep_set_priority(DBEnvObject* self, PyObject* args)
7638{
7639 int err;
7640 int priority;
7641
7642 if (!PyArg_ParseTuple(args, "i:rep_set_priority", &priority)) {
7643 return NULL;
7644 }
7645 CHECK_ENV_NOT_CLOSED(self);
7646 MYDB_BEGIN_ALLOW_THREADS;
7647 err = self->db_env->rep_set_priority(self->db_env, priority);
7648 MYDB_END_ALLOW_THREADS;
7649 RETURN_IF_ERR();
7650 RETURN_NONE();
7651}
7652
7653static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007654DBEnv_rep_get_priority(DBEnvObject* self)
Jesus Ceaef9764f2008-05-13 18:45:46 +00007655{
7656 int err;
Jesus Ceaca3939c2008-05-22 15:27:38 +00007657#if (DBVER >= 47)
7658 u_int32_t priority;
7659#else
Jesus Ceaef9764f2008-05-13 18:45:46 +00007660 int priority;
Jesus Ceaca3939c2008-05-22 15:27:38 +00007661#endif
Jesus Ceaef9764f2008-05-13 18:45:46 +00007662
Jesus Ceaef9764f2008-05-13 18:45:46 +00007663 CHECK_ENV_NOT_CLOSED(self);
7664 MYDB_BEGIN_ALLOW_THREADS;
7665 err = self->db_env->rep_get_priority(self->db_env, &priority);
7666 MYDB_END_ALLOW_THREADS;
7667 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007668 return NUMBER_FromLong(priority);
Jesus Ceaef9764f2008-05-13 18:45:46 +00007669}
7670
7671static PyObject*
7672DBEnv_rep_set_timeout(DBEnvObject* self, PyObject* args)
7673{
7674 int err;
7675 int which, timeout;
7676
7677 if (!PyArg_ParseTuple(args, "ii:rep_set_timeout", &which, &timeout)) {
7678 return NULL;
7679 }
7680 CHECK_ENV_NOT_CLOSED(self);
7681 MYDB_BEGIN_ALLOW_THREADS;
7682 err = self->db_env->rep_set_timeout(self->db_env, which, timeout);
7683 MYDB_END_ALLOW_THREADS;
7684 RETURN_IF_ERR();
7685 RETURN_NONE();
7686}
7687
7688static PyObject*
7689DBEnv_rep_get_timeout(DBEnvObject* self, PyObject* args)
7690{
7691 int err;
7692 int which;
7693 u_int32_t timeout;
7694
7695 if (!PyArg_ParseTuple(args, "i:rep_get_timeout", &which)) {
7696 return NULL;
7697 }
7698 CHECK_ENV_NOT_CLOSED(self);
7699 MYDB_BEGIN_ALLOW_THREADS;
7700 err = self->db_env->rep_get_timeout(self->db_env, which, &timeout);
7701 MYDB_END_ALLOW_THREADS;
7702 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007703 return NUMBER_FromLong(timeout);
Jesus Ceaef9764f2008-05-13 18:45:46 +00007704}
7705#endif
7706
Jesus Cea6557aac2010-03-22 14:22:26 +00007707
7708#if (DBVER >= 47)
7709static PyObject*
7710DBEnv_rep_set_clockskew(DBEnvObject* self, PyObject* args)
7711{
7712 int err;
7713 unsigned int fast, slow;
7714
Jesus Cea6557aac2010-03-22 14:22:26 +00007715 if (!PyArg_ParseTuple(args,"II:rep_set_clockskew", &fast, &slow))
7716 return NULL;
Jesus Cea6557aac2010-03-22 14:22:26 +00007717
7718 CHECK_ENV_NOT_CLOSED(self);
7719
7720 MYDB_BEGIN_ALLOW_THREADS;
7721 err = self->db_env->rep_set_clockskew(self->db_env, fast, slow);
7722 MYDB_END_ALLOW_THREADS;
7723 RETURN_IF_ERR();
7724 RETURN_NONE();
7725}
7726
7727static PyObject*
7728DBEnv_rep_get_clockskew(DBEnvObject* self)
7729{
7730 int err;
7731 unsigned int fast, slow;
7732
7733 CHECK_ENV_NOT_CLOSED(self);
7734 MYDB_BEGIN_ALLOW_THREADS;
7735 err = self->db_env->rep_get_clockskew(self->db_env, &fast, &slow);
7736 MYDB_END_ALLOW_THREADS;
7737 RETURN_IF_ERR();
Jesus Cea6557aac2010-03-22 14:22:26 +00007738 return Py_BuildValue("(II)", fast, slow);
Jesus Cea6557aac2010-03-22 14:22:26 +00007739}
7740#endif
7741
Jesus Cea6557aac2010-03-22 14:22:26 +00007742static PyObject*
7743DBEnv_rep_stat_print(DBEnvObject* self, PyObject* args, PyObject *kwargs)
7744{
7745 int err;
7746 int flags=0;
7747 static char* kwnames[] = { "flags", NULL };
7748
7749 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:rep_stat_print",
7750 kwnames, &flags))
7751 {
7752 return NULL;
7753 }
7754 CHECK_ENV_NOT_CLOSED(self);
7755 MYDB_BEGIN_ALLOW_THREADS;
7756 err = self->db_env->rep_stat_print(self->db_env, flags);
7757 MYDB_END_ALLOW_THREADS;
7758 RETURN_IF_ERR();
7759 RETURN_NONE();
7760}
Jesus Cea6557aac2010-03-22 14:22:26 +00007761
7762static PyObject*
7763DBEnv_rep_stat(DBEnvObject* self, PyObject* args, PyObject *kwargs)
7764{
7765 int err;
7766 int flags=0;
7767 DB_REP_STAT *statp;
7768 PyObject *stats;
7769 static char* kwnames[] = { "flags", NULL };
7770
7771 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:rep_stat",
7772 kwnames, &flags))
7773 {
7774 return NULL;
7775 }
7776 CHECK_ENV_NOT_CLOSED(self);
7777 MYDB_BEGIN_ALLOW_THREADS;
7778 err = self->db_env->rep_stat(self->db_env, &statp, flags);
7779 MYDB_END_ALLOW_THREADS;
7780 RETURN_IF_ERR();
7781
7782 stats=PyDict_New();
7783 if (stats == NULL) {
7784 free(statp);
7785 return NULL;
7786 }
7787
7788#define MAKE_ENTRY(name) _addIntToDict(stats, #name, statp->st_##name)
7789#define MAKE_DB_LSN_ENTRY(name) _addDB_lsnToDict(stats , #name, statp->st_##name)
7790
7791#if (DBVER >= 44)
7792 MAKE_ENTRY(bulk_fills);
7793 MAKE_ENTRY(bulk_overflows);
7794 MAKE_ENTRY(bulk_records);
7795 MAKE_ENTRY(bulk_transfers);
7796 MAKE_ENTRY(client_rerequests);
7797 MAKE_ENTRY(client_svc_miss);
7798 MAKE_ENTRY(client_svc_req);
7799#endif
7800 MAKE_ENTRY(dupmasters);
Jesus Cea6557aac2010-03-22 14:22:26 +00007801 MAKE_ENTRY(egen);
7802 MAKE_ENTRY(election_nvotes);
7803 MAKE_ENTRY(startup_complete);
7804 MAKE_ENTRY(pg_duplicated);
7805 MAKE_ENTRY(pg_records);
7806 MAKE_ENTRY(pg_requested);
7807 MAKE_ENTRY(next_pg);
7808 MAKE_ENTRY(waiting_pg);
Jesus Cea6557aac2010-03-22 14:22:26 +00007809 MAKE_ENTRY(election_cur_winner);
7810 MAKE_ENTRY(election_gen);
7811 MAKE_DB_LSN_ENTRY(election_lsn);
7812 MAKE_ENTRY(election_nsites);
7813 MAKE_ENTRY(election_priority);
7814#if (DBVER >= 44)
7815 MAKE_ENTRY(election_sec);
7816 MAKE_ENTRY(election_usec);
7817#endif
7818 MAKE_ENTRY(election_status);
7819 MAKE_ENTRY(election_tiebreaker);
7820 MAKE_ENTRY(election_votes);
7821 MAKE_ENTRY(elections);
7822 MAKE_ENTRY(elections_won);
7823 MAKE_ENTRY(env_id);
7824 MAKE_ENTRY(env_priority);
7825 MAKE_ENTRY(gen);
7826 MAKE_ENTRY(log_duplicated);
7827 MAKE_ENTRY(log_queued);
7828 MAKE_ENTRY(log_queued_max);
7829 MAKE_ENTRY(log_queued_total);
7830 MAKE_ENTRY(log_records);
7831 MAKE_ENTRY(log_requested);
7832 MAKE_ENTRY(master);
7833 MAKE_ENTRY(master_changes);
7834#if (DBVER >= 47)
7835 MAKE_ENTRY(max_lease_sec);
7836 MAKE_ENTRY(max_lease_usec);
7837 MAKE_DB_LSN_ENTRY(max_perm_lsn);
7838#endif
7839 MAKE_ENTRY(msgs_badgen);
7840 MAKE_ENTRY(msgs_processed);
7841 MAKE_ENTRY(msgs_recover);
7842 MAKE_ENTRY(msgs_send_failures);
7843 MAKE_ENTRY(msgs_sent);
7844 MAKE_ENTRY(newsites);
7845 MAKE_DB_LSN_ENTRY(next_lsn);
7846 MAKE_ENTRY(nsites);
7847 MAKE_ENTRY(nthrottles);
7848 MAKE_ENTRY(outdated);
7849#if (DBVER >= 46)
7850 MAKE_ENTRY(startsync_delayed);
7851#endif
7852 MAKE_ENTRY(status);
7853 MAKE_ENTRY(txns_applied);
7854 MAKE_DB_LSN_ENTRY(waiting_lsn);
7855
7856#undef MAKE_DB_LSN_ENTRY
7857#undef MAKE_ENTRY
7858
7859 free(statp);
7860 return stats;
7861}
7862
Jesus Ceaef9764f2008-05-13 18:45:46 +00007863/* --------------------------------------------------------------------- */
7864/* REPLICATION METHODS: Replication Manager */
7865
7866#if (DBVER >= 45)
7867static PyObject*
7868DBEnv_repmgr_start(DBEnvObject* self, PyObject* args, PyObject*
7869 kwargs)
7870{
7871 int err;
7872 int nthreads, flags;
7873 static char* kwnames[] = {"nthreads","flags", NULL};
7874
7875 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
7876 "ii:repmgr_start", kwnames, &nthreads, &flags))
7877 {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00007878 return NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00007879 }
7880 CHECK_ENV_NOT_CLOSED(self);
7881 MYDB_BEGIN_ALLOW_THREADS;
7882 err = self->db_env->repmgr_start(self->db_env, nthreads, flags);
7883 MYDB_END_ALLOW_THREADS;
7884 RETURN_IF_ERR();
7885 RETURN_NONE();
7886}
7887
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07007888#if (DBVER < 52)
Jesus Ceaef9764f2008-05-13 18:45:46 +00007889static PyObject*
7890DBEnv_repmgr_set_local_site(DBEnvObject* self, PyObject* args, PyObject*
7891 kwargs)
7892{
7893 int err;
7894 char *host;
7895 int port;
7896 int flags = 0;
7897 static char* kwnames[] = {"host", "port", "flags", NULL};
7898
7899 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
7900 "si|i:repmgr_set_local_site", kwnames, &host, &port, &flags))
7901 {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00007902 return NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00007903 }
7904 CHECK_ENV_NOT_CLOSED(self);
7905 MYDB_BEGIN_ALLOW_THREADS;
7906 err = self->db_env->repmgr_set_local_site(self->db_env, host, port, flags);
7907 MYDB_END_ALLOW_THREADS;
7908 RETURN_IF_ERR();
7909 RETURN_NONE();
7910}
7911
7912static PyObject*
7913DBEnv_repmgr_add_remote_site(DBEnvObject* self, PyObject* args, PyObject*
7914 kwargs)
7915{
7916 int err;
7917 char *host;
7918 int port;
7919 int flags = 0;
7920 int eidp;
7921 static char* kwnames[] = {"host", "port", "flags", NULL};
7922
7923 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
7924 "si|i:repmgr_add_remote_site", kwnames, &host, &port, &flags))
7925 {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00007926 return NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00007927 }
7928 CHECK_ENV_NOT_CLOSED(self);
7929 MYDB_BEGIN_ALLOW_THREADS;
7930 err = self->db_env->repmgr_add_remote_site(self->db_env, host, port, &eidp, flags);
7931 MYDB_END_ALLOW_THREADS;
7932 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007933 return NUMBER_FromLong(eidp);
Jesus Ceaef9764f2008-05-13 18:45:46 +00007934}
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07007935#endif
Jesus Ceaef9764f2008-05-13 18:45:46 +00007936
7937static PyObject*
7938DBEnv_repmgr_set_ack_policy(DBEnvObject* self, PyObject* args)
7939{
7940 int err;
7941 int ack_policy;
7942
7943 if (!PyArg_ParseTuple(args, "i:repmgr_set_ack_policy", &ack_policy))
7944 {
Antoine Pitrouc83ea132010-05-09 14:46:46 +00007945 return NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00007946 }
7947 CHECK_ENV_NOT_CLOSED(self);
7948 MYDB_BEGIN_ALLOW_THREADS;
7949 err = self->db_env->repmgr_set_ack_policy(self->db_env, ack_policy);
7950 MYDB_END_ALLOW_THREADS;
7951 RETURN_IF_ERR();
7952 RETURN_NONE();
7953}
7954
7955static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007956DBEnv_repmgr_get_ack_policy(DBEnvObject* self)
Jesus Ceaef9764f2008-05-13 18:45:46 +00007957{
7958 int err;
7959 int ack_policy;
7960
Jesus Ceaef9764f2008-05-13 18:45:46 +00007961 CHECK_ENV_NOT_CLOSED(self);
7962 MYDB_BEGIN_ALLOW_THREADS;
7963 err = self->db_env->repmgr_get_ack_policy(self->db_env, &ack_policy);
7964 MYDB_END_ALLOW_THREADS;
7965 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007966 return NUMBER_FromLong(ack_policy);
Jesus Ceaef9764f2008-05-13 18:45:46 +00007967}
7968
7969static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007970DBEnv_repmgr_site_list(DBEnvObject* self)
Jesus Ceaef9764f2008-05-13 18:45:46 +00007971{
7972 int err;
7973 unsigned int countp;
7974 DB_REPMGR_SITE *listp;
7975 PyObject *stats, *key, *tuple;
7976
Jesus Ceaef9764f2008-05-13 18:45:46 +00007977 CHECK_ENV_NOT_CLOSED(self);
7978 MYDB_BEGIN_ALLOW_THREADS;
7979 err = self->db_env->repmgr_site_list(self->db_env, &countp, &listp);
7980 MYDB_END_ALLOW_THREADS;
7981 RETURN_IF_ERR();
7982
7983 stats=PyDict_New();
7984 if (stats == NULL) {
7985 free(listp);
7986 return NULL;
7987 }
7988
7989 for(;countp--;) {
Jesus Ceac5a11fa2008-07-23 11:38:42 +00007990 key=NUMBER_FromLong(listp[countp].eid);
Jesus Ceaef9764f2008-05-13 18:45:46 +00007991 if(!key) {
7992 Py_DECREF(stats);
7993 free(listp);
7994 return NULL;
7995 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00007996 tuple=Py_BuildValue("(sII)", listp[countp].host,
7997 listp[countp].port, listp[countp].status);
Jesus Ceaef9764f2008-05-13 18:45:46 +00007998 if(!tuple) {
7999 Py_DECREF(key);
8000 Py_DECREF(stats);
8001 free(listp);
8002 return NULL;
8003 }
8004 if(PyDict_SetItem(stats, key, tuple)) {
8005 Py_DECREF(key);
8006 Py_DECREF(tuple);
8007 Py_DECREF(stats);
8008 free(listp);
8009 return NULL;
8010 }
Florent Xiclunae7901c52010-03-01 20:45:01 +00008011 Py_DECREF(key);
8012 Py_DECREF(tuple);
Jesus Ceaef9764f2008-05-13 18:45:46 +00008013 }
8014 free(listp);
8015 return stats;
8016}
8017#endif
8018
8019#if (DBVER >= 46)
8020static PyObject*
8021DBEnv_repmgr_stat_print(DBEnvObject* self, PyObject* args, PyObject *kwargs)
8022{
8023 int err;
8024 int flags=0;
8025 static char* kwnames[] = { "flags", NULL };
8026
8027 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:repmgr_stat_print",
8028 kwnames, &flags))
8029 {
8030 return NULL;
8031 }
8032 CHECK_ENV_NOT_CLOSED(self);
8033 MYDB_BEGIN_ALLOW_THREADS;
8034 err = self->db_env->repmgr_stat_print(self->db_env, flags);
8035 MYDB_END_ALLOW_THREADS;
8036 RETURN_IF_ERR();
8037 RETURN_NONE();
8038}
8039
8040static PyObject*
8041DBEnv_repmgr_stat(DBEnvObject* self, PyObject* args, PyObject *kwargs)
8042{
8043 int err;
8044 int flags=0;
8045 DB_REPMGR_STAT *statp;
8046 PyObject *stats;
8047 static char* kwnames[] = { "flags", NULL };
8048
8049 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:repmgr_stat",
8050 kwnames, &flags))
8051 {
8052 return NULL;
8053 }
8054 CHECK_ENV_NOT_CLOSED(self);
8055 MYDB_BEGIN_ALLOW_THREADS;
8056 err = self->db_env->repmgr_stat(self->db_env, &statp, flags);
8057 MYDB_END_ALLOW_THREADS;
8058 RETURN_IF_ERR();
8059
8060 stats=PyDict_New();
8061 if (stats == NULL) {
8062 free(statp);
8063 return NULL;
8064 }
8065
8066#define MAKE_ENTRY(name) _addIntToDict(stats, #name, statp->st_##name)
8067
8068 MAKE_ENTRY(perm_failed);
8069 MAKE_ENTRY(msgs_queued);
8070 MAKE_ENTRY(msgs_dropped);
8071 MAKE_ENTRY(connection_drop);
8072 MAKE_ENTRY(connect_fail);
8073
8074#undef MAKE_ENTRY
8075
8076 free(statp);
8077 return stats;
8078}
8079#endif
8080
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008081
8082/* --------------------------------------------------------------------- */
8083/* DBTxn methods */
8084
8085
Jesus Ceaef9764f2008-05-13 18:45:46 +00008086static void _close_transaction_cursors(DBTxnObject* txn)
8087{
8088 PyObject *dummy;
8089
8090 while(txn->children_cursors) {
8091 PyErr_Warn(PyExc_RuntimeWarning,
8092 "Must close cursors before resolving a transaction.");
8093 dummy=DBC_close_internal(txn->children_cursors);
8094 Py_XDECREF(dummy);
8095 }
8096}
8097
8098static void _promote_transaction_dbs_and_sequences(DBTxnObject *txn)
8099{
8100 DBObject *db;
Jesus Ceaef9764f2008-05-13 18:45:46 +00008101 DBSequenceObject *dbs;
Jesus Ceaef9764f2008-05-13 18:45:46 +00008102
8103 while (txn->children_dbs) {
8104 db=txn->children_dbs;
8105 EXTRACT_FROM_DOUBLE_LINKED_LIST_TXN(db);
8106 if (txn->parent_txn) {
8107 INSERT_IN_DOUBLE_LINKED_LIST_TXN(txn->parent_txn->children_dbs,db);
8108 db->txn=txn->parent_txn;
8109 } else {
8110 /* The db is already linked to its environment,
8111 ** so nothing to do.
8112 */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00008113 db->txn=NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00008114 }
8115 }
8116
Jesus Ceaef9764f2008-05-13 18:45:46 +00008117 while (txn->children_sequences) {
8118 dbs=txn->children_sequences;
8119 EXTRACT_FROM_DOUBLE_LINKED_LIST_TXN(dbs);
8120 if (txn->parent_txn) {
8121 INSERT_IN_DOUBLE_LINKED_LIST_TXN(txn->parent_txn->children_sequences,dbs);
8122 dbs->txn=txn->parent_txn;
8123 } else {
8124 /* The sequence is already linked to its
8125 ** parent db. Nothing to do.
8126 */
8127 dbs->txn=NULL;
8128 }
8129 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00008130}
8131
8132
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008133static PyObject*
8134DBTxn_commit(DBTxnObject* self, PyObject* args)
8135{
8136 int flags=0, err;
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008137 DB_TXN *txn;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008138
8139 if (!PyArg_ParseTuple(args, "|i:commit", &flags))
8140 return NULL;
8141
Jesus Ceaef9764f2008-05-13 18:45:46 +00008142 _close_transaction_cursors(self);
8143
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008144 if (!self->txn) {
Thomas Woutersb3153832006-03-08 01:47:19 +00008145 PyObject *t = Py_BuildValue("(is)", 0, "DBTxn must not be used "
Jesus Ceaef9764f2008-05-13 18:45:46 +00008146 "after txn_commit, txn_abort "
8147 "or txn_discard");
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008148 if (t) {
8149 PyErr_SetObject(DBError, t);
8150 Py_DECREF(t);
8151 }
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008152 return NULL;
8153 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00008154 self->flag_prepare=0;
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008155 txn = self->txn;
8156 self->txn = NULL; /* this DB_TXN is no longer valid after this call */
Jesus Ceaef9764f2008-05-13 18:45:46 +00008157
8158 EXTRACT_FROM_DOUBLE_LINKED_LIST(self);
8159
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008160 MYDB_BEGIN_ALLOW_THREADS;
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008161 err = txn->commit(txn, flags);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008162 MYDB_END_ALLOW_THREADS;
Jesus Ceaef9764f2008-05-13 18:45:46 +00008163
8164 _promote_transaction_dbs_and_sequences(self);
8165
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008166 RETURN_IF_ERR();
8167 RETURN_NONE();
8168}
8169
8170static PyObject*
8171DBTxn_prepare(DBTxnObject* self, PyObject* args)
8172{
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008173 int err;
8174 char* gid=NULL;
8175 int gid_size=0;
8176
8177 if (!PyArg_ParseTuple(args, "s#:prepare", &gid, &gid_size))
8178 return NULL;
8179
Matthias Klose54cc5392010-03-15 12:46:18 +00008180 if (gid_size != DB_GID_SIZE) {
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008181 PyErr_SetString(PyExc_TypeError,
Matthias Klose54cc5392010-03-15 12:46:18 +00008182 "gid must be DB_GID_SIZE bytes long");
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008183 return NULL;
8184 }
8185
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008186 if (!self->txn) {
Thomas Woutersb3153832006-03-08 01:47:19 +00008187 PyObject *t = Py_BuildValue("(is)", 0,"DBTxn must not be used "
Jesus Ceaef9764f2008-05-13 18:45:46 +00008188 "after txn_commit, txn_abort "
8189 "or txn_discard");
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008190 if (t) {
8191 PyErr_SetObject(DBError, t);
8192 Py_DECREF(t);
8193 }
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008194 return NULL;
8195 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00008196 self->flag_prepare=1; /* Prepare state */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008197 MYDB_BEGIN_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008198 err = self->txn->prepare(self->txn, (u_int8_t*)gid);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008199 MYDB_END_ALLOW_THREADS;
8200 RETURN_IF_ERR();
8201 RETURN_NONE();
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008202}
8203
8204
8205static PyObject*
Jesus Ceaef9764f2008-05-13 18:45:46 +00008206DBTxn_abort_discard_internal(DBTxnObject* self, int discard)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008207{
Jesus Ceaef9764f2008-05-13 18:45:46 +00008208 PyObject *dummy;
8209 int err=0;
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008210 DB_TXN *txn;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008211
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008212 if (!self->txn) {
Thomas Woutersb3153832006-03-08 01:47:19 +00008213 PyObject *t = Py_BuildValue("(is)", 0, "DBTxn must not be used "
Jesus Ceaef9764f2008-05-13 18:45:46 +00008214 "after txn_commit, txn_abort "
8215 "or txn_discard");
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008216 if (t) {
8217 PyErr_SetObject(DBError, t);
8218 Py_DECREF(t);
8219 }
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008220 return NULL;
8221 }
8222 txn = self->txn;
8223 self->txn = NULL; /* this DB_TXN is no longer valid after this call */
Jesus Ceaef9764f2008-05-13 18:45:46 +00008224
8225 _close_transaction_cursors(self);
Jesus Ceaef9764f2008-05-13 18:45:46 +00008226 while (self->children_sequences) {
8227 dummy=DBSequence_close_internal(self->children_sequences,0,0);
8228 Py_XDECREF(dummy);
8229 }
Jesus Ceaef9764f2008-05-13 18:45:46 +00008230 while (self->children_dbs) {
Jesus Cea5cd5f122008-09-23 18:54:08 +00008231 dummy=DB_close_internal(self->children_dbs, 0, 0);
Jesus Ceaef9764f2008-05-13 18:45:46 +00008232 Py_XDECREF(dummy);
8233 }
8234
8235 EXTRACT_FROM_DOUBLE_LINKED_LIST(self);
8236
8237 MYDB_BEGIN_ALLOW_THREADS;
8238 if (discard) {
8239 assert(!self->flag_prepare);
Jesus Ceaef9764f2008-05-13 18:45:46 +00008240 err = txn->discard(txn,0);
Jesus Ceaef9764f2008-05-13 18:45:46 +00008241 } else {
8242 /*
8243 ** If the transaction is in the "prepare" or "recover" state,
8244 ** we better do not implicitly abort it.
8245 */
8246 if (!self->flag_prepare) {
Jesus Ceaef9764f2008-05-13 18:45:46 +00008247 err = txn->abort(txn);
Jesus Ceaef9764f2008-05-13 18:45:46 +00008248 }
8249 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008250 MYDB_END_ALLOW_THREADS;
8251 RETURN_IF_ERR();
8252 RETURN_NONE();
8253}
8254
Jesus Ceaef9764f2008-05-13 18:45:46 +00008255static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008256DBTxn_abort(DBTxnObject* self)
Jesus Ceaef9764f2008-05-13 18:45:46 +00008257{
Jesus Ceaef9764f2008-05-13 18:45:46 +00008258 self->flag_prepare=0;
8259 _close_transaction_cursors(self);
8260
8261 return DBTxn_abort_discard_internal(self,0);
8262}
8263
8264static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008265DBTxn_discard(DBTxnObject* self)
Jesus Ceaef9764f2008-05-13 18:45:46 +00008266{
Jesus Ceaef9764f2008-05-13 18:45:46 +00008267 self->flag_prepare=0;
8268 _close_transaction_cursors(self);
8269
8270 return DBTxn_abort_discard_internal(self,1);
8271}
8272
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008273
8274static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008275DBTxn_id(DBTxnObject* self)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008276{
8277 int id;
8278
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008279 if (!self->txn) {
Thomas Woutersb3153832006-03-08 01:47:19 +00008280 PyObject *t = Py_BuildValue("(is)", 0, "DBTxn must not be used "
Jesus Ceaef9764f2008-05-13 18:45:46 +00008281 "after txn_commit, txn_abort "
8282 "or txn_discard");
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008283 if (t) {
8284 PyErr_SetObject(DBError, t);
8285 Py_DECREF(t);
8286 }
Gregory P. Smithc25fd3f2003-01-17 07:52:59 +00008287 return NULL;
8288 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008289 MYDB_BEGIN_ALLOW_THREADS;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008290 id = self->txn->id(self->txn);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008291 MYDB_END_ALLOW_THREADS;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008292 return NUMBER_FromLong(id);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008293}
8294
Jesus Cea6557aac2010-03-22 14:22:26 +00008295
8296static PyObject*
8297DBTxn_set_timeout(DBTxnObject* self, PyObject* args, PyObject* kwargs)
8298{
8299 int err;
8300 u_int32_t flags=0;
8301 u_int32_t timeout = 0;
8302 static char* kwnames[] = { "timeout", "flags", NULL };
8303
8304 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "ii:set_timeout", kwnames,
Antoine Pitrouc83ea132010-05-09 14:46:46 +00008305 &timeout, &flags)) {
8306 return NULL;
Jesus Cea6557aac2010-03-22 14:22:26 +00008307 }
8308
8309 MYDB_BEGIN_ALLOW_THREADS;
8310 err = self->txn->set_timeout(self->txn, (db_timeout_t)timeout, flags);
8311 MYDB_END_ALLOW_THREADS;
8312
8313 RETURN_IF_ERR();
8314 RETURN_NONE();
8315}
8316
8317
8318#if (DBVER >= 44)
8319static PyObject*
8320DBTxn_set_name(DBTxnObject* self, PyObject* args)
8321{
8322 int err;
8323 const char *name;
8324
8325 if (!PyArg_ParseTuple(args, "s:set_name", &name))
8326 return NULL;
8327
8328 MYDB_BEGIN_ALLOW_THREADS;
8329 err = self->txn->set_name(self->txn, name);
8330 MYDB_END_ALLOW_THREADS;
8331
8332 RETURN_IF_ERR();
8333 RETURN_NONE();
8334}
8335#endif
8336
8337
8338#if (DBVER >= 44)
8339static PyObject*
8340DBTxn_get_name(DBTxnObject* self)
8341{
8342 int err;
8343 const char *name;
8344
8345 MYDB_BEGIN_ALLOW_THREADS;
8346 err = self->txn->get_name(self->txn, &name);
8347 MYDB_END_ALLOW_THREADS;
8348
8349 RETURN_IF_ERR();
8350#if (PY_VERSION_HEX < 0x03000000)
8351 if (!name) {
8352 return PyString_FromString("");
8353 }
8354 return PyString_FromString(name);
8355#else
8356 if (!name) {
8357 return PyUnicode_FromString("");
8358 }
8359 return PyUnicode_FromString(name);
8360#endif
8361}
8362#endif
8363
8364
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008365/* --------------------------------------------------------------------- */
8366/* DBSequence methods */
8367
8368
8369static PyObject*
Jesus Ceaef9764f2008-05-13 18:45:46 +00008370DBSequence_close_internal(DBSequenceObject* self, int flags, int do_not_close)
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008371{
Jesus Ceaef9764f2008-05-13 18:45:46 +00008372 int err=0;
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008373
Jesus Ceaef9764f2008-05-13 18:45:46 +00008374 if (self->sequence!=NULL) {
8375 EXTRACT_FROM_DOUBLE_LINKED_LIST(self);
8376 if (self->txn) {
8377 EXTRACT_FROM_DOUBLE_LINKED_LIST_TXN(self);
8378 self->txn=NULL;
8379 }
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008380
Jesus Cea5cd5f122008-09-23 18:54:08 +00008381 /*
8382 ** "do_not_close" is used to dispose all related objects in the
8383 ** tree, without actually releasing the "root" object.
8384 ** This is done, for example, because function calls like
8385 ** "DBSequence.remove()" implicitly close the underlying handle. So
8386 ** the handle doesn't need to be closed, but related objects
8387 ** must be cleaned up.
8388 */
Jesus Ceaef9764f2008-05-13 18:45:46 +00008389 if (!do_not_close) {
8390 MYDB_BEGIN_ALLOW_THREADS
8391 err = self->sequence->close(self->sequence, flags);
8392 MYDB_END_ALLOW_THREADS
8393 }
8394 self->sequence = NULL;
8395
8396 RETURN_IF_ERR();
8397 }
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008398
8399 RETURN_NONE();
8400}
8401
8402static PyObject*
Jesus Ceaef9764f2008-05-13 18:45:46 +00008403DBSequence_close(DBSequenceObject* self, PyObject* args)
8404{
8405 int flags=0;
8406 if (!PyArg_ParseTuple(args,"|i:close", &flags))
8407 return NULL;
8408
8409 return DBSequence_close_internal(self,flags,0);
8410}
8411
8412static PyObject*
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008413DBSequence_get(DBSequenceObject* self, PyObject* args, PyObject* kwargs)
8414{
8415 int err, flags = 0;
8416 int delta = 1;
8417 db_seq_t value;
8418 PyObject *txnobj = NULL;
8419 DB_TXN *txn = NULL;
8420 static char* kwnames[] = {"delta", "txn", "flags", NULL };
8421 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|iOi:get", kwnames, &delta, &txnobj, &flags))
8422 return NULL;
8423 CHECK_SEQUENCE_NOT_CLOSED(self)
8424
8425 if (!checkTxnObj(txnobj, &txn))
8426 return NULL;
8427
8428 MYDB_BEGIN_ALLOW_THREADS
8429 err = self->sequence->get(self->sequence, txn, delta, &value, flags);
8430 MYDB_END_ALLOW_THREADS
8431
8432 RETURN_IF_ERR();
8433 return PyLong_FromLongLong(value);
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008434}
8435
8436static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008437DBSequence_get_dbp(DBSequenceObject* self)
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008438{
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008439 CHECK_SEQUENCE_NOT_CLOSED(self)
8440 Py_INCREF(self->mydb);
8441 return (PyObject* )self->mydb;
8442}
8443
8444static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008445DBSequence_get_key(DBSequenceObject* self)
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008446{
8447 int err;
8448 DBT key;
Neal Norwitz088beae2007-10-12 03:01:54 +00008449 PyObject *retval = NULL;
Jesus Ceaef9764f2008-05-13 18:45:46 +00008450
Gregory P. Smithe70be5c2007-10-06 07:48:10 +00008451 key.flags = DB_DBT_MALLOC;
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008452 CHECK_SEQUENCE_NOT_CLOSED(self)
8453 MYDB_BEGIN_ALLOW_THREADS
8454 err = self->sequence->get_key(self->sequence, &key);
8455 MYDB_END_ALLOW_THREADS
8456
Gregory P. Smithe70be5c2007-10-06 07:48:10 +00008457 if (!err)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008458 retval = Build_PyString(key.data, key.size);
Gregory P. Smithe70be5c2007-10-06 07:48:10 +00008459
8460 FREE_DBT(key);
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008461 RETURN_IF_ERR();
8462
Gregory P. Smithe70be5c2007-10-06 07:48:10 +00008463 return retval;
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008464}
8465
8466static PyObject*
Jesus Cea6557aac2010-03-22 14:22:26 +00008467DBSequence_initial_value(DBSequenceObject* self, PyObject* args)
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008468{
8469 int err;
Jesus Ceaef9764f2008-05-13 18:45:46 +00008470 PY_LONG_LONG value;
8471 db_seq_t value2;
Jesus Cea6557aac2010-03-22 14:22:26 +00008472 if (!PyArg_ParseTuple(args,"L:initial_value", &value))
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008473 return NULL;
8474 CHECK_SEQUENCE_NOT_CLOSED(self)
8475
Jesus Ceaef9764f2008-05-13 18:45:46 +00008476 value2=value; /* If truncation, compiler should show a warning */
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008477 MYDB_BEGIN_ALLOW_THREADS
Jesus Ceaef9764f2008-05-13 18:45:46 +00008478 err = self->sequence->initial_value(self->sequence, value2);
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008479 MYDB_END_ALLOW_THREADS
8480
8481 RETURN_IF_ERR();
8482
8483 RETURN_NONE();
8484}
8485
8486static PyObject*
8487DBSequence_open(DBSequenceObject* self, PyObject* args, PyObject* kwargs)
8488{
8489 int err, flags = 0;
8490 PyObject* keyobj;
8491 PyObject *txnobj = NULL;
8492 DB_TXN *txn = NULL;
8493 DBT key;
8494
8495 static char* kwnames[] = {"key", "txn", "flags", NULL };
Neal Norwitzdd2a6bf2006-06-06 07:23:01 +00008496 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|Oi:open", kwnames, &keyobj, &txnobj, &flags))
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008497 return NULL;
8498
8499 if (!checkTxnObj(txnobj, &txn))
8500 return NULL;
8501
8502 if (!make_key_dbt(self->mydb, keyobj, &key, NULL))
8503 return NULL;
8504
8505 MYDB_BEGIN_ALLOW_THREADS
8506 err = self->sequence->open(self->sequence, txn, &key, flags);
8507 MYDB_END_ALLOW_THREADS
8508
Jesus Ceaac25fab2008-09-03 17:50:32 +00008509 FREE_DBT(key);
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008510 RETURN_IF_ERR();
8511
Jesus Ceaef9764f2008-05-13 18:45:46 +00008512 if (txn) {
8513 INSERT_IN_DOUBLE_LINKED_LIST_TXN(((DBTxnObject *)txnobj)->children_sequences,self);
8514 self->txn=(DBTxnObject *)txnobj;
8515 }
8516
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008517 RETURN_NONE();
8518}
8519
8520static PyObject*
8521DBSequence_remove(DBSequenceObject* self, PyObject* args, PyObject* kwargs)
8522{
Jesus Ceaef9764f2008-05-13 18:45:46 +00008523 PyObject *dummy;
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008524 int err, flags = 0;
8525 PyObject *txnobj = NULL;
8526 DB_TXN *txn = NULL;
8527
8528 static char* kwnames[] = {"txn", "flags", NULL };
Neal Norwitzdd2a6bf2006-06-06 07:23:01 +00008529 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Oi:remove", kwnames, &txnobj, &flags))
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008530 return NULL;
8531
8532 if (!checkTxnObj(txnobj, &txn))
8533 return NULL;
8534
8535 CHECK_SEQUENCE_NOT_CLOSED(self)
8536
8537 MYDB_BEGIN_ALLOW_THREADS
8538 err = self->sequence->remove(self->sequence, txn, flags);
8539 MYDB_END_ALLOW_THREADS
8540
Jesus Ceaef9764f2008-05-13 18:45:46 +00008541 dummy=DBSequence_close_internal(self,flags,1);
8542 Py_XDECREF(dummy);
8543
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008544 RETURN_IF_ERR();
8545 RETURN_NONE();
8546}
8547
8548static PyObject*
8549DBSequence_set_cachesize(DBSequenceObject* self, PyObject* args)
8550{
8551 int err, size;
Neal Norwitzdd2a6bf2006-06-06 07:23:01 +00008552 if (!PyArg_ParseTuple(args,"i:set_cachesize", &size))
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008553 return NULL;
8554 CHECK_SEQUENCE_NOT_CLOSED(self)
8555
8556 MYDB_BEGIN_ALLOW_THREADS
8557 err = self->sequence->set_cachesize(self->sequence, size);
8558 MYDB_END_ALLOW_THREADS
8559
8560 RETURN_IF_ERR();
8561 RETURN_NONE();
8562}
8563
8564static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008565DBSequence_get_cachesize(DBSequenceObject* self)
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008566{
8567 int err, size;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008568
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008569 CHECK_SEQUENCE_NOT_CLOSED(self)
8570
8571 MYDB_BEGIN_ALLOW_THREADS
8572 err = self->sequence->get_cachesize(self->sequence, &size);
8573 MYDB_END_ALLOW_THREADS
8574
8575 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008576 return NUMBER_FromLong(size);
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008577}
8578
8579static PyObject*
8580DBSequence_set_flags(DBSequenceObject* self, PyObject* args)
8581{
8582 int err, flags = 0;
Neal Norwitzdd2a6bf2006-06-06 07:23:01 +00008583 if (!PyArg_ParseTuple(args,"i:set_flags", &flags))
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008584 return NULL;
8585 CHECK_SEQUENCE_NOT_CLOSED(self)
8586
8587 MYDB_BEGIN_ALLOW_THREADS
8588 err = self->sequence->set_flags(self->sequence, flags);
8589 MYDB_END_ALLOW_THREADS
8590
8591 RETURN_IF_ERR();
8592 RETURN_NONE();
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008593}
8594
8595static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008596DBSequence_get_flags(DBSequenceObject* self)
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008597{
8598 unsigned int flags;
8599 int err;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008600
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008601 CHECK_SEQUENCE_NOT_CLOSED(self)
8602
8603 MYDB_BEGIN_ALLOW_THREADS
8604 err = self->sequence->get_flags(self->sequence, &flags);
8605 MYDB_END_ALLOW_THREADS
8606
8607 RETURN_IF_ERR();
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008608 return NUMBER_FromLong((int)flags);
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008609}
8610
8611static PyObject*
8612DBSequence_set_range(DBSequenceObject* self, PyObject* args)
8613{
8614 int err;
Jesus Ceaef9764f2008-05-13 18:45:46 +00008615 PY_LONG_LONG min, max;
8616 db_seq_t min2, max2;
Tim Petersbb21b2c2006-06-06 15:50:17 +00008617 if (!PyArg_ParseTuple(args,"(LL):set_range", &min, &max))
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008618 return NULL;
8619 CHECK_SEQUENCE_NOT_CLOSED(self)
8620
Jesus Ceaef9764f2008-05-13 18:45:46 +00008621 min2=min; /* If truncation, compiler should show a warning */
8622 max2=max;
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008623 MYDB_BEGIN_ALLOW_THREADS
Jesus Ceaef9764f2008-05-13 18:45:46 +00008624 err = self->sequence->set_range(self->sequence, min2, max2);
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008625 MYDB_END_ALLOW_THREADS
8626
8627 RETURN_IF_ERR();
8628 RETURN_NONE();
8629}
8630
8631static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008632DBSequence_get_range(DBSequenceObject* self)
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008633{
8634 int err;
Jesus Ceaef9764f2008-05-13 18:45:46 +00008635 PY_LONG_LONG min, max;
8636 db_seq_t min2, max2;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008637
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008638 CHECK_SEQUENCE_NOT_CLOSED(self)
8639
8640 MYDB_BEGIN_ALLOW_THREADS
Jesus Ceaef9764f2008-05-13 18:45:46 +00008641 err = self->sequence->get_range(self->sequence, &min2, &max2);
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008642 MYDB_END_ALLOW_THREADS
8643
8644 RETURN_IF_ERR();
Jesus Ceaef9764f2008-05-13 18:45:46 +00008645 min=min2; /* If truncation, compiler should show a warning */
8646 max=max2;
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008647 return Py_BuildValue("(LL)", min, max);
8648}
8649
Jesus Cea6557aac2010-03-22 14:22:26 +00008650
8651static PyObject*
8652DBSequence_stat_print(DBSequenceObject* self, PyObject* args, PyObject *kwargs)
8653{
8654 int err;
8655 int flags=0;
8656 static char* kwnames[] = { "flags", NULL };
8657
8658 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:stat_print",
8659 kwnames, &flags))
8660 {
8661 return NULL;
8662 }
8663
8664 CHECK_SEQUENCE_NOT_CLOSED(self);
8665
8666 MYDB_BEGIN_ALLOW_THREADS;
8667 err = self->sequence->stat_print(self->sequence, flags);
8668 MYDB_END_ALLOW_THREADS;
8669 RETURN_IF_ERR();
8670 RETURN_NONE();
8671}
8672
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008673static PyObject*
8674DBSequence_stat(DBSequenceObject* self, PyObject* args, PyObject* kwargs)
8675{
8676 int err, flags = 0;
8677 DB_SEQUENCE_STAT* sp = NULL;
8678 PyObject* dict_stat;
8679 static char* kwnames[] = {"flags", NULL };
8680 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i:stat", kwnames, &flags))
8681 return NULL;
8682 CHECK_SEQUENCE_NOT_CLOSED(self);
8683
8684 MYDB_BEGIN_ALLOW_THREADS;
8685 err = self->sequence->stat(self->sequence, &sp, flags);
8686 MYDB_END_ALLOW_THREADS;
8687 RETURN_IF_ERR();
8688
8689 if ((dict_stat = PyDict_New()) == NULL) {
8690 free(sp);
8691 return NULL;
8692 }
8693
8694
8695#define MAKE_INT_ENTRY(name) _addIntToDict(dict_stat, #name, sp->st_##name)
8696#define MAKE_LONG_LONG_ENTRY(name) _addDb_seq_tToDict(dict_stat, #name, sp->st_##name)
8697
8698 MAKE_INT_ENTRY(wait);
8699 MAKE_INT_ENTRY(nowait);
8700 MAKE_LONG_LONG_ENTRY(current);
8701 MAKE_LONG_LONG_ENTRY(value);
8702 MAKE_LONG_LONG_ENTRY(last_value);
8703 MAKE_LONG_LONG_ENTRY(min);
8704 MAKE_LONG_LONG_ENTRY(max);
8705 MAKE_INT_ENTRY(cache_size);
8706 MAKE_INT_ENTRY(flags);
8707
8708#undef MAKE_INT_ENTRY
8709#undef MAKE_LONG_LONG_ENTRY
8710
8711 free(sp);
8712 return dict_stat;
8713}
Gregory P. Smithf0547d02006-06-05 17:38:04 +00008714
8715
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008716/* --------------------------------------------------------------------- */
8717/* Method definition tables and type objects */
8718
8719static PyMethodDef DB_methods[] = {
Jesus Cea4907d272008-08-31 14:00:51 +00008720 {"append", (PyCFunction)DB_append, METH_VARARGS|METH_KEYWORDS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008721 {"associate", (PyCFunction)DB_associate, METH_VARARGS|METH_KEYWORDS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008722 {"close", (PyCFunction)DB_close, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008723#if (DBVER >= 47)
8724 {"compact", (PyCFunction)DB_compact, METH_VARARGS|METH_KEYWORDS},
8725#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008726 {"consume", (PyCFunction)DB_consume, METH_VARARGS|METH_KEYWORDS},
8727 {"consume_wait", (PyCFunction)DB_consume_wait, METH_VARARGS|METH_KEYWORDS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008728 {"cursor", (PyCFunction)DB_cursor, METH_VARARGS|METH_KEYWORDS},
8729 {"delete", (PyCFunction)DB_delete, METH_VARARGS|METH_KEYWORDS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008730 {"fd", (PyCFunction)DB_fd, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008731#if (DBVER >= 46)
8732 {"exists", (PyCFunction)DB_exists,
8733 METH_VARARGS|METH_KEYWORDS},
8734#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008735 {"get", (PyCFunction)DB_get, METH_VARARGS|METH_KEYWORDS},
Gregory P. Smith19699a92004-06-28 04:06:49 +00008736 {"pget", (PyCFunction)DB_pget, METH_VARARGS|METH_KEYWORDS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008737 {"get_both", (PyCFunction)DB_get_both, METH_VARARGS|METH_KEYWORDS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008738 {"get_byteswapped", (PyCFunction)DB_get_byteswapped,METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008739 {"get_size", (PyCFunction)DB_get_size, METH_VARARGS|METH_KEYWORDS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008740 {"get_type", (PyCFunction)DB_get_type, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008741 {"join", (PyCFunction)DB_join, METH_VARARGS},
8742 {"key_range", (PyCFunction)DB_key_range, METH_VARARGS|METH_KEYWORDS},
Jesus Cea4907d272008-08-31 14:00:51 +00008743 {"has_key", (PyCFunction)DB_has_key, METH_VARARGS|METH_KEYWORDS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008744 {"items", (PyCFunction)DB_items, METH_VARARGS},
8745 {"keys", (PyCFunction)DB_keys, METH_VARARGS},
8746 {"open", (PyCFunction)DB_open, METH_VARARGS|METH_KEYWORDS},
8747 {"put", (PyCFunction)DB_put, METH_VARARGS|METH_KEYWORDS},
8748 {"remove", (PyCFunction)DB_remove, METH_VARARGS|METH_KEYWORDS},
8749 {"rename", (PyCFunction)DB_rename, METH_VARARGS},
8750 {"set_bt_minkey", (PyCFunction)DB_set_bt_minkey, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008751 {"get_bt_minkey", (PyCFunction)DB_get_bt_minkey, METH_NOARGS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008752 {"set_bt_compare", (PyCFunction)DB_set_bt_compare, METH_O},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008753 {"set_cachesize", (PyCFunction)DB_set_cachesize, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008754 {"get_cachesize", (PyCFunction)DB_get_cachesize, METH_NOARGS},
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07008755 {"set_dup_compare", (PyCFunction)DB_set_dup_compare, METH_O},
Jesus Cea6557aac2010-03-22 14:22:26 +00008756 {"set_encrypt", (PyCFunction)DB_set_encrypt, METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008757 {"get_encrypt_flags", (PyCFunction)DB_get_encrypt_flags, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008758 {"set_flags", (PyCFunction)DB_set_flags, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008759 {"get_flags", (PyCFunction)DB_get_flags, METH_NOARGS},
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07008760 {"get_transactional", (PyCFunction)DB_get_transactional, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008761 {"set_h_ffactor", (PyCFunction)DB_set_h_ffactor, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008762 {"get_h_ffactor", (PyCFunction)DB_get_h_ffactor, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008763 {"set_h_nelem", (PyCFunction)DB_set_h_nelem, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008764 {"get_h_nelem", (PyCFunction)DB_get_h_nelem, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008765 {"set_lorder", (PyCFunction)DB_set_lorder, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008766 {"get_lorder", (PyCFunction)DB_get_lorder, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008767 {"set_pagesize", (PyCFunction)DB_set_pagesize, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008768 {"get_pagesize", (PyCFunction)DB_get_pagesize, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008769 {"set_re_delim", (PyCFunction)DB_set_re_delim, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008770 {"get_re_delim", (PyCFunction)DB_get_re_delim, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008771 {"set_re_len", (PyCFunction)DB_set_re_len, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008772 {"get_re_len", (PyCFunction)DB_get_re_len, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008773 {"set_re_pad", (PyCFunction)DB_set_re_pad, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008774 {"get_re_pad", (PyCFunction)DB_get_re_pad, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008775 {"set_re_source", (PyCFunction)DB_set_re_source, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008776 {"get_re_source", (PyCFunction)DB_get_re_source, METH_NOARGS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008777 {"set_q_extentsize",(PyCFunction)DB_set_q_extentsize, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008778 {"get_q_extentsize",(PyCFunction)DB_get_q_extentsize, METH_NOARGS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008779 {"set_private", (PyCFunction)DB_set_private, METH_O},
8780 {"get_private", (PyCFunction)DB_get_private, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008781#if (DBVER >= 46)
8782 {"set_priority", (PyCFunction)DB_set_priority, METH_VARARGS},
8783 {"get_priority", (PyCFunction)DB_get_priority, METH_NOARGS},
8784#endif
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07008785 {"get_dbname", (PyCFunction)DB_get_dbname, METH_NOARGS},
8786 {"get_open_flags", (PyCFunction)DB_get_open_flags, METH_NOARGS},
Gregory P. Smith8b7e9172004-12-13 09:51:23 +00008787 {"stat", (PyCFunction)DB_stat, METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008788 {"stat_print", (PyCFunction)DB_stat_print,
8789 METH_VARARGS|METH_KEYWORDS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008790 {"sync", (PyCFunction)DB_sync, METH_VARARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008791 {"truncate", (PyCFunction)DB_truncate, METH_VARARGS|METH_KEYWORDS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008792 {"type", (PyCFunction)DB_get_type, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008793 {"upgrade", (PyCFunction)DB_upgrade, METH_VARARGS},
8794 {"values", (PyCFunction)DB_values, METH_VARARGS},
8795 {"verify", (PyCFunction)DB_verify, METH_VARARGS|METH_KEYWORDS},
8796 {"set_get_returns_none",(PyCFunction)DB_set_get_returns_none, METH_VARARGS},
8797 {NULL, NULL} /* sentinel */
8798};
8799
8800
Jesus Cea6557aac2010-03-22 14:22:26 +00008801/* We need this to support __contains__() */
8802static PySequenceMethods DB_sequence = {
8803 0, /* sq_length, mapping wins here */
8804 0, /* sq_concat */
8805 0, /* sq_repeat */
8806 0, /* sq_item */
8807 0, /* sq_slice */
8808 0, /* sq_ass_item */
8809 0, /* sq_ass_slice */
8810 (objobjproc)DB_contains, /* sq_contains */
8811 0, /* sq_inplace_concat */
8812 0, /* sq_inplace_repeat */
8813};
8814
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008815static PyMappingMethods DB_mapping = {
Martin v. Löwis70ee3cc2006-06-12 04:26:31 +00008816 DB_length, /*mp_length*/
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008817 (binaryfunc)DB_subscript, /*mp_subscript*/
8818 (objobjargproc)DB_ass_sub, /*mp_ass_subscript*/
8819};
8820
8821
8822static PyMethodDef DBCursor_methods[] = {
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008823 {"close", (PyCFunction)DBC_close, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008824 {"count", (PyCFunction)DBC_count, METH_VARARGS},
8825 {"current", (PyCFunction)DBC_current, METH_VARARGS|METH_KEYWORDS},
8826 {"delete", (PyCFunction)DBC_delete, METH_VARARGS},
8827 {"dup", (PyCFunction)DBC_dup, METH_VARARGS},
8828 {"first", (PyCFunction)DBC_first, METH_VARARGS|METH_KEYWORDS},
8829 {"get", (PyCFunction)DBC_get, METH_VARARGS|METH_KEYWORDS},
Gregory P. Smith19699a92004-06-28 04:06:49 +00008830 {"pget", (PyCFunction)DBC_pget, METH_VARARGS|METH_KEYWORDS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008831 {"get_recno", (PyCFunction)DBC_get_recno, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008832 {"last", (PyCFunction)DBC_last, METH_VARARGS|METH_KEYWORDS},
8833 {"next", (PyCFunction)DBC_next, METH_VARARGS|METH_KEYWORDS},
8834 {"prev", (PyCFunction)DBC_prev, METH_VARARGS|METH_KEYWORDS},
8835 {"put", (PyCFunction)DBC_put, METH_VARARGS|METH_KEYWORDS},
8836 {"set", (PyCFunction)DBC_set, METH_VARARGS|METH_KEYWORDS},
8837 {"set_range", (PyCFunction)DBC_set_range, METH_VARARGS|METH_KEYWORDS},
8838 {"get_both", (PyCFunction)DBC_get_both, METH_VARARGS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00008839 {"get_current_size",(PyCFunction)DBC_get_current_size, METH_NOARGS},
Gregory P. Smith455d46f2003-07-09 04:45:59 +00008840 {"set_both", (PyCFunction)DBC_set_both, METH_VARARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008841 {"set_recno", (PyCFunction)DBC_set_recno, METH_VARARGS|METH_KEYWORDS},
8842 {"consume", (PyCFunction)DBC_consume, METH_VARARGS|METH_KEYWORDS},
8843 {"next_dup", (PyCFunction)DBC_next_dup, METH_VARARGS|METH_KEYWORDS},
8844 {"next_nodup", (PyCFunction)DBC_next_nodup, METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008845#if (DBVER >= 46)
8846 {"prev_dup", (PyCFunction)DBC_prev_dup,
8847 METH_VARARGS|METH_KEYWORDS},
8848#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008849 {"prev_nodup", (PyCFunction)DBC_prev_nodup, METH_VARARGS|METH_KEYWORDS},
8850 {"join_item", (PyCFunction)DBC_join_item, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008851#if (DBVER >= 46)
8852 {"set_priority", (PyCFunction)DBC_set_priority,
8853 METH_VARARGS|METH_KEYWORDS},
8854 {"get_priority", (PyCFunction)DBC_get_priority, METH_NOARGS},
8855#endif
8856 {NULL, NULL} /* sentinel */
8857};
8858
8859
8860static PyMethodDef DBLogCursor_methods[] = {
8861 {"close", (PyCFunction)DBLogCursor_close, METH_NOARGS},
8862 {"current", (PyCFunction)DBLogCursor_current, METH_NOARGS},
8863 {"first", (PyCFunction)DBLogCursor_first, METH_NOARGS},
8864 {"last", (PyCFunction)DBLogCursor_last, METH_NOARGS},
8865 {"next", (PyCFunction)DBLogCursor_next, METH_NOARGS},
8866 {"prev", (PyCFunction)DBLogCursor_prev, METH_NOARGS},
8867 {"set", (PyCFunction)DBLogCursor_set, METH_VARARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008868 {NULL, NULL} /* sentinel */
8869};
8870
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07008871#if (DBVER >= 52)
8872static PyMethodDef DBSite_methods[] = {
8873 {"get_config", (PyCFunction)DBSite_get_config,
8874 METH_VARARGS | METH_KEYWORDS},
8875 {"set_config", (PyCFunction)DBSite_set_config,
8876 METH_VARARGS | METH_KEYWORDS},
8877 {"remove", (PyCFunction)DBSite_remove, METH_NOARGS},
8878 {"get_eid", (PyCFunction)DBSite_get_eid, METH_NOARGS},
8879 {"get_address", (PyCFunction)DBSite_get_address, METH_NOARGS},
8880 {"close", (PyCFunction)DBSite_close, METH_NOARGS},
8881 {NULL, NULL} /* sentinel */
8882};
8883#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008884
8885static PyMethodDef DBEnv_methods[] = {
8886 {"close", (PyCFunction)DBEnv_close, METH_VARARGS},
8887 {"open", (PyCFunction)DBEnv_open, METH_VARARGS},
8888 {"remove", (PyCFunction)DBEnv_remove, METH_VARARGS},
Barry Warsaw9a0d7792002-12-30 20:53:52 +00008889 {"dbremove", (PyCFunction)DBEnv_dbremove, METH_VARARGS|METH_KEYWORDS},
8890 {"dbrename", (PyCFunction)DBEnv_dbrename, METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008891#if (DBVER >= 46)
8892 {"set_thread_count", (PyCFunction)DBEnv_set_thread_count, METH_VARARGS},
8893 {"get_thread_count", (PyCFunction)DBEnv_get_thread_count, METH_NOARGS},
8894#endif
Barry Warsaw9a0d7792002-12-30 20:53:52 +00008895 {"set_encrypt", (PyCFunction)DBEnv_set_encrypt, METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008896 {"get_encrypt_flags", (PyCFunction)DBEnv_get_encrypt_flags, METH_NOARGS},
8897 {"get_timeout", (PyCFunction)DBEnv_get_timeout,
8898 METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008899 {"set_timeout", (PyCFunction)DBEnv_set_timeout, METH_VARARGS|METH_KEYWORDS},
8900 {"set_shm_key", (PyCFunction)DBEnv_set_shm_key, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008901 {"get_shm_key", (PyCFunction)DBEnv_get_shm_key, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008902#if (DBVER >= 46)
8903 {"set_cache_max", (PyCFunction)DBEnv_set_cache_max, METH_VARARGS},
8904 {"get_cache_max", (PyCFunction)DBEnv_get_cache_max, METH_NOARGS},
8905#endif
8906 {"set_cachesize", (PyCFunction)DBEnv_set_cachesize, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008907 {"get_cachesize", (PyCFunction)DBEnv_get_cachesize, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008908 {"memp_trickle", (PyCFunction)DBEnv_memp_trickle, METH_VARARGS},
8909 {"memp_sync", (PyCFunction)DBEnv_memp_sync, METH_VARARGS},
8910 {"memp_stat", (PyCFunction)DBEnv_memp_stat,
8911 METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008912 {"memp_stat_print", (PyCFunction)DBEnv_memp_stat_print,
8913 METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008914#if (DBVER >= 44)
8915 {"mutex_set_max", (PyCFunction)DBEnv_mutex_set_max, METH_VARARGS},
8916 {"mutex_get_max", (PyCFunction)DBEnv_mutex_get_max, METH_NOARGS},
8917 {"mutex_set_align", (PyCFunction)DBEnv_mutex_set_align, METH_VARARGS},
8918 {"mutex_get_align", (PyCFunction)DBEnv_mutex_get_align, METH_NOARGS},
8919 {"mutex_set_increment", (PyCFunction)DBEnv_mutex_set_increment,
8920 METH_VARARGS},
8921 {"mutex_get_increment", (PyCFunction)DBEnv_mutex_get_increment,
8922 METH_NOARGS},
8923 {"mutex_set_tas_spins", (PyCFunction)DBEnv_mutex_set_tas_spins,
8924 METH_VARARGS},
8925 {"mutex_get_tas_spins", (PyCFunction)DBEnv_mutex_get_tas_spins,
8926 METH_NOARGS},
8927 {"mutex_stat", (PyCFunction)DBEnv_mutex_stat, METH_VARARGS},
8928#if (DBVER >= 44)
8929 {"mutex_stat_print", (PyCFunction)DBEnv_mutex_stat_print,
8930 METH_VARARGS|METH_KEYWORDS},
8931#endif
8932#endif
8933 {"set_data_dir", (PyCFunction)DBEnv_set_data_dir, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008934 {"get_data_dirs", (PyCFunction)DBEnv_get_data_dirs, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008935 {"get_flags", (PyCFunction)DBEnv_get_flags, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008936 {"set_flags", (PyCFunction)DBEnv_set_flags, METH_VARARGS},
8937#if (DBVER >= 47)
8938 {"log_set_config", (PyCFunction)DBEnv_log_set_config, METH_VARARGS},
8939 {"log_get_config", (PyCFunction)DBEnv_log_get_config, METH_VARARGS},
8940#endif
8941 {"set_lg_bsize", (PyCFunction)DBEnv_set_lg_bsize, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008942 {"get_lg_bsize", (PyCFunction)DBEnv_get_lg_bsize, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008943 {"set_lg_dir", (PyCFunction)DBEnv_set_lg_dir, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008944 {"get_lg_dir", (PyCFunction)DBEnv_get_lg_dir, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008945 {"set_lg_max", (PyCFunction)DBEnv_set_lg_max, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008946 {"get_lg_max", (PyCFunction)DBEnv_get_lg_max, METH_NOARGS},
Gregory P. Smithe9477062005-06-04 06:46:59 +00008947 {"set_lg_regionmax",(PyCFunction)DBEnv_set_lg_regionmax, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008948 {"get_lg_regionmax",(PyCFunction)DBEnv_get_lg_regionmax, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008949#if (DBVER >= 44)
8950 {"set_lg_filemode", (PyCFunction)DBEnv_set_lg_filemode, METH_VARARGS},
8951 {"get_lg_filemode", (PyCFunction)DBEnv_get_lg_filemode, METH_NOARGS},
8952#endif
8953#if (DBVER >= 47)
8954 {"set_lk_partitions", (PyCFunction)DBEnv_set_lk_partitions, METH_VARARGS},
8955 {"get_lk_partitions", (PyCFunction)DBEnv_get_lk_partitions, METH_NOARGS},
8956#endif
8957 {"set_lk_detect", (PyCFunction)DBEnv_set_lk_detect, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008958 {"get_lk_detect", (PyCFunction)DBEnv_get_lk_detect, METH_NOARGS},
Gregory P. Smith8b96a352007-01-05 01:59:42 +00008959#if (DBVER < 45)
Jesus Cea6557aac2010-03-22 14:22:26 +00008960 {"set_lk_max", (PyCFunction)DBEnv_set_lk_max, METH_VARARGS},
Gregory P. Smith8b96a352007-01-05 01:59:42 +00008961#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008962 {"set_lk_max_locks", (PyCFunction)DBEnv_set_lk_max_locks, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008963 {"get_lk_max_locks", (PyCFunction)DBEnv_get_lk_max_locks, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008964 {"set_lk_max_lockers", (PyCFunction)DBEnv_set_lk_max_lockers, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008965 {"get_lk_max_lockers", (PyCFunction)DBEnv_get_lk_max_lockers, METH_NOARGS},
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00008966 {"set_lk_max_objects", (PyCFunction)DBEnv_set_lk_max_objects, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008967 {"get_lk_max_objects", (PyCFunction)DBEnv_get_lk_max_objects, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008968 {"stat_print", (PyCFunction)DBEnv_stat_print,
8969 METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008970 {"set_mp_mmapsize", (PyCFunction)DBEnv_set_mp_mmapsize, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008971 {"get_mp_mmapsize", (PyCFunction)DBEnv_get_mp_mmapsize, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008972 {"set_tmp_dir", (PyCFunction)DBEnv_set_tmp_dir, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008973 {"get_tmp_dir", (PyCFunction)DBEnv_get_tmp_dir, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008974 {"txn_begin", (PyCFunction)DBEnv_txn_begin, METH_VARARGS|METH_KEYWORDS},
8975 {"txn_checkpoint", (PyCFunction)DBEnv_txn_checkpoint, METH_VARARGS},
8976 {"txn_stat", (PyCFunction)DBEnv_txn_stat, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008977 {"txn_stat_print", (PyCFunction)DBEnv_txn_stat_print,
8978 METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008979 {"get_tx_max", (PyCFunction)DBEnv_get_tx_max, METH_NOARGS},
8980 {"get_tx_timestamp", (PyCFunction)DBEnv_get_tx_timestamp, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008981 {"set_tx_max", (PyCFunction)DBEnv_set_tx_max, METH_VARARGS},
Gregory P. Smith8a474042006-01-27 07:05:40 +00008982 {"set_tx_timestamp", (PyCFunction)DBEnv_set_tx_timestamp, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008983 {"lock_detect", (PyCFunction)DBEnv_lock_detect, METH_VARARGS},
8984 {"lock_get", (PyCFunction)DBEnv_lock_get, METH_VARARGS},
8985 {"lock_id", (PyCFunction)DBEnv_lock_id, METH_NOARGS},
8986 {"lock_id_free", (PyCFunction)DBEnv_lock_id_free, METH_VARARGS},
8987 {"lock_put", (PyCFunction)DBEnv_lock_put, METH_VARARGS},
8988 {"lock_stat", (PyCFunction)DBEnv_lock_stat, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008989 {"lock_stat_print", (PyCFunction)DBEnv_lock_stat_print,
8990 METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00008991 {"log_cursor", (PyCFunction)DBEnv_log_cursor, METH_NOARGS},
8992 {"log_file", (PyCFunction)DBEnv_log_file, METH_VARARGS},
Gregory P. Smithdb8a8072006-06-05 01:56:15 +00008993#if (DBVER >= 44)
Jesus Cea6557aac2010-03-22 14:22:26 +00008994 {"log_printf", (PyCFunction)DBEnv_log_printf,
8995 METH_VARARGS|METH_KEYWORDS},
8996#endif
8997 {"log_archive", (PyCFunction)DBEnv_log_archive, METH_VARARGS},
8998 {"log_flush", (PyCFunction)DBEnv_log_flush, METH_NOARGS},
8999 {"log_stat", (PyCFunction)DBEnv_log_stat, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00009000 {"log_stat_print", (PyCFunction)DBEnv_log_stat_print,
9001 METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00009002#if (DBVER >= 44)
9003 {"fileid_reset", (PyCFunction)DBEnv_fileid_reset, METH_VARARGS|METH_KEYWORDS},
9004 {"lsn_reset", (PyCFunction)DBEnv_lsn_reset, METH_VARARGS|METH_KEYWORDS},
Gregory P. Smithdb8a8072006-06-05 01:56:15 +00009005#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009006 {"set_get_returns_none",(PyCFunction)DBEnv_set_get_returns_none, METH_VARARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00009007 {"txn_recover", (PyCFunction)DBEnv_txn_recover, METH_NOARGS},
Matthias Klose54cc5392010-03-15 12:46:18 +00009008#if (DBVER < 48)
Jesus Ceaca3939c2008-05-22 15:27:38 +00009009 {"set_rpc_server", (PyCFunction)DBEnv_set_rpc_server,
Stefan Krah77112732011-09-15 22:56:00 +02009010 METH_VARARGS|METH_KEYWORDS},
Matthias Klose54cc5392010-03-15 12:46:18 +00009011#endif
Jesus Cea6557aac2010-03-22 14:22:26 +00009012 {"set_mp_max_openfd", (PyCFunction)DBEnv_set_mp_max_openfd, METH_VARARGS},
9013 {"get_mp_max_openfd", (PyCFunction)DBEnv_get_mp_max_openfd, METH_NOARGS},
9014 {"set_mp_max_write", (PyCFunction)DBEnv_set_mp_max_write, METH_VARARGS},
9015 {"get_mp_max_write", (PyCFunction)DBEnv_get_mp_max_write, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00009016 {"set_verbose", (PyCFunction)DBEnv_set_verbose, METH_VARARGS},
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009017 {"get_verbose", (PyCFunction)DBEnv_get_verbose, METH_VARARGS},
9018 {"set_private", (PyCFunction)DBEnv_set_private, METH_O},
9019 {"get_private", (PyCFunction)DBEnv_get_private, METH_NOARGS},
9020 {"get_open_flags", (PyCFunction)DBEnv_get_open_flags, METH_NOARGS},
9021#if (DBVER >= 47)
9022 {"set_intermediate_dir_mode", (PyCFunction)DBEnv_set_intermediate_dir_mode,
9023 METH_VARARGS},
9024 {"get_intermediate_dir_mode", (PyCFunction)DBEnv_get_intermediate_dir_mode,
9025 METH_NOARGS},
Jesus Ceaef9764f2008-05-13 18:45:46 +00009026#endif
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009027#if (DBVER < 47)
9028 {"set_intermediate_dir", (PyCFunction)DBEnv_set_intermediate_dir,
9029 METH_VARARGS},
9030#endif
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009031 {"rep_start", (PyCFunction)DBEnv_rep_start,
9032 METH_VARARGS|METH_KEYWORDS},
9033 {"rep_set_transport", (PyCFunction)DBEnv_rep_set_transport, METH_VARARGS},
9034 {"rep_process_message", (PyCFunction)DBEnv_rep_process_message,
9035 METH_VARARGS},
9036#if (DBVER >= 46)
9037 {"rep_elect", (PyCFunction)DBEnv_rep_elect, METH_VARARGS},
9038#endif
9039#if (DBVER >= 44)
9040 {"rep_set_config", (PyCFunction)DBEnv_rep_set_config, METH_VARARGS},
9041 {"rep_get_config", (PyCFunction)DBEnv_rep_get_config, METH_VARARGS},
9042 {"rep_sync", (PyCFunction)DBEnv_rep_sync, METH_NOARGS},
Jesus Ceaef9764f2008-05-13 18:45:46 +00009043#endif
9044#if (DBVER >= 45)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009045 {"rep_set_limit", (PyCFunction)DBEnv_rep_set_limit, METH_VARARGS},
9046 {"rep_get_limit", (PyCFunction)DBEnv_rep_get_limit, METH_NOARGS},
9047#endif
9048#if (DBVER >= 47)
9049 {"rep_set_request", (PyCFunction)DBEnv_rep_set_request, METH_VARARGS},
9050 {"rep_get_request", (PyCFunction)DBEnv_rep_get_request, METH_NOARGS},
9051#endif
9052#if (DBVER >= 45)
9053 {"set_event_notify", (PyCFunction)DBEnv_set_event_notify, METH_O},
Jesus Ceaef9764f2008-05-13 18:45:46 +00009054#endif
9055#if (DBVER >= 45)
9056 {"rep_set_nsites", (PyCFunction)DBEnv_rep_set_nsites, METH_VARARGS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009057 {"rep_get_nsites", (PyCFunction)DBEnv_rep_get_nsites, METH_NOARGS},
Jesus Ceaef9764f2008-05-13 18:45:46 +00009058 {"rep_set_priority", (PyCFunction)DBEnv_rep_set_priority, METH_VARARGS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009059 {"rep_get_priority", (PyCFunction)DBEnv_rep_get_priority, METH_NOARGS},
Jesus Ceaef9764f2008-05-13 18:45:46 +00009060 {"rep_set_timeout", (PyCFunction)DBEnv_rep_set_timeout, METH_VARARGS},
9061 {"rep_get_timeout", (PyCFunction)DBEnv_rep_get_timeout, METH_VARARGS},
9062#endif
Jesus Cea6557aac2010-03-22 14:22:26 +00009063#if (DBVER >= 47)
9064 {"rep_set_clockskew", (PyCFunction)DBEnv_rep_set_clockskew, METH_VARARGS},
9065 {"rep_get_clockskew", (PyCFunction)DBEnv_rep_get_clockskew, METH_VARARGS},
9066#endif
9067 {"rep_stat", (PyCFunction)DBEnv_rep_stat,
9068 METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00009069 {"rep_stat_print", (PyCFunction)DBEnv_rep_stat_print,
9070 METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00009071
Jesus Ceaef9764f2008-05-13 18:45:46 +00009072#if (DBVER >= 45)
9073 {"repmgr_start", (PyCFunction)DBEnv_repmgr_start,
9074 METH_VARARGS|METH_KEYWORDS},
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009075#if (DBVER < 52)
Jesus Ceaef9764f2008-05-13 18:45:46 +00009076 {"repmgr_set_local_site", (PyCFunction)DBEnv_repmgr_set_local_site,
9077 METH_VARARGS|METH_KEYWORDS},
9078 {"repmgr_add_remote_site", (PyCFunction)DBEnv_repmgr_add_remote_site,
9079 METH_VARARGS|METH_KEYWORDS},
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009080#endif
Jesus Ceaef9764f2008-05-13 18:45:46 +00009081 {"repmgr_set_ack_policy", (PyCFunction)DBEnv_repmgr_set_ack_policy,
9082 METH_VARARGS},
9083 {"repmgr_get_ack_policy", (PyCFunction)DBEnv_repmgr_get_ack_policy,
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009084 METH_NOARGS},
Jesus Ceaef9764f2008-05-13 18:45:46 +00009085 {"repmgr_site_list", (PyCFunction)DBEnv_repmgr_site_list,
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009086 METH_NOARGS},
Jesus Ceaef9764f2008-05-13 18:45:46 +00009087#endif
9088#if (DBVER >= 46)
9089 {"repmgr_stat", (PyCFunction)DBEnv_repmgr_stat,
9090 METH_VARARGS|METH_KEYWORDS},
9091 {"repmgr_stat_print", (PyCFunction)DBEnv_repmgr_stat_print,
9092 METH_VARARGS|METH_KEYWORDS},
9093#endif
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009094#if (DBVER >= 52)
9095 {"repmgr_site", (PyCFunction)DBEnv_repmgr_site,
9096 METH_VARARGS | METH_KEYWORDS},
9097 {"repmgr_site_by_eid", (PyCFunction)DBEnv_repmgr_site_by_eid,
9098 METH_VARARGS | METH_KEYWORDS},
9099#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009100 {NULL, NULL} /* sentinel */
9101};
9102
9103
9104static PyMethodDef DBTxn_methods[] = {
9105 {"commit", (PyCFunction)DBTxn_commit, METH_VARARGS},
9106 {"prepare", (PyCFunction)DBTxn_prepare, METH_VARARGS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009107 {"discard", (PyCFunction)DBTxn_discard, METH_NOARGS},
9108 {"abort", (PyCFunction)DBTxn_abort, METH_NOARGS},
9109 {"id", (PyCFunction)DBTxn_id, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00009110 {"set_timeout", (PyCFunction)DBTxn_set_timeout,
9111 METH_VARARGS|METH_KEYWORDS},
9112#if (DBVER >= 44)
9113 {"set_name", (PyCFunction)DBTxn_set_name, METH_VARARGS},
9114 {"get_name", (PyCFunction)DBTxn_get_name, METH_NOARGS},
9115#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009116 {NULL, NULL} /* sentinel */
9117};
9118
9119
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009120static PyMethodDef DBSequence_methods[] = {
9121 {"close", (PyCFunction)DBSequence_close, METH_VARARGS},
9122 {"get", (PyCFunction)DBSequence_get, METH_VARARGS|METH_KEYWORDS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009123 {"get_dbp", (PyCFunction)DBSequence_get_dbp, METH_NOARGS},
9124 {"get_key", (PyCFunction)DBSequence_get_key, METH_NOARGS},
Jesus Cea6557aac2010-03-22 14:22:26 +00009125 {"initial_value", (PyCFunction)DBSequence_initial_value, METH_VARARGS},
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009126 {"open", (PyCFunction)DBSequence_open, METH_VARARGS|METH_KEYWORDS},
9127 {"remove", (PyCFunction)DBSequence_remove, METH_VARARGS|METH_KEYWORDS},
9128 {"set_cachesize", (PyCFunction)DBSequence_set_cachesize, METH_VARARGS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009129 {"get_cachesize", (PyCFunction)DBSequence_get_cachesize, METH_NOARGS},
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009130 {"set_flags", (PyCFunction)DBSequence_set_flags, METH_VARARGS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009131 {"get_flags", (PyCFunction)DBSequence_get_flags, METH_NOARGS},
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009132 {"set_range", (PyCFunction)DBSequence_set_range, METH_VARARGS},
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009133 {"get_range", (PyCFunction)DBSequence_get_range, METH_NOARGS},
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009134 {"stat", (PyCFunction)DBSequence_stat, METH_VARARGS|METH_KEYWORDS},
Jesus Cea6557aac2010-03-22 14:22:26 +00009135 {"stat_print", (PyCFunction)DBSequence_stat_print,
9136 METH_VARARGS|METH_KEYWORDS},
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009137 {NULL, NULL} /* sentinel */
9138};
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009139
9140
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009141static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009142DBEnv_db_home_get(DBEnvObject* self)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009143{
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009144 const char *home = NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009145
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009146 CHECK_ENV_NOT_CLOSED(self);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009147
Jesus Cea6557aac2010-03-22 14:22:26 +00009148 MYDB_BEGIN_ALLOW_THREADS;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009149 self->db_env->get_home(self->db_env, &home);
Jesus Cea6557aac2010-03-22 14:22:26 +00009150 MYDB_END_ALLOW_THREADS;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009151
9152 if (home == NULL) {
9153 RETURN_NONE();
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009154 }
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009155 return PyBytes_FromString(home);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009156}
9157
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009158static PyGetSetDef DBEnv_getsets[] = {
9159 {"db_home", (getter)DBEnv_db_home_get, NULL,},
9160 {NULL}
9161};
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009162
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009163
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009164statichere PyTypeObject DB_Type = {
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009165#if (PY_VERSION_HEX < 0x03000000)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009166 PyObject_HEAD_INIT(NULL)
9167 0, /*ob_size*/
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009168#else
9169 PyVarObject_HEAD_INIT(NULL, 0)
9170#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009171 "DB", /*tp_name*/
9172 sizeof(DBObject), /*tp_basicsize*/
9173 0, /*tp_itemsize*/
9174 /* methods */
9175 (destructor)DB_dealloc, /*tp_dealloc*/
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009176 0, /*tp_print*/
9177 0, /*tp_getattr*/
9178 0, /*tp_setattr*/
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009179 0, /*tp_compare*/
9180 0, /*tp_repr*/
9181 0, /*tp_as_number*/
Jesus Cea6557aac2010-03-22 14:22:26 +00009182 &DB_sequence,/*tp_as_sequence*/
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009183 &DB_mapping,/*tp_as_mapping*/
9184 0, /*tp_hash*/
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009185 0, /* tp_call */
9186 0, /* tp_str */
9187 0, /* tp_getattro */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009188 0, /* tp_setattro */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009189 0, /* tp_as_buffer */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009190#if (PY_VERSION_HEX < 0x03000000)
Gregory P. Smith31c50652004-06-28 01:20:40 +00009191 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009192#else
9193 Py_TPFLAGS_DEFAULT, /* tp_flags */
9194#endif
9195 0, /* tp_doc */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009196 0, /* tp_traverse */
9197 0, /* tp_clear */
9198 0, /* tp_richcompare */
Gregory P. Smith31c50652004-06-28 01:20:40 +00009199 offsetof(DBObject, in_weakreflist), /* tp_weaklistoffset */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009200 0, /*tp_iter*/
9201 0, /*tp_iternext*/
9202 DB_methods, /*tp_methods*/
9203 0, /*tp_members*/
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009204};
9205
9206
9207statichere PyTypeObject DBCursor_Type = {
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009208#if (PY_VERSION_HEX < 0x03000000)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009209 PyObject_HEAD_INIT(NULL)
9210 0, /*ob_size*/
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009211#else
9212 PyVarObject_HEAD_INIT(NULL, 0)
9213#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009214 "DBCursor", /*tp_name*/
9215 sizeof(DBCursorObject), /*tp_basicsize*/
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009216 0, /*tp_itemsize*/
9217 /* methods */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009218 (destructor)DBCursor_dealloc,/*tp_dealloc*/
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009219 0, /*tp_print*/
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009220 0, /*tp_getattr*/
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009221 0, /*tp_setattr*/
9222 0, /*tp_compare*/
9223 0, /*tp_repr*/
9224 0, /*tp_as_number*/
9225 0, /*tp_as_sequence*/
9226 0, /*tp_as_mapping*/
9227 0, /*tp_hash*/
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009228 0, /*tp_call*/
9229 0, /*tp_str*/
9230 0, /*tp_getattro*/
9231 0, /*tp_setattro*/
9232 0, /*tp_as_buffer*/
9233#if (PY_VERSION_HEX < 0x03000000)
Gregory P. Smith31c50652004-06-28 01:20:40 +00009234 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009235#else
9236 Py_TPFLAGS_DEFAULT, /* tp_flags */
9237#endif
9238 0, /* tp_doc */
9239 0, /* tp_traverse */
9240 0, /* tp_clear */
9241 0, /* tp_richcompare */
9242 offsetof(DBCursorObject, in_weakreflist), /* tp_weaklistoffset */
9243 0, /*tp_iter*/
9244 0, /*tp_iternext*/
9245 DBCursor_methods, /*tp_methods*/
9246 0, /*tp_members*/
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009247};
9248
9249
Jesus Cea6557aac2010-03-22 14:22:26 +00009250statichere PyTypeObject DBLogCursor_Type = {
9251#if (PY_VERSION_HEX < 0x03000000)
9252 PyObject_HEAD_INIT(NULL)
9253 0, /*ob_size*/
9254#else
9255 PyVarObject_HEAD_INIT(NULL, 0)
9256#endif
9257 "DBLogCursor", /*tp_name*/
9258 sizeof(DBLogCursorObject), /*tp_basicsize*/
9259 0, /*tp_itemsize*/
9260 /* methods */
9261 (destructor)DBLogCursor_dealloc,/*tp_dealloc*/
9262 0, /*tp_print*/
9263 0, /*tp_getattr*/
9264 0, /*tp_setattr*/
9265 0, /*tp_compare*/
9266 0, /*tp_repr*/
9267 0, /*tp_as_number*/
9268 0, /*tp_as_sequence*/
9269 0, /*tp_as_mapping*/
9270 0, /*tp_hash*/
9271 0, /*tp_call*/
9272 0, /*tp_str*/
9273 0, /*tp_getattro*/
9274 0, /*tp_setattro*/
9275 0, /*tp_as_buffer*/
9276#if (PY_VERSION_HEX < 0x03000000)
9277 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
9278#else
9279 Py_TPFLAGS_DEFAULT, /* tp_flags */
9280#endif
9281 0, /* tp_doc */
9282 0, /* tp_traverse */
9283 0, /* tp_clear */
9284 0, /* tp_richcompare */
9285 offsetof(DBLogCursorObject, in_weakreflist), /* tp_weaklistoffset */
9286 0, /*tp_iter*/
9287 0, /*tp_iternext*/
9288 DBLogCursor_methods, /*tp_methods*/
9289 0, /*tp_members*/
9290};
9291
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009292#if (DBVER >= 52)
9293statichere PyTypeObject DBSite_Type = {
9294#if (PY_VERSION_HEX < 0x03000000)
9295 PyObject_HEAD_INIT(NULL)
9296 0, /*ob_size*/
9297#else
9298 PyVarObject_HEAD_INIT(NULL, 0)
9299#endif
9300 "DBSite", /*tp_name*/
9301 sizeof(DBSiteObject), /*tp_basicsize*/
9302 0, /*tp_itemsize*/
9303 /* methods */
9304 (destructor)DBSite_dealloc,/*tp_dealloc*/
9305 0, /*tp_print*/
9306 0, /*tp_getattr*/
9307 0, /*tp_setattr*/
9308 0, /*tp_compare*/
9309 0, /*tp_repr*/
9310 0, /*tp_as_number*/
9311 0, /*tp_as_sequence*/
9312 0, /*tp_as_mapping*/
9313 0, /*tp_hash*/
9314 0, /*tp_call*/
9315 0, /*tp_str*/
9316 0, /*tp_getattro*/
9317 0, /*tp_setattro*/
9318 0, /*tp_as_buffer*/
9319#if (PY_VERSION_HEX < 0x03000000)
9320 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
9321#else
9322 Py_TPFLAGS_DEFAULT, /* tp_flags */
9323#endif
9324 0, /* tp_doc */
9325 0, /* tp_traverse */
9326 0, /* tp_clear */
9327 0, /* tp_richcompare */
9328 offsetof(DBSiteObject, in_weakreflist), /* tp_weaklistoffset */
9329 0, /*tp_iter*/
9330 0, /*tp_iternext*/
9331 DBSite_methods, /*tp_methods*/
9332 0, /*tp_members*/
9333};
9334#endif
Jesus Cea6557aac2010-03-22 14:22:26 +00009335
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009336statichere PyTypeObject DBEnv_Type = {
9337#if (PY_VERSION_HEX < 0x03000000)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009338 PyObject_HEAD_INIT(NULL)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009339 0, /*ob_size*/
9340#else
9341 PyVarObject_HEAD_INIT(NULL, 0)
9342#endif
9343 "DBEnv", /*tp_name*/
9344 sizeof(DBEnvObject), /*tp_basicsize*/
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009345 0, /*tp_itemsize*/
9346 /* methods */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009347 (destructor)DBEnv_dealloc, /*tp_dealloc*/
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009348 0, /*tp_print*/
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009349 0, /*tp_getattr*/
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009350 0, /*tp_setattr*/
9351 0, /*tp_compare*/
9352 0, /*tp_repr*/
9353 0, /*tp_as_number*/
9354 0, /*tp_as_sequence*/
9355 0, /*tp_as_mapping*/
9356 0, /*tp_hash*/
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009357 0, /* tp_call */
9358 0, /* tp_str */
9359 0, /* tp_getattro */
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009360 0, /* tp_setattro */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009361 0, /* tp_as_buffer */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009362#if (PY_VERSION_HEX < 0x03000000)
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009363 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009364#else
9365 Py_TPFLAGS_DEFAULT, /* tp_flags */
9366#endif
9367 0, /* tp_doc */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009368 0, /* tp_traverse */
9369 0, /* tp_clear */
9370 0, /* tp_richcompare */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009371 offsetof(DBEnvObject, in_weakreflist), /* tp_weaklistoffset */
9372 0, /* tp_iter */
9373 0, /* tp_iternext */
9374 DBEnv_methods, /* tp_methods */
9375 0, /* tp_members */
9376 DBEnv_getsets, /* tp_getsets */
9377};
9378
9379statichere PyTypeObject DBTxn_Type = {
9380#if (PY_VERSION_HEX < 0x03000000)
9381 PyObject_HEAD_INIT(NULL)
9382 0, /*ob_size*/
9383#else
9384 PyVarObject_HEAD_INIT(NULL, 0)
9385#endif
9386 "DBTxn", /*tp_name*/
9387 sizeof(DBTxnObject), /*tp_basicsize*/
9388 0, /*tp_itemsize*/
9389 /* methods */
9390 (destructor)DBTxn_dealloc, /*tp_dealloc*/
9391 0, /*tp_print*/
9392 0, /*tp_getattr*/
9393 0, /*tp_setattr*/
9394 0, /*tp_compare*/
9395 0, /*tp_repr*/
9396 0, /*tp_as_number*/
9397 0, /*tp_as_sequence*/
9398 0, /*tp_as_mapping*/
9399 0, /*tp_hash*/
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009400 0, /* tp_call */
9401 0, /* tp_str */
9402 0, /* tp_getattro */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009403 0, /* tp_setattro */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009404 0, /* tp_as_buffer */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009405#if (PY_VERSION_HEX < 0x03000000)
9406 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
9407#else
9408 Py_TPFLAGS_DEFAULT, /* tp_flags */
9409#endif
9410 0, /* tp_doc */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009411 0, /* tp_traverse */
9412 0, /* tp_clear */
9413 0, /* tp_richcompare */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009414 offsetof(DBTxnObject, in_weakreflist), /* tp_weaklistoffset */
9415 0, /*tp_iter*/
9416 0, /*tp_iternext*/
9417 DBTxn_methods, /*tp_methods*/
9418 0, /*tp_members*/
9419};
9420
9421
9422statichere PyTypeObject DBLock_Type = {
9423#if (PY_VERSION_HEX < 0x03000000)
9424 PyObject_HEAD_INIT(NULL)
9425 0, /*ob_size*/
9426#else
9427 PyVarObject_HEAD_INIT(NULL, 0)
9428#endif
9429 "DBLock", /*tp_name*/
9430 sizeof(DBLockObject), /*tp_basicsize*/
9431 0, /*tp_itemsize*/
9432 /* methods */
9433 (destructor)DBLock_dealloc, /*tp_dealloc*/
9434 0, /*tp_print*/
9435 0, /*tp_getattr*/
9436 0, /*tp_setattr*/
9437 0, /*tp_compare*/
9438 0, /*tp_repr*/
9439 0, /*tp_as_number*/
9440 0, /*tp_as_sequence*/
9441 0, /*tp_as_mapping*/
9442 0, /*tp_hash*/
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009443 0, /* tp_call */
9444 0, /* tp_str */
9445 0, /* tp_getattro */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009446 0, /* tp_setattro */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009447 0, /* tp_as_buffer */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009448#if (PY_VERSION_HEX < 0x03000000)
9449 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
9450#else
9451 Py_TPFLAGS_DEFAULT, /* tp_flags */
9452#endif
9453 0, /* tp_doc */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009454 0, /* tp_traverse */
9455 0, /* tp_clear */
9456 0, /* tp_richcompare */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009457 offsetof(DBLockObject, in_weakreflist), /* tp_weaklistoffset */
9458};
9459
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009460statichere PyTypeObject DBSequence_Type = {
9461#if (PY_VERSION_HEX < 0x03000000)
9462 PyObject_HEAD_INIT(NULL)
9463 0, /*ob_size*/
9464#else
9465 PyVarObject_HEAD_INIT(NULL, 0)
9466#endif
9467 "DBSequence", /*tp_name*/
9468 sizeof(DBSequenceObject), /*tp_basicsize*/
9469 0, /*tp_itemsize*/
9470 /* methods */
9471 (destructor)DBSequence_dealloc, /*tp_dealloc*/
9472 0, /*tp_print*/
9473 0, /*tp_getattr*/
9474 0, /*tp_setattr*/
9475 0, /*tp_compare*/
9476 0, /*tp_repr*/
9477 0, /*tp_as_number*/
9478 0, /*tp_as_sequence*/
9479 0, /*tp_as_mapping*/
9480 0, /*tp_hash*/
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009481 0, /* tp_call */
9482 0, /* tp_str */
9483 0, /* tp_getattro */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009484 0, /* tp_setattro */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009485 0, /* tp_as_buffer */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009486#if (PY_VERSION_HEX < 0x03000000)
9487 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_WEAKREFS, /* tp_flags */
9488#else
9489 Py_TPFLAGS_DEFAULT, /* tp_flags */
9490#endif
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009491 0, /* tp_doc */
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009492 0, /* tp_traverse */
9493 0, /* tp_clear */
9494 0, /* tp_richcompare */
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009495 offsetof(DBSequenceObject, in_weakreflist), /* tp_weaklistoffset */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009496 0, /*tp_iter*/
9497 0, /*tp_iternext*/
9498 DBSequence_methods, /*tp_methods*/
9499 0, /*tp_members*/
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009500};
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009501
9502/* --------------------------------------------------------------------- */
9503/* Module-level functions */
9504
9505static PyObject*
9506DB_construct(PyObject* self, PyObject* args, PyObject* kwargs)
9507{
9508 PyObject* dbenvobj = NULL;
9509 int flags = 0;
Martin v. Löwis02cbf4a2006-02-27 17:20:04 +00009510 static char* kwnames[] = { "dbEnv", "flags", NULL};
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009511
Barry Warsaw9a0d7792002-12-30 20:53:52 +00009512 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|Oi:DB", kwnames,
9513 &dbenvobj, &flags))
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009514 return NULL;
9515 if (dbenvobj == Py_None)
9516 dbenvobj = NULL;
9517 else if (dbenvobj && !DBEnvObject_Check(dbenvobj)) {
9518 makeTypeError("DBEnv", dbenvobj);
9519 return NULL;
9520 }
9521
9522 return (PyObject* )newDBObject((DBEnvObject*)dbenvobj, flags);
9523}
9524
9525
9526static PyObject*
9527DBEnv_construct(PyObject* self, PyObject* args)
9528{
9529 int flags = 0;
9530 if (!PyArg_ParseTuple(args, "|i:DbEnv", &flags)) return NULL;
9531 return (PyObject* )newDBEnvObject(flags);
9532}
9533
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009534static PyObject*
9535DBSequence_construct(PyObject* self, PyObject* args, PyObject* kwargs)
9536{
Neal Norwitzb4fcf8d2006-06-11 05:44:18 +00009537 PyObject* dbobj;
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009538 int flags = 0;
9539 static char* kwnames[] = { "db", "flags", NULL};
9540
9541 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|i:DBSequence", kwnames, &dbobj, &flags))
9542 return NULL;
Neal Norwitzb4fcf8d2006-06-11 05:44:18 +00009543 if (!DBObject_Check(dbobj)) {
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009544 makeTypeError("DB", dbobj);
9545 return NULL;
9546 }
9547 return (PyObject* )newDBSequenceObject((DBObject*)dbobj, flags);
9548}
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009549
9550static char bsddb_version_doc[] =
9551"Returns a tuple of major, minor, and patch release numbers of the\n\
9552underlying DB library.";
9553
9554static PyObject*
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009555bsddb_version(PyObject* self)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009556{
9557 int major, minor, patch;
9558
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009559 /* This should be instantaneous, no need to release the GIL */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009560 db_version(&major, &minor, &patch);
9561 return Py_BuildValue("(iii)", major, minor, patch);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009562}
9563
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009564#if (DBVER >= 50)
9565static PyObject*
9566bsddb_version_full(PyObject* self)
9567{
9568 char *version_string;
9569 int family, release, major, minor, patch;
9570
9571 /* This should be instantaneous, no need to release the GIL */
9572 version_string = db_full_version(&family, &release, &major, &minor, &patch);
9573 return Py_BuildValue("(siiiii)",
9574 version_string, family, release, major, minor, patch);
9575}
9576#endif
9577
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009578
9579/* List of functions defined in the module */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009580static PyMethodDef bsddb_methods[] = {
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009581 {"DB", (PyCFunction)DB_construct, METH_VARARGS | METH_KEYWORDS },
9582 {"DBEnv", (PyCFunction)DBEnv_construct, METH_VARARGS},
Gregory P. Smithf0547d02006-06-05 17:38:04 +00009583 {"DBSequence", (PyCFunction)DBSequence_construct, METH_VARARGS | METH_KEYWORDS },
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009584 {"version", (PyCFunction)bsddb_version, METH_NOARGS, bsddb_version_doc},
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009585#if (DBVER >= 50)
9586 {"full_version", (PyCFunction)bsddb_version_full, METH_NOARGS},
9587#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009588 {NULL, NULL} /* sentinel */
9589};
9590
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009591
Gregory P. Smith39250532007-10-09 06:02:21 +00009592/* API structure */
9593static BSDDB_api bsddb_api;
9594
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009595
9596/* --------------------------------------------------------------------- */
9597/* Module initialization */
9598
9599
9600/* Convenience routine to export an integer value.
9601 * Errors are silently ignored, for better or for worse...
9602 */
9603#define ADD_INT(dict, NAME) _addIntToDict(dict, #NAME, NAME)
9604
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009605/*
9606** We can rename the module at import time, so the string allocated
9607** must be big enough, and any use of the name must use this particular
9608** string.
9609*/
Gregory P. Smith41631e82003-09-21 00:08:14 +00009610#define MODULE_NAME_MAX_LEN 11
9611static char _bsddbModuleName[MODULE_NAME_MAX_LEN+1] = "_bsddb";
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009612
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009613#if (PY_VERSION_HEX >= 0x03000000)
9614static struct PyModuleDef bsddbmodule = {
9615 PyModuleDef_HEAD_INIT,
9616 _bsddbModuleName, /* Name of module */
9617 NULL, /* module documentation, may be NULL */
9618 -1, /* size of per-interpreter state of the module,
9619 or -1 if the module keeps state in global variables. */
9620 bsddb_methods,
9621 NULL, /* Reload */
9622 NULL, /* Traverse */
9623 NULL, /* Clear */
9624 NULL /* Free */
9625};
9626#endif
9627
9628
9629#if (PY_VERSION_HEX < 0x03000000)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009630DL_EXPORT(void) init_bsddb(void)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009631#else
9632PyMODINIT_FUNC PyInit__bsddb(void) /* Note the two underscores */
9633#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009634{
9635 PyObject* m;
9636 PyObject* d;
Gregory P. Smith39250532007-10-09 06:02:21 +00009637 PyObject* py_api;
Jesus Cea6557aac2010-03-22 14:22:26 +00009638 PyObject* pybsddb_version_s;
9639 PyObject* db_version_s;
9640 PyObject* cvsid_s;
9641
9642#if (PY_VERSION_HEX < 0x03000000)
9643 pybsddb_version_s = PyString_FromString(PY_BSDDB_VERSION);
9644 db_version_s = PyString_FromString(DB_VERSION_STRING);
9645 cvsid_s = PyString_FromString(rcs_id);
9646#else
9647 /* This data should be ascii, so UTF-8 conversion is fine */
9648 pybsddb_version_s = PyUnicode_FromString(PY_BSDDB_VERSION);
9649 db_version_s = PyUnicode_FromString(DB_VERSION_STRING);
9650 cvsid_s = PyUnicode_FromString(rcs_id);
9651#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009652
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009653 /* Initialize object types */
9654 if ((PyType_Ready(&DB_Type) < 0)
9655 || (PyType_Ready(&DBCursor_Type) < 0)
Jesus Cea6557aac2010-03-22 14:22:26 +00009656 || (PyType_Ready(&DBLogCursor_Type) < 0)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009657 || (PyType_Ready(&DBEnv_Type) < 0)
9658 || (PyType_Ready(&DBTxn_Type) < 0)
9659 || (PyType_Ready(&DBLock_Type) < 0)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009660 || (PyType_Ready(&DBSequence_Type) < 0)
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009661#if (DBVER >= 52)
9662 || (PyType_Ready(&DBSite_Type) < 0)
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009663#endif
9664 ) {
9665#if (PY_VERSION_HEX < 0x03000000)
9666 return;
9667#else
9668 return NULL;
9669#endif
9670 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009671
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009672 /* Create the module and add the functions */
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009673#if (PY_VERSION_HEX < 0x03000000)
Gregory P. Smith41631e82003-09-21 00:08:14 +00009674 m = Py_InitModule(_bsddbModuleName, bsddb_methods);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009675#else
9676 m=PyModule_Create(&bsddbmodule);
9677#endif
9678 if (m == NULL) {
9679#if (PY_VERSION_HEX < 0x03000000)
9680 return;
9681#else
Antoine Pitrouc83ea132010-05-09 14:46:46 +00009682 return NULL;
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009683#endif
9684 }
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009685
9686 /* Add some symbolic constants to the module */
9687 d = PyModule_GetDict(m);
9688 PyDict_SetItemString(d, "__version__", pybsddb_version_s);
9689 PyDict_SetItemString(d, "cvsid", cvsid_s);
9690 PyDict_SetItemString(d, "DB_VERSION_STRING", db_version_s);
9691 Py_DECREF(pybsddb_version_s);
9692 pybsddb_version_s = NULL;
9693 Py_DECREF(cvsid_s);
9694 cvsid_s = NULL;
9695 Py_DECREF(db_version_s);
9696 db_version_s = NULL;
9697
9698 ADD_INT(d, DB_VERSION_MAJOR);
9699 ADD_INT(d, DB_VERSION_MINOR);
9700 ADD_INT(d, DB_VERSION_PATCH);
9701
9702 ADD_INT(d, DB_MAX_PAGES);
9703 ADD_INT(d, DB_MAX_RECORDS);
9704
Matthias Klose54cc5392010-03-15 12:46:18 +00009705#if (DBVER < 48)
Gregory P. Smith41631e82003-09-21 00:08:14 +00009706 ADD_INT(d, DB_RPCCLIENT);
Matthias Klose54cc5392010-03-15 12:46:18 +00009707#endif
9708
9709#if (DBVER < 48)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009710 ADD_INT(d, DB_XA_CREATE);
Matthias Klose54cc5392010-03-15 12:46:18 +00009711#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009712
9713 ADD_INT(d, DB_CREATE);
9714 ADD_INT(d, DB_NOMMAP);
9715 ADD_INT(d, DB_THREAD);
Jesus Ceaef9764f2008-05-13 18:45:46 +00009716#if (DBVER >= 45)
9717 ADD_INT(d, DB_MULTIVERSION);
9718#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009719
9720 ADD_INT(d, DB_FORCE);
9721 ADD_INT(d, DB_INIT_CDB);
9722 ADD_INT(d, DB_INIT_LOCK);
9723 ADD_INT(d, DB_INIT_LOG);
9724 ADD_INT(d, DB_INIT_MPOOL);
9725 ADD_INT(d, DB_INIT_TXN);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009726 ADD_INT(d, DB_JOINENV);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009727
Matthias Klose54cc5392010-03-15 12:46:18 +00009728#if (DBVER >= 48)
9729 ADD_INT(d, DB_GID_SIZE);
9730#else
Jesus Ceaef9764f2008-05-13 18:45:46 +00009731 ADD_INT(d, DB_XIDDATASIZE);
Matthias Klose54cc5392010-03-15 12:46:18 +00009732 /* Allow new code to work in old BDB releases */
9733 _addIntToDict(d, "DB_GID_SIZE", DB_XIDDATASIZE);
9734#endif
Jesus Ceaef9764f2008-05-13 18:45:46 +00009735
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009736 ADD_INT(d, DB_RECOVER);
9737 ADD_INT(d, DB_RECOVER_FATAL);
9738 ADD_INT(d, DB_TXN_NOSYNC);
9739 ADD_INT(d, DB_USE_ENVIRON);
9740 ADD_INT(d, DB_USE_ENVIRON_ROOT);
9741
9742 ADD_INT(d, DB_LOCKDOWN);
9743 ADD_INT(d, DB_PRIVATE);
9744 ADD_INT(d, DB_SYSTEM_MEM);
9745
9746 ADD_INT(d, DB_TXN_SYNC);
9747 ADD_INT(d, DB_TXN_NOWAIT);
9748
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009749#if (DBVER >= 51)
9750 ADD_INT(d, DB_TXN_BULK);
9751#endif
9752
9753#if (DBVER >= 48)
9754 ADD_INT(d, DB_CURSOR_BULK);
9755#endif
9756
Jesus Cea6557aac2010-03-22 14:22:26 +00009757#if (DBVER >= 46)
9758 ADD_INT(d, DB_TXN_WAIT);
9759#endif
9760
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009761 ADD_INT(d, DB_EXCL);
9762 ADD_INT(d, DB_FCNTL_LOCKING);
9763 ADD_INT(d, DB_ODDFILESIZE);
9764 ADD_INT(d, DB_RDWRMASTER);
9765 ADD_INT(d, DB_RDONLY);
9766 ADD_INT(d, DB_TRUNCATE);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009767 ADD_INT(d, DB_EXTENT);
9768 ADD_INT(d, DB_CDB_ALLDB);
9769 ADD_INT(d, DB_VERIFY);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009770 ADD_INT(d, DB_UPGRADE);
9771
Jesus Cea6557aac2010-03-22 14:22:26 +00009772 ADD_INT(d, DB_PRINTABLE);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009773 ADD_INT(d, DB_AGGRESSIVE);
9774 ADD_INT(d, DB_NOORDERCHK);
9775 ADD_INT(d, DB_ORDERCHKONLY);
9776 ADD_INT(d, DB_PR_PAGE);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009777
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009778 ADD_INT(d, DB_PR_RECOVERYTEST);
9779 ADD_INT(d, DB_SALVAGE);
9780
9781 ADD_INT(d, DB_LOCK_NORUN);
9782 ADD_INT(d, DB_LOCK_DEFAULT);
9783 ADD_INT(d, DB_LOCK_OLDEST);
9784 ADD_INT(d, DB_LOCK_RANDOM);
9785 ADD_INT(d, DB_LOCK_YOUNGEST);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009786 ADD_INT(d, DB_LOCK_MAXLOCKS);
9787 ADD_INT(d, DB_LOCK_MINLOCKS);
9788 ADD_INT(d, DB_LOCK_MINWRITE);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009789
Jesus Ceaef9764f2008-05-13 18:45:46 +00009790 ADD_INT(d, DB_LOCK_EXPIRE);
Jesus Ceaef9764f2008-05-13 18:45:46 +00009791 ADD_INT(d, DB_LOCK_MAXWRITE);
Jesus Ceaef9764f2008-05-13 18:45:46 +00009792
Barry Warsaw9a0d7792002-12-30 20:53:52 +00009793 _addIntToDict(d, "DB_LOCK_CONFLICT", 0);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009794
9795 ADD_INT(d, DB_LOCK_DUMP);
9796 ADD_INT(d, DB_LOCK_GET);
9797 ADD_INT(d, DB_LOCK_INHERIT);
9798 ADD_INT(d, DB_LOCK_PUT);
9799 ADD_INT(d, DB_LOCK_PUT_ALL);
9800 ADD_INT(d, DB_LOCK_PUT_OBJ);
9801
9802 ADD_INT(d, DB_LOCK_NG);
9803 ADD_INT(d, DB_LOCK_READ);
9804 ADD_INT(d, DB_LOCK_WRITE);
9805 ADD_INT(d, DB_LOCK_NOWAIT);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009806 ADD_INT(d, DB_LOCK_WAIT);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009807 ADD_INT(d, DB_LOCK_IWRITE);
9808 ADD_INT(d, DB_LOCK_IREAD);
9809 ADD_INT(d, DB_LOCK_IWR);
Gregory P. Smith29602d22006-01-24 09:46:48 +00009810#if (DBVER < 44)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009811 ADD_INT(d, DB_LOCK_DIRTY);
Gregory P. Smith29602d22006-01-24 09:46:48 +00009812#else
9813 ADD_INT(d, DB_LOCK_READ_UNCOMMITTED); /* renamed in 4.4 */
9814#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009815 ADD_INT(d, DB_LOCK_WWRITE);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009816
9817 ADD_INT(d, DB_LOCK_RECORD);
9818 ADD_INT(d, DB_LOCK_UPGRADE);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009819 ADD_INT(d, DB_LOCK_SWITCH);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009820 ADD_INT(d, DB_LOCK_UPGRADE_WRITE);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009821
9822 ADD_INT(d, DB_LOCK_NOWAIT);
9823 ADD_INT(d, DB_LOCK_RECORD);
9824 ADD_INT(d, DB_LOCK_UPGRADE);
9825
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009826 ADD_INT(d, DB_LSTAT_ABORTED);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009827 ADD_INT(d, DB_LSTAT_FREE);
9828 ADD_INT(d, DB_LSTAT_HELD);
Jesus Ceac5a11fa2008-07-23 11:38:42 +00009829
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009830 ADD_INT(d, DB_LSTAT_PENDING);
9831 ADD_INT(d, DB_LSTAT_WAITING);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009832
9833 ADD_INT(d, DB_ARCH_ABS);
9834 ADD_INT(d, DB_ARCH_DATA);
9835 ADD_INT(d, DB_ARCH_LOG);
Gregory P. Smith3dd20022006-06-05 00:31:01 +00009836 ADD_INT(d, DB_ARCH_REMOVE);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009837
9838 ADD_INT(d, DB_BTREE);
9839 ADD_INT(d, DB_HASH);
9840 ADD_INT(d, DB_RECNO);
9841 ADD_INT(d, DB_QUEUE);
9842 ADD_INT(d, DB_UNKNOWN);
9843
9844 ADD_INT(d, DB_DUP);
9845 ADD_INT(d, DB_DUPSORT);
9846 ADD_INT(d, DB_RECNUM);
9847 ADD_INT(d, DB_RENUMBER);
9848 ADD_INT(d, DB_REVSPLITOFF);
9849 ADD_INT(d, DB_SNAPSHOT);
9850
Jesus Cea6557aac2010-03-22 14:22:26 +00009851 ADD_INT(d, DB_INORDER);
Jesus Cea6557aac2010-03-22 14:22:26 +00009852
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009853 ADD_INT(d, DB_JOIN_NOSORT);
9854
9855 ADD_INT(d, DB_AFTER);
9856 ADD_INT(d, DB_APPEND);
9857 ADD_INT(d, DB_BEFORE);
Gregory P. Smith8b96a352007-01-05 01:59:42 +00009858#if (DBVER < 45)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009859 ADD_INT(d, DB_CACHED_COUNTS);
Gregory P. Smith8b96a352007-01-05 01:59:42 +00009860#endif
Jesus Ceaca3939c2008-05-22 15:27:38 +00009861
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009862 ADD_INT(d, DB_CONSUME);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009863 ADD_INT(d, DB_CONSUME_WAIT);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009864 ADD_INT(d, DB_CURRENT);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009865 ADD_INT(d, DB_FAST_STAT);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009866 ADD_INT(d, DB_FIRST);
9867 ADD_INT(d, DB_FLUSH);
9868 ADD_INT(d, DB_GET_BOTH);
Jesus Cea6557aac2010-03-22 14:22:26 +00009869 ADD_INT(d, DB_GET_BOTH_RANGE);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009870 ADD_INT(d, DB_GET_RECNO);
9871 ADD_INT(d, DB_JOIN_ITEM);
9872 ADD_INT(d, DB_KEYFIRST);
9873 ADD_INT(d, DB_KEYLAST);
9874 ADD_INT(d, DB_LAST);
9875 ADD_INT(d, DB_NEXT);
9876 ADD_INT(d, DB_NEXT_DUP);
9877 ADD_INT(d, DB_NEXT_NODUP);
9878 ADD_INT(d, DB_NODUPDATA);
9879 ADD_INT(d, DB_NOOVERWRITE);
9880 ADD_INT(d, DB_NOSYNC);
9881 ADD_INT(d, DB_POSITION);
9882 ADD_INT(d, DB_PREV);
9883 ADD_INT(d, DB_PREV_NODUP);
Jesus Cea6557aac2010-03-22 14:22:26 +00009884#if (DBVER >= 46)
9885 ADD_INT(d, DB_PREV_DUP);
9886#endif
Gregory P. Smith8b96a352007-01-05 01:59:42 +00009887#if (DBVER < 45)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009888 ADD_INT(d, DB_RECORDCOUNT);
Gregory P. Smith8b96a352007-01-05 01:59:42 +00009889#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009890 ADD_INT(d, DB_SET);
9891 ADD_INT(d, DB_SET_RANGE);
9892 ADD_INT(d, DB_SET_RECNO);
9893 ADD_INT(d, DB_WRITECURSOR);
9894
9895 ADD_INT(d, DB_OPFLAGS_MASK);
9896 ADD_INT(d, DB_RMW);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009897 ADD_INT(d, DB_DIRTY_READ);
9898 ADD_INT(d, DB_MULTIPLE);
9899 ADD_INT(d, DB_MULTIPLE_KEY);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009900
Gregory P. Smith29602d22006-01-24 09:46:48 +00009901#if (DBVER >= 44)
Jesus Cea6557aac2010-03-22 14:22:26 +00009902 ADD_INT(d, DB_IMMUTABLE_KEY);
Gregory P. Smith29602d22006-01-24 09:46:48 +00009903 ADD_INT(d, DB_READ_UNCOMMITTED); /* replaces DB_DIRTY_READ in 4.4 */
9904 ADD_INT(d, DB_READ_COMMITTED);
9905#endif
9906
Jesus Cea6557aac2010-03-22 14:22:26 +00009907#if (DBVER >= 44)
9908 ADD_INT(d, DB_FREELIST_ONLY);
9909 ADD_INT(d, DB_FREE_SPACE);
9910#endif
9911
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009912 ADD_INT(d, DB_DONOTINDEX);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009913
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009914 ADD_INT(d, DB_KEYEMPTY);
9915 ADD_INT(d, DB_KEYEXIST);
9916 ADD_INT(d, DB_LOCK_DEADLOCK);
9917 ADD_INT(d, DB_LOCK_NOTGRANTED);
9918 ADD_INT(d, DB_NOSERVER);
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009919#if (DBVER < 52)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009920 ADD_INT(d, DB_NOSERVER_HOME);
9921 ADD_INT(d, DB_NOSERVER_ID);
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009922#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009923 ADD_INT(d, DB_NOTFOUND);
9924 ADD_INT(d, DB_OLD_VERSION);
9925 ADD_INT(d, DB_RUNRECOVERY);
9926 ADD_INT(d, DB_VERIFY_BAD);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009927 ADD_INT(d, DB_PAGE_NOTFOUND);
9928 ADD_INT(d, DB_SECONDARY_BAD);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +00009929 ADD_INT(d, DB_STAT_CLEAR);
9930 ADD_INT(d, DB_REGION_INIT);
9931 ADD_INT(d, DB_NOLOCKING);
9932 ADD_INT(d, DB_YIELDCPU);
9933 ADD_INT(d, DB_PANIC_ENVIRONMENT);
9934 ADD_INT(d, DB_NOPANIC);
Jesus Ceaef9764f2008-05-13 18:45:46 +00009935 ADD_INT(d, DB_OVERWRITE);
Jesus Cea6557aac2010-03-22 14:22:26 +00009936
Jesus Cea6557aac2010-03-22 14:22:26 +00009937 ADD_INT(d, DB_STAT_SUBSYSTEM);
9938 ADD_INT(d, DB_STAT_MEMP_HASH);
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009939 ADD_INT(d, DB_STAT_LOCK_CONF);
9940 ADD_INT(d, DB_STAT_LOCK_LOCKERS);
9941 ADD_INT(d, DB_STAT_LOCK_OBJECTS);
9942 ADD_INT(d, DB_STAT_LOCK_PARAMS);
Jesus Ceaef9764f2008-05-13 18:45:46 +00009943
Jesus Cea6557aac2010-03-22 14:22:26 +00009944#if (DBVER >= 48)
9945 ADD_INT(d, DB_OVERWRITE_DUP);
9946#endif
9947
9948#if (DBVER >= 47)
9949 ADD_INT(d, DB_FOREIGN_ABORT);
9950 ADD_INT(d, DB_FOREIGN_CASCADE);
9951 ADD_INT(d, DB_FOREIGN_NULLIFY);
9952#endif
9953
9954#if (DBVER >= 44)
Gregory P. Smithaae141a2007-11-01 21:08:14 +00009955 ADD_INT(d, DB_REGISTER);
9956#endif
9957
Jesus Cea6557aac2010-03-22 14:22:26 +00009958 ADD_INT(d, DB_EID_INVALID);
9959 ADD_INT(d, DB_EID_BROADCAST);
9960
Gregory P. Smith41631e82003-09-21 00:08:14 +00009961 ADD_INT(d, DB_TIME_NOTGRANTED);
9962 ADD_INT(d, DB_TXN_NOT_DURABLE);
9963 ADD_INT(d, DB_TXN_WRITE_NOSYNC);
Gregory P. Smith41631e82003-09-21 00:08:14 +00009964 ADD_INT(d, DB_DIRECT_DB);
9965 ADD_INT(d, DB_INIT_REP);
9966 ADD_INT(d, DB_ENCRYPT);
9967 ADD_INT(d, DB_CHKSUM);
Gregory P. Smith41631e82003-09-21 00:08:14 +00009968
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -07009969#if (DBVER < 47)
Jesus Ceaca3939c2008-05-22 15:27:38 +00009970 ADD_INT(d, DB_LOG_AUTOREMOVE);
9971 ADD_INT(d, DB_DIRECT_LOG);
9972#endif
9973
9974#if (DBVER >= 47)
9975 ADD_INT(d, DB_LOG_DIRECT);
9976 ADD_INT(d, DB_LOG_DSYNC);
9977 ADD_INT(d, DB_LOG_IN_MEMORY);
9978 ADD_INT(d, DB_LOG_AUTO_REMOVE);
9979 ADD_INT(d, DB_LOG_ZERO);
9980#endif
9981
Jesus Ceaef9764f2008-05-13 18:45:46 +00009982#if (DBVER >= 44)
9983 ADD_INT(d, DB_DSYNC_DB);
9984#endif
9985
9986#if (DBVER >= 45)
9987 ADD_INT(d, DB_TXN_SNAPSHOT);
9988#endif
9989
Jesus Ceaef9764f2008-05-13 18:45:46 +00009990 ADD_INT(d, DB_VERB_DEADLOCK);
9991#if (DBVER >= 46)
9992 ADD_INT(d, DB_VERB_FILEOPS);
9993 ADD_INT(d, DB_VERB_FILEOPS_ALL);
9994#endif
9995 ADD_INT(d, DB_VERB_RECOVERY);
9996#if (DBVER >= 44)
9997 ADD_INT(d, DB_VERB_REGISTER);
9998#endif
9999 ADD_INT(d, DB_VERB_REPLICATION);
10000 ADD_INT(d, DB_VERB_WAITSFOR);
Jesus Ceaef9764f2008-05-13 18:45:46 +000010001
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010002#if (DBVER >= 50)
10003 ADD_INT(d, DB_VERB_REP_SYSTEM);
10004#endif
10005
10006#if (DBVER >= 47)
10007 ADD_INT(d, DB_VERB_REP_ELECT);
10008 ADD_INT(d, DB_VERB_REP_LEASE);
10009 ADD_INT(d, DB_VERB_REP_MISC);
10010 ADD_INT(d, DB_VERB_REP_MSGS);
10011 ADD_INT(d, DB_VERB_REP_SYNC);
10012 ADD_INT(d, DB_VERB_REPMGR_CONNFAIL);
10013 ADD_INT(d, DB_VERB_REPMGR_MISC);
10014#endif
10015
Jesus Ceaef9764f2008-05-13 18:45:46 +000010016#if (DBVER >= 45)
10017 ADD_INT(d, DB_EVENT_PANIC);
10018 ADD_INT(d, DB_EVENT_REP_CLIENT);
10019#if (DBVER >= 46)
10020 ADD_INT(d, DB_EVENT_REP_ELECTED);
10021#endif
10022 ADD_INT(d, DB_EVENT_REP_MASTER);
10023 ADD_INT(d, DB_EVENT_REP_NEWMASTER);
10024#if (DBVER >= 46)
10025 ADD_INT(d, DB_EVENT_REP_PERM_FAILED);
10026#endif
10027 ADD_INT(d, DB_EVENT_REP_STARTUPDONE);
10028 ADD_INT(d, DB_EVENT_WRITE_FAILED);
10029#endif
10030
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010031#if (DBVER >= 50)
10032 ADD_INT(d, DB_REPMGR_CONF_ELECTIONS);
10033 ADD_INT(d, DB_EVENT_REP_MASTER_FAILURE);
10034 ADD_INT(d, DB_EVENT_REP_DUPMASTER);
10035 ADD_INT(d, DB_EVENT_REP_ELECTION_FAILED);
10036#endif
10037#if (DBVER >= 48)
10038 ADD_INT(d, DB_EVENT_REG_ALIVE);
10039 ADD_INT(d, DB_EVENT_REG_PANIC);
10040#endif
10041
10042#if (DBVER >=52)
10043 ADD_INT(d, DB_EVENT_REP_SITE_ADDED);
10044 ADD_INT(d, DB_EVENT_REP_SITE_REMOVED);
10045 ADD_INT(d, DB_EVENT_REP_LOCAL_SITE_REMOVED);
10046 ADD_INT(d, DB_EVENT_REP_CONNECT_BROKEN);
10047 ADD_INT(d, DB_EVENT_REP_CONNECT_ESTD);
10048 ADD_INT(d, DB_EVENT_REP_CONNECT_TRY_FAILED);
10049 ADD_INT(d, DB_EVENT_REP_INIT_DONE);
10050
10051 ADD_INT(d, DB_MEM_LOCK);
10052 ADD_INT(d, DB_MEM_LOCKOBJECT);
10053 ADD_INT(d, DB_MEM_LOCKER);
10054 ADD_INT(d, DB_MEM_LOGID);
10055 ADD_INT(d, DB_MEM_TRANSACTION);
10056 ADD_INT(d, DB_MEM_THREAD);
10057
10058 ADD_INT(d, DB_BOOTSTRAP_HELPER);
10059 ADD_INT(d, DB_GROUP_CREATOR);
10060 ADD_INT(d, DB_LEGACY);
10061 ADD_INT(d, DB_LOCAL_SITE);
10062 ADD_INT(d, DB_REPMGR_PEER);
10063#endif
10064
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010065 ADD_INT(d, DB_REP_DUPMASTER);
10066 ADD_INT(d, DB_REP_HOLDELECTION);
10067#if (DBVER >= 44)
10068 ADD_INT(d, DB_REP_IGNORE);
10069 ADD_INT(d, DB_REP_JOIN_FAILURE);
10070#endif
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010071 ADD_INT(d, DB_REP_ISPERM);
10072 ADD_INT(d, DB_REP_NOTPERM);
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010073 ADD_INT(d, DB_REP_NEWSITE);
10074
Jesus Ceaef9764f2008-05-13 18:45:46 +000010075 ADD_INT(d, DB_REP_MASTER);
10076 ADD_INT(d, DB_REP_CLIENT);
Jesus Cea6557aac2010-03-22 14:22:26 +000010077
10078 ADD_INT(d, DB_REP_PERMANENT);
10079
10080#if (DBVER >= 44)
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010081#if (DBVER >= 50)
10082 ADD_INT(d, DB_REP_CONF_AUTOINIT);
10083#else
Jesus Cea6557aac2010-03-22 14:22:26 +000010084 ADD_INT(d, DB_REP_CONF_NOAUTOINIT);
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010085#endif /* 5.0 */
10086#endif /* 4.4 */
10087#if (DBVER >= 44)
Jesus Cea6557aac2010-03-22 14:22:26 +000010088 ADD_INT(d, DB_REP_CONF_DELAYCLIENT);
10089 ADD_INT(d, DB_REP_CONF_BULK);
10090 ADD_INT(d, DB_REP_CONF_NOWAIT);
10091 ADD_INT(d, DB_REP_ANYWHERE);
10092 ADD_INT(d, DB_REP_REREQUEST);
10093#endif
10094
Jesus Cea6557aac2010-03-22 14:22:26 +000010095 ADD_INT(d, DB_REP_NOBUFFER);
Jesus Cea6557aac2010-03-22 14:22:26 +000010096
10097#if (DBVER >= 46)
10098 ADD_INT(d, DB_REP_LEASE_EXPIRED);
10099 ADD_INT(d, DB_IGNORE_LEASE);
10100#endif
10101
10102#if (DBVER >= 47)
10103 ADD_INT(d, DB_REP_CONF_LEASE);
10104 ADD_INT(d, DB_REPMGR_CONF_2SITE_STRICT);
10105#endif
10106
Jesus Ceaef9764f2008-05-13 18:45:46 +000010107#if (DBVER >= 45)
10108 ADD_INT(d, DB_REP_ELECTION);
10109
10110 ADD_INT(d, DB_REP_ACK_TIMEOUT);
10111 ADD_INT(d, DB_REP_CONNECTION_RETRY);
10112 ADD_INT(d, DB_REP_ELECTION_TIMEOUT);
10113 ADD_INT(d, DB_REP_ELECTION_RETRY);
10114#endif
10115#if (DBVER >= 46)
10116 ADD_INT(d, DB_REP_CHECKPOINT_DELAY);
10117 ADD_INT(d, DB_REP_FULL_ELECTION_TIMEOUT);
Jesus Cea6557aac2010-03-22 14:22:26 +000010118 ADD_INT(d, DB_REP_LEASE_TIMEOUT);
10119#endif
10120#if (DBVER >= 47)
10121 ADD_INT(d, DB_REP_HEARTBEAT_MONITOR);
10122 ADD_INT(d, DB_REP_HEARTBEAT_SEND);
Jesus Ceaef9764f2008-05-13 18:45:46 +000010123#endif
Jesus Ceaef9764f2008-05-13 18:45:46 +000010124
10125#if (DBVER >= 45)
10126 ADD_INT(d, DB_REPMGR_PEER);
10127 ADD_INT(d, DB_REPMGR_ACKS_ALL);
10128 ADD_INT(d, DB_REPMGR_ACKS_ALL_PEERS);
10129 ADD_INT(d, DB_REPMGR_ACKS_NONE);
10130 ADD_INT(d, DB_REPMGR_ACKS_ONE);
10131 ADD_INT(d, DB_REPMGR_ACKS_ONE_PEER);
10132 ADD_INT(d, DB_REPMGR_ACKS_QUORUM);
10133 ADD_INT(d, DB_REPMGR_CONNECTED);
10134 ADD_INT(d, DB_REPMGR_DISCONNECTED);
Jesus Ceaef9764f2008-05-13 18:45:46 +000010135 ADD_INT(d, DB_STAT_ALL);
10136#endif
10137
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010138#if (DBVER >= 51)
10139 ADD_INT(d, DB_REPMGR_ACKS_ALL_AVAILABLE);
10140#endif
10141
10142#if (DBVER >= 48)
10143 ADD_INT(d, DB_REP_CONF_INMEM);
10144#endif
10145
10146 ADD_INT(d, DB_TIMEOUT);
10147
10148#if (DBVER >= 50)
10149 ADD_INT(d, DB_FORCESYNC);
10150#endif
10151
10152#if (DBVER >= 48)
10153 ADD_INT(d, DB_FAILCHK);
10154#endif
10155
10156#if (DBVER >= 51)
10157 ADD_INT(d, DB_HOTBACKUP_IN_PROGRESS);
10158#endif
10159
Gregory P. Smith8b7e9172004-12-13 09:51:23 +000010160 ADD_INT(d, DB_BUFFER_SMALL);
Gregory P. Smithf0547d02006-06-05 17:38:04 +000010161 ADD_INT(d, DB_SEQ_DEC);
10162 ADD_INT(d, DB_SEQ_INC);
10163 ADD_INT(d, DB_SEQ_WRAP);
Gregory P. Smith8b7e9172004-12-13 09:51:23 +000010164
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010165#if (DBVER < 47)
Jesus Ceaca3939c2008-05-22 15:27:38 +000010166 ADD_INT(d, DB_LOG_INMEMORY);
10167 ADD_INT(d, DB_DSYNC_LOG);
10168#endif
10169
Barry Warsaw9a0d7792002-12-30 20:53:52 +000010170 ADD_INT(d, DB_ENCRYPT_AES);
10171 ADD_INT(d, DB_AUTO_COMMIT);
Jesus Cea6557aac2010-03-22 14:22:26 +000010172 ADD_INT(d, DB_PRIORITY_VERY_LOW);
10173 ADD_INT(d, DB_PRIORITY_LOW);
10174 ADD_INT(d, DB_PRIORITY_DEFAULT);
10175 ADD_INT(d, DB_PRIORITY_HIGH);
10176 ADD_INT(d, DB_PRIORITY_VERY_HIGH);
10177
10178#if (DBVER >= 46)
10179 ADD_INT(d, DB_PRIORITY_UNCHANGED);
Barry Warsaw9a0d7792002-12-30 20:53:52 +000010180#endif
10181
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010182 ADD_INT(d, EINVAL);
10183 ADD_INT(d, EACCES);
10184 ADD_INT(d, ENOSPC);
10185 ADD_INT(d, ENOMEM);
10186 ADD_INT(d, EAGAIN);
10187 ADD_INT(d, EBUSY);
10188 ADD_INT(d, EEXIST);
10189 ADD_INT(d, ENOENT);
10190 ADD_INT(d, EPERM);
10191
Barry Warsaw1baa9822003-03-31 19:51:29 +000010192 ADD_INT(d, DB_SET_LOCK_TIMEOUT);
10193 ADD_INT(d, DB_SET_TXN_TIMEOUT);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010194
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010195#if (DBVER >= 48)
10196 ADD_INT(d, DB_SET_REG_TIMEOUT);
10197#endif
10198
Gregory P. Smith7f5b6f42006-04-08 07:10:51 +000010199 /* The exception name must be correct for pickled exception *
10200 * objects to unpickle properly. */
10201#ifdef PYBSDDB_STANDALONE /* different value needed for standalone pybsddb */
10202#define PYBSDDB_EXCEPTION_BASE "bsddb3.db."
10203#else
10204#define PYBSDDB_EXCEPTION_BASE "bsddb.db."
10205#endif
10206
10207 /* All the rest of the exceptions derive only from DBError */
10208#define MAKE_EX(name) name = PyErr_NewException(PYBSDDB_EXCEPTION_BASE #name, DBError, NULL); \
10209 PyDict_SetItemString(d, #name, name)
10210
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010211 /* The base exception class is DBError */
Gregory P. Smith7f5b6f42006-04-08 07:10:51 +000010212 DBError = NULL; /* used in MAKE_EX so that it derives from nothing */
10213 MAKE_EX(DBError);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010214
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010215#if (PY_VERSION_HEX < 0x03000000)
Gregory P. Smithe9477062005-06-04 06:46:59 +000010216 /* Some magic to make DBNotFoundError and DBKeyEmptyError derive
10217 * from both DBError and KeyError, since the API only supports
10218 * using one base class. */
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010219 PyDict_SetItemString(d, "KeyError", PyExc_KeyError);
Gregory P. Smithe9477062005-06-04 06:46:59 +000010220 PyRun_String("class DBNotFoundError(DBError, KeyError): pass\n"
Antoine Pitrouc83ea132010-05-09 14:46:46 +000010221 "class DBKeyEmptyError(DBError, KeyError): pass",
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010222 Py_file_input, d, d);
10223 DBNotFoundError = PyDict_GetItemString(d, "DBNotFoundError");
Gregory P. Smithe9477062005-06-04 06:46:59 +000010224 DBKeyEmptyError = PyDict_GetItemString(d, "DBKeyEmptyError");
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010225 PyDict_DelItemString(d, "KeyError");
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010226#else
10227 /* Since Python 2.5, PyErr_NewException() accepts a tuple, to be able to
10228 ** derive from several classes. We use this new API only for Python 3.0,
10229 ** though.
10230 */
10231 {
10232 PyObject* bases;
10233
10234 bases = PyTuple_Pack(2, DBError, PyExc_KeyError);
10235
10236#define MAKE_EX2(name) name = PyErr_NewException(PYBSDDB_EXCEPTION_BASE #name, bases, NULL); \
10237 PyDict_SetItemString(d, #name, name)
10238 MAKE_EX2(DBNotFoundError);
10239 MAKE_EX2(DBKeyEmptyError);
10240
10241#undef MAKE_EX2
10242
10243 Py_XDECREF(bases);
10244 }
10245#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010246
Gregory P. Smithe2767172003-11-02 08:06:29 +000010247 MAKE_EX(DBCursorClosedError);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010248 MAKE_EX(DBKeyExistError);
10249 MAKE_EX(DBLockDeadlockError);
10250 MAKE_EX(DBLockNotGrantedError);
10251 MAKE_EX(DBOldVersionError);
10252 MAKE_EX(DBRunRecoveryError);
10253 MAKE_EX(DBVerifyBadError);
10254 MAKE_EX(DBNoServerError);
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010255#if (DBVER < 52)
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010256 MAKE_EX(DBNoServerHomeError);
10257 MAKE_EX(DBNoServerIDError);
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010258#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010259 MAKE_EX(DBPageNotFoundError);
10260 MAKE_EX(DBSecondaryBadError);
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010261
10262 MAKE_EX(DBInvalidArgError);
10263 MAKE_EX(DBAccessError);
10264 MAKE_EX(DBNoSpaceError);
10265 MAKE_EX(DBNoMemoryError);
10266 MAKE_EX(DBAgainError);
10267 MAKE_EX(DBBusyError);
10268 MAKE_EX(DBFileExistsError);
10269 MAKE_EX(DBNoSuchFileError);
10270 MAKE_EX(DBPermissionsError);
10271
Jesus Ceaef9764f2008-05-13 18:45:46 +000010272 MAKE_EX(DBRepHandleDeadError);
Jesus Cea6557aac2010-03-22 14:22:26 +000010273#if (DBVER >= 44)
10274 MAKE_EX(DBRepLockoutError);
10275#endif
Jesus Ceaef9764f2008-05-13 18:45:46 +000010276
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010277 MAKE_EX(DBRepUnavailError);
10278
Jesus Cea6557aac2010-03-22 14:22:26 +000010279#if (DBVER >= 46)
10280 MAKE_EX(DBRepLeaseExpiredError);
10281#endif
10282
10283#if (DBVER >= 47)
10284 MAKE_EX(DBForeignConflictError);
10285#endif
10286
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010287#undef MAKE_EX
10288
Jesus Cea6557aac2010-03-22 14:22:26 +000010289 /* Initialise the C API structure and add it to the module */
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010290 bsddb_api.api_version = PYBSDDB_API_VERSION;
Jesus Cea6557aac2010-03-22 14:22:26 +000010291 bsddb_api.db_type = &DB_Type;
10292 bsddb_api.dbcursor_type = &DBCursor_Type;
10293 bsddb_api.dblogcursor_type = &DBLogCursor_Type;
10294 bsddb_api.dbenv_type = &DBEnv_Type;
10295 bsddb_api.dbtxn_type = &DBTxn_Type;
10296 bsddb_api.dblock_type = &DBLock_Type;
Jesus Cea6557aac2010-03-22 14:22:26 +000010297 bsddb_api.dbsequence_type = &DBSequence_Type;
Jesus Cea6557aac2010-03-22 14:22:26 +000010298 bsddb_api.makeDBError = makeDBError;
Gregory P. Smith39250532007-10-09 06:02:21 +000010299
Jesus Cea6557aac2010-03-22 14:22:26 +000010300 /*
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010301 ** Capsules exist from Python 2.7 and 3.1.
10302 ** We don't support Python 3.0 anymore, so...
10303 ** #if (PY_VERSION_HEX < ((PY_MAJOR_VERSION < 3) ? 0x02070000 : 0x03020000))
Jesus Cea6557aac2010-03-22 14:22:26 +000010304 */
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010305#if (PY_VERSION_HEX < 0x02070000)
Gregory P. Smith39250532007-10-09 06:02:21 +000010306 py_api = PyCObject_FromVoidPtr((void*)&bsddb_api, NULL);
Jesus Cea6557aac2010-03-22 14:22:26 +000010307#else
10308 {
doko@ubuntu.com4950a3b2013-03-19 14:46:29 -070010309 /*
10310 ** The data must outlive the call!!. So, the static definition.
10311 ** The buffer must be big enough...
10312 */
10313 static char py_api_name[MODULE_NAME_MAX_LEN+10];
Jesus Cea6557aac2010-03-22 14:22:26 +000010314
10315 strcpy(py_api_name, _bsddbModuleName);
10316 strcat(py_api_name, ".api");
10317
10318 py_api = PyCapsule_New((void*)&bsddb_api, py_api_name, NULL);
10319 }
10320#endif
10321
Jesus Cea84f2c322010-11-05 00:13:50 +000010322 /* Check error control */
10323 /*
10324 ** PyErr_NoMemory();
10325 ** py_api = NULL;
10326 */
10327
10328 if (py_api) {
10329 PyDict_SetItemString(d, "api", py_api);
10330 Py_DECREF(py_api);
10331 } else { /* Something bad happened */
10332 PyErr_WriteUnraisable(m);
Jesus Ceabf088f82010-11-08 12:57:59 +000010333 if(PyErr_Warn(PyExc_RuntimeWarning,
10334 "_bsddb/_pybsddb C API will be not available")) {
10335 PyErr_WriteUnraisable(m);
10336 }
Jesus Cea84f2c322010-11-05 00:13:50 +000010337 PyErr_Clear();
10338 }
Gregory P. Smith39250532007-10-09 06:02:21 +000010339
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010340 /* Check for errors */
10341 if (PyErr_Occurred()) {
10342 PyErr_Print();
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010343 Py_FatalError("can't initialize module _bsddb/_pybsddb");
10344 Py_DECREF(m);
10345 m = NULL;
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010346 }
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010347#if (PY_VERSION_HEX < 0x03000000)
10348 return;
10349#else
10350 return m;
10351#endif
Martin v. Löwis6aa4a1f2002-11-19 08:09:52 +000010352}
Gregory P. Smith41631e82003-09-21 00:08:14 +000010353
10354/* allow this module to be named _pybsddb so that it can be installed
10355 * and imported on top of python >= 2.3 that includes its own older
10356 * copy of the library named _bsddb without importing the old version. */
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010357#if (PY_VERSION_HEX < 0x03000000)
Gregory P. Smith41631e82003-09-21 00:08:14 +000010358DL_EXPORT(void) init_pybsddb(void)
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010359#else
10360PyMODINIT_FUNC PyInit__pybsddb(void) /* Note the two underscores */
10361#endif
Gregory P. Smith41631e82003-09-21 00:08:14 +000010362{
10363 strncpy(_bsddbModuleName, "_pybsddb", MODULE_NAME_MAX_LEN);
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010364#if (PY_VERSION_HEX < 0x03000000)
Gregory P. Smith41631e82003-09-21 00:08:14 +000010365 init_bsddb();
Jesus Ceac5a11fa2008-07-23 11:38:42 +000010366#else
10367 return PyInit__bsddb(); /* Note the two underscores */
10368#endif
Gregory P. Smith41631e82003-09-21 00:08:14 +000010369}