Guido van Rossum | 8ce8a78 | 2007-11-01 19:42:39 +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 |
| 39 | * to compile with BerkeleyDB versions 3.2 through 4.2. |
| 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 | * |
| 64 | * This module contains 6 types: |
| 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) |
| 72 | * |
| 73 | */ |
| 74 | |
| 75 | /* --------------------------------------------------------------------- */ |
| 76 | |
| 77 | /* |
| 78 | * Portions of this module, associated unit tests and build scripts are the |
| 79 | * result of a contract with The Written Word (http://thewrittenword.com/) |
| 80 | * Many thanks go out to them for causing me to raise the bar on quality and |
| 81 | * functionality, resulting in a better bsddb3 package for all of us to use. |
| 82 | * |
| 83 | * --Robin |
| 84 | */ |
| 85 | |
| 86 | /* --------------------------------------------------------------------- */ |
| 87 | |
| 88 | /* |
| 89 | * Work to split it up into a separate header and to add a C API was |
| 90 | * contributed by Duncan Grisby <duncan@tideway.com>. See here: |
| 91 | * http://sourceforge.net/tracker/index.php?func=detail&aid=1551895&group_id=13900&atid=313900 |
| 92 | */ |
| 93 | |
| 94 | /* --------------------------------------------------------------------- */ |
| 95 | |
| 96 | #ifndef _BSDDB_H_ |
| 97 | #define _BSDDB_H_ |
| 98 | |
| 99 | #include <db.h> |
| 100 | |
| 101 | |
| 102 | /* 40 = 4.0, 33 = 3.3; this will break if the minor revision is > 9 */ |
| 103 | #define DBVER (DB_VERSION_MAJOR * 10 + DB_VERSION_MINOR) |
| 104 | #if DB_VERSION_MINOR > 9 |
| 105 | #error "eek! DBVER can't handle minor versions > 9" |
| 106 | #endif |
| 107 | |
| 108 | #define PY_BSDDB_VERSION "4.6.0" |
| 109 | |
| 110 | /* Python object definitions */ |
| 111 | |
| 112 | struct behaviourFlags { |
| 113 | /* What is the default behaviour when DB->get or DBCursor->get returns a |
| 114 | DB_NOTFOUND || DB_KEYEMPTY error? Return None or raise an exception? */ |
| 115 | unsigned int getReturnsNone : 1; |
| 116 | /* What is the default behaviour for DBCursor.set* methods when DBCursor->get |
| 117 | * returns a DB_NOTFOUND || DB_KEYEMPTY error? Return None or raise? */ |
| 118 | unsigned int cursorSetReturnsNone : 1; |
| 119 | }; |
| 120 | |
| 121 | |
| 122 | typedef struct { |
| 123 | PyObject_HEAD |
| 124 | DB_ENV* db_env; |
| 125 | u_int32_t flags; /* saved flags from open() */ |
| 126 | int closed; |
| 127 | struct behaviourFlags moduleFlags; |
| 128 | PyObject *in_weakreflist; /* List of weak references */ |
| 129 | } DBEnvObject; |
| 130 | |
| 131 | |
| 132 | typedef struct { |
| 133 | PyObject_HEAD |
| 134 | DB* db; |
| 135 | DBEnvObject* myenvobj; /* PyObject containing the DB_ENV */ |
| 136 | u_int32_t flags; /* saved flags from open() */ |
| 137 | u_int32_t setflags; /* saved flags from set_flags() */ |
| 138 | int haveStat; |
| 139 | struct behaviourFlags moduleFlags; |
| 140 | #if (DBVER >= 33) |
| 141 | PyObject* associateCallback; |
| 142 | PyObject* btCompareCallback; |
| 143 | int primaryDBType; |
| 144 | #endif |
| 145 | PyObject *in_weakreflist; /* List of weak references */ |
| 146 | } DBObject; |
| 147 | |
| 148 | |
| 149 | typedef struct { |
| 150 | PyObject_HEAD |
| 151 | DBC* dbc; |
| 152 | DBObject* mydb; |
| 153 | PyObject *in_weakreflist; /* List of weak references */ |
| 154 | } DBCursorObject; |
| 155 | |
| 156 | |
| 157 | typedef struct { |
| 158 | PyObject_HEAD |
| 159 | DB_TXN* txn; |
| 160 | PyObject *env; |
| 161 | PyObject *in_weakreflist; /* List of weak references */ |
| 162 | } DBTxnObject; |
| 163 | |
| 164 | |
| 165 | typedef struct { |
| 166 | PyObject_HEAD |
| 167 | DB_LOCK lock; |
| 168 | PyObject *in_weakreflist; /* List of weak references */ |
| 169 | } DBLockObject; |
| 170 | |
| 171 | |
| 172 | #if (DBVER >= 43) |
| 173 | typedef struct { |
| 174 | PyObject_HEAD |
| 175 | DB_SEQUENCE* sequence; |
| 176 | DBObject* mydb; |
| 177 | PyObject *in_weakreflist; /* List of weak references */ |
| 178 | } DBSequenceObject; |
| 179 | static PyTypeObject DBSequence_Type; |
| 180 | #endif |
| 181 | |
| 182 | |
| 183 | /* API structure for use by C code */ |
| 184 | |
| 185 | /* To access the structure from an external module, use code like the |
| 186 | following (error checking missed out for clarity): |
| 187 | |
| 188 | BSDDB_api* bsddb_api; |
| 189 | PyObject* mod; |
| 190 | PyObject* cobj; |
| 191 | |
| 192 | mod = PyImport_ImportModule("bsddb._bsddb"); |
| 193 | // Use "bsddb3._pybsddb" if you're using the standalone pybsddb add-on. |
| 194 | cobj = PyObject_GetAttrString(mod, "api"); |
| 195 | api = (BSDDB_api*)PyCObject_AsVoidPtr(cobj); |
| 196 | Py_DECREF(cobj); |
| 197 | Py_DECREF(mod); |
| 198 | |
| 199 | The structure's members must not be changed. |
| 200 | */ |
| 201 | |
| 202 | typedef struct { |
| 203 | /* Type objects */ |
| 204 | PyTypeObject* db_type; |
| 205 | PyTypeObject* dbcursor_type; |
| 206 | PyTypeObject* dbenv_type; |
| 207 | PyTypeObject* dbtxn_type; |
| 208 | PyTypeObject* dblock_type; |
| 209 | #if (DBVER >= 43) |
| 210 | PyTypeObject* dbsequence_type; |
| 211 | #endif |
| 212 | |
| 213 | /* Functions */ |
| 214 | int (*makeDBError)(int err); |
| 215 | |
| 216 | } BSDDB_api; |
| 217 | |
| 218 | |
| 219 | #ifndef COMPILING_BSDDB_C |
| 220 | |
| 221 | /* If not inside _bsddb.c, define type check macros that use the api |
| 222 | structure. The calling code must have a value named bsddb_api |
| 223 | pointing to the api structure. |
| 224 | */ |
| 225 | |
| 226 | #define DBObject_Check(v) ((v)->ob_type == bsddb_api->db_type) |
| 227 | #define DBCursorObject_Check(v) ((v)->ob_type == bsddb_api->dbcursor_type) |
| 228 | #define DBEnvObject_Check(v) ((v)->ob_type == bsddb_api->dbenv_type) |
| 229 | #define DBTxnObject_Check(v) ((v)->ob_type == bsddb_api->dbtxn_type) |
| 230 | #define DBLockObject_Check(v) ((v)->ob_type == bsddb_api->dblock_type) |
| 231 | #if (DBVER >= 43) |
| 232 | #define DBSequenceObject_Check(v) ((v)->ob_type == bsddb_api->dbsequence_type) |
| 233 | #endif |
| 234 | |
| 235 | #endif // COMPILING_BSDDB_C |
| 236 | |
| 237 | |
| 238 | #endif // _BSDDB_H_ |