| 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 Berkeley DB 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 7 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 | * DBSite (Site)
|
|---|
| 73 | *
|
|---|
| 74 | * New datatypes:
|
|---|
| 75 | *
|
|---|
| 76 | * DBLogCursor (Log Cursor)
|
|---|
| 77 | *
|
|---|
| 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 |
|
|---|
| 113 | #define PY_BSDDB_VERSION "5.3.0"
|
|---|
| 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 |
|
|---|
| 127 |
|
|---|
| 128 | struct DBObject; /* Forward declaration */
|
|---|
| 129 | struct DBCursorObject; /* Forward declaration */
|
|---|
| 130 | struct DBLogCursorObject; /* Forward declaration */
|
|---|
| 131 | struct DBTxnObject; /* Forward declaration */
|
|---|
| 132 | struct DBSequenceObject; /* Forward declaration */
|
|---|
| 133 | #if (DBVER >= 52)
|
|---|
| 134 | struct DBSiteObject; /* Forward declaration */
|
|---|
| 135 | #endif
|
|---|
| 136 |
|
|---|
| 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;
|
|---|
| 143 | PyObject* event_notifyCallback;
|
|---|
| 144 | struct DBObject *children_dbs;
|
|---|
| 145 | struct DBTxnObject *children_txns;
|
|---|
| 146 | struct DBLogCursorObject *children_logcursors;
|
|---|
| 147 | #if (DBVER >= 52)
|
|---|
| 148 | struct DBSiteObject *children_sites;
|
|---|
| 149 | #endif
|
|---|
| 150 | PyObject *private_obj;
|
|---|
| 151 | PyObject *rep_transport;
|
|---|
| 152 | PyObject *in_weakreflist; /* List of weak references */
|
|---|
| 153 | } DBEnvObject;
|
|---|
| 154 |
|
|---|
| 155 | typedef struct DBObject {
|
|---|
| 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() */
|
|---|
| 161 | struct behaviourFlags moduleFlags;
|
|---|
| 162 | struct DBTxnObject *txn;
|
|---|
| 163 | struct DBCursorObject *children_cursors;
|
|---|
| 164 | struct DBSequenceObject *children_sequences;
|
|---|
| 165 | struct DBObject **sibling_prev_p;
|
|---|
| 166 | struct DBObject *sibling_next;
|
|---|
| 167 | struct DBObject **sibling_prev_p_txn;
|
|---|
| 168 | struct DBObject *sibling_next_txn;
|
|---|
| 169 | PyObject* associateCallback;
|
|---|
| 170 | PyObject* btCompareCallback;
|
|---|
| 171 | PyObject* dupCompareCallback;
|
|---|
| 172 | int primaryDBType;
|
|---|
| 173 | PyObject *private_obj;
|
|---|
| 174 | PyObject *in_weakreflist; /* List of weak references */
|
|---|
| 175 | } DBObject;
|
|---|
| 176 |
|
|---|
| 177 |
|
|---|
| 178 | typedef struct DBCursorObject {
|
|---|
| 179 | PyObject_HEAD
|
|---|
| 180 | DBC* dbc;
|
|---|
| 181 | struct DBCursorObject **sibling_prev_p;
|
|---|
| 182 | struct DBCursorObject *sibling_next;
|
|---|
| 183 | struct DBCursorObject **sibling_prev_p_txn;
|
|---|
| 184 | struct DBCursorObject *sibling_next_txn;
|
|---|
| 185 | DBObject* mydb;
|
|---|
| 186 | struct DBTxnObject *txn;
|
|---|
| 187 | PyObject *in_weakreflist; /* List of weak references */
|
|---|
| 188 | } DBCursorObject;
|
|---|
| 189 |
|
|---|
| 190 |
|
|---|
| 191 | typedef struct DBTxnObject {
|
|---|
| 192 | PyObject_HEAD
|
|---|
| 193 | DB_TXN* txn;
|
|---|
| 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;
|
|---|
| 203 | PyObject *in_weakreflist; /* List of weak references */
|
|---|
| 204 | } DBTxnObject;
|
|---|
| 205 |
|
|---|
| 206 |
|
|---|
| 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 |
|
|---|
| 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
|
|---|
| 226 |
|
|---|
| 227 | typedef struct {
|
|---|
| 228 | PyObject_HEAD
|
|---|
| 229 | DB_LOCK lock;
|
|---|
| 230 | int lock_initialized; /* Signal if we actually have a lock */
|
|---|
| 231 | PyObject *in_weakreflist; /* List of weak references */
|
|---|
| 232 | } DBLockObject;
|
|---|
| 233 |
|
|---|
| 234 |
|
|---|
| 235 | typedef struct DBSequenceObject {
|
|---|
| 236 | PyObject_HEAD
|
|---|
| 237 | DB_SEQUENCE* sequence;
|
|---|
| 238 | DBObject* mydb;
|
|---|
| 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;
|
|---|
| 244 | PyObject *in_weakreflist; /* List of weak references */
|
|---|
| 245 | } DBSequenceObject;
|
|---|
| 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 |
|
|---|
| 253 | // If you are using Python before 2.7:
|
|---|
| 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 |
|
|---|
| 265 |
|
|---|
| 266 | // If you are using Python 2.7 or up: (except Python 3.0, unsupported)
|
|---|
| 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 |
|
|---|
| 274 | Check "api_version" number before trying to use the API.
|
|---|
| 275 |
|
|---|
| 276 | The structure's members must not be changed.
|
|---|
| 277 | */
|
|---|
| 278 |
|
|---|
| 279 | #define PYBSDDB_API_VERSION 1
|
|---|
| 280 | typedef struct {
|
|---|
| 281 | unsigned int api_version;
|
|---|
| 282 | /* Type objects */
|
|---|
| 283 | PyTypeObject* db_type;
|
|---|
| 284 | PyTypeObject* dbcursor_type;
|
|---|
| 285 | PyTypeObject* dblogcursor_type;
|
|---|
| 286 | PyTypeObject* dbenv_type;
|
|---|
| 287 | PyTypeObject* dbtxn_type;
|
|---|
| 288 | PyTypeObject* dblock_type;
|
|---|
| 289 | PyTypeObject* dbsequence_type;
|
|---|
| 290 |
|
|---|
| 291 | /* Functions */
|
|---|
| 292 | int (*makeDBError)(int err);
|
|---|
| 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)
|
|---|
| 308 | #define DBSequenceObject_Check(v) \
|
|---|
| 309 | ((bsddb_api->dbsequence_type) && \
|
|---|
| 310 | ((v)->ob_type == bsddb_api->dbsequence_type))
|
|---|
| 311 |
|
|---|
| 312 | #endif /* COMPILING_BSDDB_C */
|
|---|
| 313 |
|
|---|
| 314 |
|
|---|
| 315 | #endif /* _BSDDB_H_ */
|
|---|