Gregory P. Smith | 3925053 | 2007-10-09 06:02:21 +0000 | [diff] [blame] | 1 | /*---------------------------------------------------------------------- |
| 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, |
| 38 | * written to replace a SWIG-generated file. It has since been updated |
Jesus Cea | ef9764f | 2008-05-13 18:45:46 +0000 | [diff] [blame] | 39 | * to compile with Berkeley DB versions 3.2 through 4.2. |
Gregory P. Smith | 3925053 | 2007-10-09 06:02:21 +0000 | [diff] [blame] | 40 | * |
| 41 | * This module was started by Andrew Kuchling to remove the dependency |
| 42 | * 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. |
| 45 | * |
| 46 | * 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 | * |
| 51 | * Gregory P. Smith <greg@krypto.org> is once again the maintainer. |
| 52 | * |
| 53 | * Use the pybsddb-users@lists.sf.net mailing list for all questions. |
| 54 | * Things can change faster than the header of this file is updated. This |
| 55 | * file is shared with the PyBSDDB project at SourceForge: |
| 56 | * |
| 57 | * http://pybsddb.sf.net |
| 58 | * |
| 59 | * This file should remain backward compatible with Python 2.1, but see PEP |
| 60 | * 291 for the most current backward compatibility requirements: |
| 61 | * |
| 62 | * http://www.python.org/peps/pep-0291.html |
| 63 | * |
doko@ubuntu.com | 4950a3b | 2013-03-19 14:46:29 -0700 | [diff] [blame] | 64 | * This module contains 7 types: |
Gregory P. Smith | 3925053 | 2007-10-09 06:02:21 +0000 | [diff] [blame] | 65 | * |
| 66 | * DB (Database) |
| 67 | * DBCursor (Database Cursor) |
| 68 | * DBEnv (database environment) |
| 69 | * DBTxn (An explicit database transaction) |
| 70 | * DBLock (A lock handle) |
| 71 | * DBSequence (Sequence) |
doko@ubuntu.com | 4950a3b | 2013-03-19 14:46:29 -0700 | [diff] [blame] | 72 | * DBSite (Site) |
Gregory P. Smith | 3925053 | 2007-10-09 06:02:21 +0000 | [diff] [blame] | 73 | * |
Jesus Cea | 6557aac | 2010-03-22 14:22:26 +0000 | [diff] [blame] | 74 | * New datatypes: |
| 75 | * |
| 76 | * DBLogCursor (Log Cursor) |
| 77 | * |
Gregory P. Smith | 3925053 | 2007-10-09 06:02:21 +0000 | [diff] [blame] | 78 | */ |
| 79 | |
| 80 | /* --------------------------------------------------------------------- */ |
| 81 | |
| 82 | /* |
| 83 | * Portions of this module, associated unit tests and build scripts are the |
| 84 | * result of a contract with The Written Word (http://thewrittenword.com/) |
| 85 | * Many thanks go out to them for causing me to raise the bar on quality and |
| 86 | * functionality, resulting in a better bsddb3 package for all of us to use. |
| 87 | * |
| 88 | * --Robin |
| 89 | */ |
| 90 | |
| 91 | /* --------------------------------------------------------------------- */ |
| 92 | |
| 93 | /* |
| 94 | * Work to split it up into a separate header and to add a C API was |
| 95 | * contributed by Duncan Grisby <duncan@tideway.com>. See here: |
| 96 | * http://sourceforge.net/tracker/index.php?func=detail&aid=1551895&group_id=13900&atid=313900 |
| 97 | */ |
| 98 | |
| 99 | /* --------------------------------------------------------------------- */ |
| 100 | |
| 101 | #ifndef _BSDDB_H_ |
| 102 | #define _BSDDB_H_ |
| 103 | |
| 104 | #include <db.h> |
| 105 | |
| 106 | |
| 107 | /* 40 = 4.0, 33 = 3.3; this will break if the minor revision is > 9 */ |
| 108 | #define DBVER (DB_VERSION_MAJOR * 10 + DB_VERSION_MINOR) |
| 109 | #if DB_VERSION_MINOR > 9 |
| 110 | #error "eek! DBVER can't handle minor versions > 9" |
| 111 | #endif |
| 112 | |
doko@ubuntu.com | 4950a3b | 2013-03-19 14:46:29 -0700 | [diff] [blame] | 113 | #define PY_BSDDB_VERSION "5.3.0" |
Gregory P. Smith | 3925053 | 2007-10-09 06:02:21 +0000 | [diff] [blame] | 114 | |
| 115 | /* Python object definitions */ |
| 116 | |
| 117 | struct behaviourFlags { |
| 118 | /* What is the default behaviour when DB->get or DBCursor->get returns a |
| 119 | DB_NOTFOUND || DB_KEYEMPTY error? Return None or raise an exception? */ |
| 120 | unsigned int getReturnsNone : 1; |
| 121 | /* What is the default behaviour for DBCursor.set* methods when DBCursor->get |
| 122 | * returns a DB_NOTFOUND || DB_KEYEMPTY error? Return None or raise? */ |
| 123 | unsigned int cursorSetReturnsNone : 1; |
| 124 | }; |
| 125 | |
| 126 | |
Jesus Cea | ef9764f | 2008-05-13 18:45:46 +0000 | [diff] [blame] | 127 | |
| 128 | struct DBObject; /* Forward declaration */ |
| 129 | struct DBCursorObject; /* Forward declaration */ |
Jesus Cea | 6557aac | 2010-03-22 14:22:26 +0000 | [diff] [blame] | 130 | struct DBLogCursorObject; /* Forward declaration */ |
Jesus Cea | ef9764f | 2008-05-13 18:45:46 +0000 | [diff] [blame] | 131 | struct DBTxnObject; /* Forward declaration */ |
| 132 | struct DBSequenceObject; /* Forward declaration */ |
doko@ubuntu.com | 4950a3b | 2013-03-19 14:46:29 -0700 | [diff] [blame] | 133 | #if (DBVER >= 52) |
| 134 | struct DBSiteObject; /* Forward declaration */ |
| 135 | #endif |
Jesus Cea | ef9764f | 2008-05-13 18:45:46 +0000 | [diff] [blame] | 136 | |
Gregory P. Smith | 3925053 | 2007-10-09 06:02:21 +0000 | [diff] [blame] | 137 | typedef struct { |
| 138 | PyObject_HEAD |
| 139 | DB_ENV* db_env; |
| 140 | u_int32_t flags; /* saved flags from open() */ |
| 141 | int closed; |
| 142 | struct behaviourFlags moduleFlags; |
Jesus Cea | ef9764f | 2008-05-13 18:45:46 +0000 | [diff] [blame] | 143 | PyObject* event_notifyCallback; |
Jesus Cea | ef9764f | 2008-05-13 18:45:46 +0000 | [diff] [blame] | 144 | struct DBObject *children_dbs; |
| 145 | struct DBTxnObject *children_txns; |
Jesus Cea | 6557aac | 2010-03-22 14:22:26 +0000 | [diff] [blame] | 146 | struct DBLogCursorObject *children_logcursors; |
doko@ubuntu.com | 4950a3b | 2013-03-19 14:46:29 -0700 | [diff] [blame] | 147 | #if (DBVER >= 52) |
| 148 | struct DBSiteObject *children_sites; |
| 149 | #endif |
Jesus Cea | 4907d27 | 2008-08-31 14:00:51 +0000 | [diff] [blame] | 150 | PyObject *private_obj; |
Jesus Cea | c5a11fa | 2008-07-23 11:38:42 +0000 | [diff] [blame] | 151 | PyObject *rep_transport; |
Gregory P. Smith | 3925053 | 2007-10-09 06:02:21 +0000 | [diff] [blame] | 152 | PyObject *in_weakreflist; /* List of weak references */ |
| 153 | } DBEnvObject; |
| 154 | |
Jesus Cea | ef9764f | 2008-05-13 18:45:46 +0000 | [diff] [blame] | 155 | typedef struct DBObject { |
Gregory P. Smith | 3925053 | 2007-10-09 06:02:21 +0000 | [diff] [blame] | 156 | PyObject_HEAD |
| 157 | DB* db; |
| 158 | DBEnvObject* myenvobj; /* PyObject containing the DB_ENV */ |
| 159 | u_int32_t flags; /* saved flags from open() */ |
| 160 | u_int32_t setflags; /* saved flags from set_flags() */ |
Gregory P. Smith | 3925053 | 2007-10-09 06:02:21 +0000 | [diff] [blame] | 161 | struct behaviourFlags moduleFlags; |
Jesus Cea | ef9764f | 2008-05-13 18:45:46 +0000 | [diff] [blame] | 162 | struct DBTxnObject *txn; |
| 163 | struct DBCursorObject *children_cursors; |
Jesus Cea | ef9764f | 2008-05-13 18:45:46 +0000 | [diff] [blame] | 164 | struct DBSequenceObject *children_sequences; |
Jesus Cea | ef9764f | 2008-05-13 18:45:46 +0000 | [diff] [blame] | 165 | struct DBObject **sibling_prev_p; |
| 166 | struct DBObject *sibling_next; |
| 167 | struct DBObject **sibling_prev_p_txn; |
| 168 | struct DBObject *sibling_next_txn; |
Gregory P. Smith | 3925053 | 2007-10-09 06:02:21 +0000 | [diff] [blame] | 169 | PyObject* associateCallback; |
| 170 | PyObject* btCompareCallback; |
doko@ubuntu.com | 4950a3b | 2013-03-19 14:46:29 -0700 | [diff] [blame] | 171 | PyObject* dupCompareCallback; |
Gregory P. Smith | 3925053 | 2007-10-09 06:02:21 +0000 | [diff] [blame] | 172 | int primaryDBType; |
Jesus Cea | 4907d27 | 2008-08-31 14:00:51 +0000 | [diff] [blame] | 173 | PyObject *private_obj; |
Gregory P. Smith | 3925053 | 2007-10-09 06:02:21 +0000 | [diff] [blame] | 174 | PyObject *in_weakreflist; /* List of weak references */ |
| 175 | } DBObject; |
| 176 | |
| 177 | |
Jesus Cea | ef9764f | 2008-05-13 18:45:46 +0000 | [diff] [blame] | 178 | typedef struct DBCursorObject { |
Gregory P. Smith | 3925053 | 2007-10-09 06:02:21 +0000 | [diff] [blame] | 179 | PyObject_HEAD |
| 180 | DBC* dbc; |
Jesus Cea | ef9764f | 2008-05-13 18:45:46 +0000 | [diff] [blame] | 181 | struct DBCursorObject **sibling_prev_p; |
| 182 | struct DBCursorObject *sibling_next; |
| 183 | struct DBCursorObject **sibling_prev_p_txn; |
| 184 | struct DBCursorObject *sibling_next_txn; |
Gregory P. Smith | 3925053 | 2007-10-09 06:02:21 +0000 | [diff] [blame] | 185 | DBObject* mydb; |
Jesus Cea | ef9764f | 2008-05-13 18:45:46 +0000 | [diff] [blame] | 186 | struct DBTxnObject *txn; |
Gregory P. Smith | 3925053 | 2007-10-09 06:02:21 +0000 | [diff] [blame] | 187 | PyObject *in_weakreflist; /* List of weak references */ |
| 188 | } DBCursorObject; |
| 189 | |
| 190 | |
Jesus Cea | ef9764f | 2008-05-13 18:45:46 +0000 | [diff] [blame] | 191 | typedef struct DBTxnObject { |
Gregory P. Smith | 3925053 | 2007-10-09 06:02:21 +0000 | [diff] [blame] | 192 | PyObject_HEAD |
| 193 | DB_TXN* txn; |
Jesus Cea | ef9764f | 2008-05-13 18:45:46 +0000 | [diff] [blame] | 194 | DBEnvObject* env; |
| 195 | int flag_prepare; |
| 196 | struct DBTxnObject *parent_txn; |
| 197 | struct DBTxnObject **sibling_prev_p; |
| 198 | struct DBTxnObject *sibling_next; |
| 199 | struct DBTxnObject *children_txns; |
| 200 | struct DBObject *children_dbs; |
| 201 | struct DBSequenceObject *children_sequences; |
| 202 | struct DBCursorObject *children_cursors; |
Gregory P. Smith | 3925053 | 2007-10-09 06:02:21 +0000 | [diff] [blame] | 203 | PyObject *in_weakreflist; /* List of weak references */ |
| 204 | } DBTxnObject; |
| 205 | |
| 206 | |
Jesus Cea | 6557aac | 2010-03-22 14:22:26 +0000 | [diff] [blame] | 207 | typedef struct DBLogCursorObject { |
| 208 | PyObject_HEAD |
| 209 | DB_LOGC* logc; |
| 210 | DBEnvObject* env; |
| 211 | struct DBLogCursorObject **sibling_prev_p; |
| 212 | struct DBLogCursorObject *sibling_next; |
| 213 | PyObject *in_weakreflist; /* List of weak references */ |
| 214 | } DBLogCursorObject; |
| 215 | |
doko@ubuntu.com | 4950a3b | 2013-03-19 14:46:29 -0700 | [diff] [blame] | 216 | #if (DBVER >= 52) |
| 217 | typedef struct DBSiteObject { |
| 218 | PyObject_HEAD |
| 219 | DB_SITE *site; |
| 220 | DBEnvObject *env; |
| 221 | struct DBSiteObject **sibling_prev_p; |
| 222 | struct DBSiteObject *sibling_next; |
| 223 | PyObject *in_weakreflist; /* List of weak references */ |
| 224 | } DBSiteObject; |
| 225 | #endif |
Jesus Cea | 6557aac | 2010-03-22 14:22:26 +0000 | [diff] [blame] | 226 | |
Gregory P. Smith | 3925053 | 2007-10-09 06:02:21 +0000 | [diff] [blame] | 227 | typedef struct { |
| 228 | PyObject_HEAD |
| 229 | DB_LOCK lock; |
Jesus Cea | 6557aac | 2010-03-22 14:22:26 +0000 | [diff] [blame] | 230 | int lock_initialized; /* Signal if we actually have a lock */ |
Gregory P. Smith | 3925053 | 2007-10-09 06:02:21 +0000 | [diff] [blame] | 231 | PyObject *in_weakreflist; /* List of weak references */ |
| 232 | } DBLockObject; |
| 233 | |
| 234 | |
Jesus Cea | ef9764f | 2008-05-13 18:45:46 +0000 | [diff] [blame] | 235 | typedef struct DBSequenceObject { |
Gregory P. Smith | 3925053 | 2007-10-09 06:02:21 +0000 | [diff] [blame] | 236 | PyObject_HEAD |
| 237 | DB_SEQUENCE* sequence; |
| 238 | DBObject* mydb; |
Jesus Cea | ef9764f | 2008-05-13 18:45:46 +0000 | [diff] [blame] | 239 | struct DBTxnObject *txn; |
| 240 | struct DBSequenceObject **sibling_prev_p; |
| 241 | struct DBSequenceObject *sibling_next; |
| 242 | struct DBSequenceObject **sibling_prev_p_txn; |
| 243 | struct DBSequenceObject *sibling_next_txn; |
Gregory P. Smith | 3925053 | 2007-10-09 06:02:21 +0000 | [diff] [blame] | 244 | PyObject *in_weakreflist; /* List of weak references */ |
| 245 | } DBSequenceObject; |
Gregory P. Smith | 3925053 | 2007-10-09 06:02:21 +0000 | [diff] [blame] | 246 | |
| 247 | |
| 248 | /* API structure for use by C code */ |
| 249 | |
| 250 | /* To access the structure from an external module, use code like the |
| 251 | following (error checking missed out for clarity): |
| 252 | |
doko@ubuntu.com | 4950a3b | 2013-03-19 14:46:29 -0700 | [diff] [blame] | 253 | // If you are using Python before 2.7: |
Gregory P. Smith | 3925053 | 2007-10-09 06:02:21 +0000 | [diff] [blame] | 254 | BSDDB_api* bsddb_api; |
| 255 | PyObject* mod; |
| 256 | PyObject* cobj; |
| 257 | |
| 258 | mod = PyImport_ImportModule("bsddb._bsddb"); |
| 259 | // Use "bsddb3._pybsddb" if you're using the standalone pybsddb add-on. |
| 260 | cobj = PyObject_GetAttrString(mod, "api"); |
| 261 | api = (BSDDB_api*)PyCObject_AsVoidPtr(cobj); |
| 262 | Py_DECREF(cobj); |
| 263 | Py_DECREF(mod); |
| 264 | |
Jesus Cea | 6557aac | 2010-03-22 14:22:26 +0000 | [diff] [blame] | 265 | |
doko@ubuntu.com | 4950a3b | 2013-03-19 14:46:29 -0700 | [diff] [blame] | 266 | // If you are using Python 2.7 or up: (except Python 3.0, unsupported) |
Jesus Cea | 6557aac | 2010-03-22 14:22:26 +0000 | [diff] [blame] | 267 | BSDDB_api* bsddb_api; |
| 268 | |
| 269 | // Use "bsddb3._pybsddb.api" if you're using |
| 270 | // the standalone pybsddb add-on. |
| 271 | bsddb_api = (void **)PyCapsule_Import("bsddb._bsddb.api", 1); |
| 272 | |
| 273 | |
doko@ubuntu.com | 4950a3b | 2013-03-19 14:46:29 -0700 | [diff] [blame] | 274 | Check "api_version" number before trying to use the API. |
| 275 | |
Gregory P. Smith | 3925053 | 2007-10-09 06:02:21 +0000 | [diff] [blame] | 276 | The structure's members must not be changed. |
| 277 | */ |
| 278 | |
doko@ubuntu.com | 4950a3b | 2013-03-19 14:46:29 -0700 | [diff] [blame] | 279 | #define PYBSDDB_API_VERSION 1 |
Gregory P. Smith | 3925053 | 2007-10-09 06:02:21 +0000 | [diff] [blame] | 280 | typedef struct { |
doko@ubuntu.com | 4950a3b | 2013-03-19 14:46:29 -0700 | [diff] [blame] | 281 | unsigned int api_version; |
Gregory P. Smith | 3925053 | 2007-10-09 06:02:21 +0000 | [diff] [blame] | 282 | /* Type objects */ |
| 283 | PyTypeObject* db_type; |
| 284 | PyTypeObject* dbcursor_type; |
Jesus Cea | 6557aac | 2010-03-22 14:22:26 +0000 | [diff] [blame] | 285 | PyTypeObject* dblogcursor_type; |
Gregory P. Smith | 3925053 | 2007-10-09 06:02:21 +0000 | [diff] [blame] | 286 | PyTypeObject* dbenv_type; |
| 287 | PyTypeObject* dbtxn_type; |
| 288 | PyTypeObject* dblock_type; |
Gregory P. Smith | 3925053 | 2007-10-09 06:02:21 +0000 | [diff] [blame] | 289 | PyTypeObject* dbsequence_type; |
Gregory P. Smith | 3925053 | 2007-10-09 06:02:21 +0000 | [diff] [blame] | 290 | |
| 291 | /* Functions */ |
| 292 | int (*makeDBError)(int err); |
Gregory P. Smith | 3925053 | 2007-10-09 06:02:21 +0000 | [diff] [blame] | 293 | } BSDDB_api; |
| 294 | |
| 295 | |
| 296 | #ifndef COMPILING_BSDDB_C |
| 297 | |
| 298 | /* If not inside _bsddb.c, define type check macros that use the api |
| 299 | structure. The calling code must have a value named bsddb_api |
| 300 | pointing to the api structure. |
| 301 | */ |
| 302 | |
| 303 | #define DBObject_Check(v) ((v)->ob_type == bsddb_api->db_type) |
| 304 | #define DBCursorObject_Check(v) ((v)->ob_type == bsddb_api->dbcursor_type) |
| 305 | #define DBEnvObject_Check(v) ((v)->ob_type == bsddb_api->dbenv_type) |
| 306 | #define DBTxnObject_Check(v) ((v)->ob_type == bsddb_api->dbtxn_type) |
| 307 | #define DBLockObject_Check(v) ((v)->ob_type == bsddb_api->dblock_type) |
doko@ubuntu.com | 4950a3b | 2013-03-19 14:46:29 -0700 | [diff] [blame] | 308 | #define DBSequenceObject_Check(v) \ |
| 309 | ((bsddb_api->dbsequence_type) && \ |
| 310 | ((v)->ob_type == bsddb_api->dbsequence_type)) |
Gregory P. Smith | 3925053 | 2007-10-09 06:02:21 +0000 | [diff] [blame] | 311 | |
Christian Heimes | 2518b25 | 2007-12-14 03:02:34 +0000 | [diff] [blame] | 312 | #endif /* COMPILING_BSDDB_C */ |
Gregory P. Smith | 3925053 | 2007-10-09 06:02:21 +0000 | [diff] [blame] | 313 | |
| 314 | |
Christian Heimes | 2518b25 | 2007-12-14 03:02:34 +0000 | [diff] [blame] | 315 | #endif /* _BSDDB_H_ */ |