BerkeleyDB 0.8 → 0.8.1
raw patch · 5 files changed
+68/−44 lines, 5 filesPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
API changes (from Hackage documentation)
- Database.Berkeley.Db: dbTxn_id :: DbTxn -> DbLocker
+ Database.Berkeley.Db: dbTxn_id :: DbTxn -> IO DbLocker
Files
- BerkeleyDB.cabal +1/−1
- Database/Berkeley/Db.hsc +7/−5
- Database/Berkeley/db_helper.c +48/−26
- Database/Berkeley/db_helper.h +10/−11
- examples/tests.hs +2/−1
BerkeleyDB.cabal view
@@ -1,5 +1,5 @@ name: BerkeleyDB-version: 0.8+version: 0.8.1 license: BSD3 license-file: LICENSE cabal-version: >= 1.4
Database/Berkeley/Db.hsc view
@@ -87,7 +87,6 @@ import System.IO.Error import System.IO (FilePath) import Foreign.ForeignPtr-import System.IO.Unsafe import Data.ByteString (ByteString) import qualified Data.ByteString.Internal as BSI import Data.Word@@ -778,14 +777,17 @@ foreign import ccall "db_helper.h _dbtxn_id" _dbtxn_id- :: Ptr DbTxn_struct -> IO CUInt+ :: Ptr DbTxn_struct -> Ptr CUInt -> IO CInt -- | Get the locker ID for a transaction, which can be used with 'dbEnv_withLock'.-dbTxn_id :: DbTxn -> DbLocker+dbTxn_id :: DbTxn -> IO DbLocker dbTxn_id dbtxn =- unsafePerformIO $ withForeignPtr dbtxn $ \c_dbtxn ->- liftM DbLocker$ _dbtxn_id c_dbtxn+ alloca $ \ptr -> do+ ret <- _dbtxn_id c_dbtxn ptr+ if ret /= 0+ then throwDB "dbTxn_id" ret+ else DbLocker <$> peek ptr data DbLockMode = DB_LOCK_READ | DB_LOCK_WRITE | DB_LOCK_IWRITE | DB_LOCK_IREAD | DB_LOCK_IWR
Database/Berkeley/db_helper.c view
@@ -9,7 +9,7 @@ if (*dbenvp == NULL) return -20881; /* Haskell binding-specific error code */ \ dbenv = *dbenvp; -#define UNWRAP_DBTXN_() \+#define UNWRAP_DB_TXN_() \ if (dbtxnp == NULL) \ dbtxn = NULL; \ else { \@@ -17,6 +17,14 @@ dbtxn = *dbtxnp; \ } +#define UNWRAP_DB_TXN2_() \+ if (dbtxnp == NULL) \+ dbtxn = NULL; \+ else { \+ if (dbtxnp[1] == NULL) return -20883; /* Haskell binding-specific error code */ \+ dbtxn = dbtxnp[1]; \+ }+ #define UNWRAP_DB() \ DB* db = *dbp; \ if (db == NULL) return -20882; /* Haskell binding-specific error code */@@ -25,10 +33,14 @@ DBC* dbc = *dbcp; \ if (dbc == NULL) return -20884; /* Haskell binding-specific error code */ -#define UNWRAP_DBTXN() \+#define UNWRAP_DB_TXN() \ DB_TXN* dbtxn; \- UNWRAP_DBTXN_()+ UNWRAP_DB_TXN_() +#define UNWRAP_DB_TXN2() \+ DB_TXN* dbtxn; \+ UNWRAP_DB_TXN2_()+ int _dbenv_create(MY_DBENV** dbenvpp, u_int32_t flags) { int ret;@@ -146,7 +158,7 @@ return db->set_pagesize(db, pagesize); } -int _db_open(DB** dbp, MY_DBTXN** txnp, const char* file, const char* database,+int _db_open(DB** dbp, DB_TXN** txnp, const char* file, const char* database, int type, u_int32_t flags, int mode) { DB_TXN* txn;@@ -160,9 +172,10 @@ return db->open(db, txn, file, database, (DBTYPE) type, flags, mode); } -int _dbenv_txn_begin(MY_DBENV* dbenvp, MY_DBTXN** parentp, MY_DBTXN*** txnpp, u_int32_t flags)+int _dbenv_txn_begin(MY_DBENV* dbenvp, DB_TXN** parentp, DB_TXN*** txnpp, u_int32_t flags) {- MY_DBTXN* parent;+ int ret;+ DB_TXN* parent; UNWRAP_DBENV(); if (parentp == NULL) parent = NULL;@@ -170,8 +183,14 @@ parent = *parentp; if (parent == NULL) return -20883; /* Haskell binding-specific error code */ }- *txnpp = (MY_DBTXN**)malloc(sizeof(MY_DBTXN*));- return dbenv->txn_begin(dbenv, parent, *txnpp, flags);+ *txnpp = (DB_TXN**)malloc(sizeof(DB_TXN*)*2);+ ret = dbenv->txn_begin(dbenv, parent, *txnpp, flags);+ /* Store the DB_TXN twice - the first is NULLed when we pass it to be wrapped+ as a DBXML transaction.+ We keep the second for operations where we still want to access it+ after DBXML has taken it over, in particular _dbtxn_id(). */+ (*txnpp)[1] = (*txnpp)[0];+ return ret; } int _dbenv_txn_checkpoint(MY_DBENV* dbenvp, u_int32_t kbyte, u_int32_t min, u_int32_t flags)@@ -180,31 +199,34 @@ return dbenv->txn_checkpoint(dbenv, kbyte, min, flags); } -int _dbtxn_abort(MY_DBTXN** dbtxnp)+int _dbtxn_abort(DB_TXN** dbtxnp) {- UNWRAP_DBTXN();- *dbtxnp = NULL;+ UNWRAP_DB_TXN();+ dbtxnp[0] = NULL;+ dbtxnp[1] = NULL; dbtxn->abort(dbtxn); } -int _dbtxn_commit(MY_DBTXN** dbtxnp, u_int32_t flags)+int _dbtxn_commit(DB_TXN** dbtxnp, u_int32_t flags) {- UNWRAP_DBTXN();- *dbtxnp = NULL;+ UNWRAP_DB_TXN();+ dbtxnp[0] = NULL;+ dbtxnp[1] = NULL; dbtxn->commit(dbtxn, flags); } -void _dbtxn_delete(MY_DBTXN** dbtxnp)+void _dbtxn_delete(DB_TXN** dbtxnp) { if (*dbtxnp != NULL) (*dbtxnp)->abort(*dbtxnp); free(dbtxnp); } -u_int32_t _dbtxn_id(MY_DBTXN** dbtxnp)+int _dbtxn_id(DB_TXN** dbtxnp, u_int32_t* locker) {- UNWRAP_DBTXN();- return dbtxn->id(dbtxn);+ UNWRAP_DB_TXN2();+ *locker = dbtxn->id(dbtxn);+ return 0; } int _dbenv_lock_get(MY_DBENV* dbenvp, u_int32_t lockerID, u_int32_t flags,@@ -242,14 +264,14 @@ free(str); } -int _db_get(DB** dbp, MY_DBTXN** dbtxnp, const char* key, u_int32_t key_len, char** value, u_int32_t* value_len, u_int32_t flags)+int _db_get(DB** dbp, DB_TXN** dbtxnp, const char* key, u_int32_t key_len, char** value, u_int32_t* value_len, u_int32_t flags) { DBT keyDbt; DBT valueDbt; int ret; DB_TXN* dbtxn; UNWRAP_DB();- UNWRAP_DBTXN_();+ UNWRAP_DB_TXN2_(); memset(&keyDbt, 0, sizeof(keyDbt)); keyDbt.flags = DB_DBT_USERMEM;@@ -268,13 +290,13 @@ return ret; } -int _db_put(DB** dbp, MY_DBTXN** dbtxnp, const char* key, u_int32_t key_len, const char* value, u_int32_t value_len, u_int32_t flags)+int _db_put(DB** dbp, DB_TXN** dbtxnp, const char* key, u_int32_t key_len, const char* value, u_int32_t value_len, u_int32_t flags) { DBT keyDbt; DBT valueDbt; DB_TXN* dbtxn; UNWRAP_DB();- UNWRAP_DBTXN_();+ UNWRAP_DB_TXN2_(); memset(&keyDbt, 0, sizeof(keyDbt)); keyDbt.flags = DB_DBT_USERMEM;@@ -287,12 +309,12 @@ return db->put(db, dbtxn, &keyDbt, &valueDbt, flags); } -int _db_del(DB** dbp, MY_DBTXN** dbtxnp, const char* key, u_int32_t key_len, u_int32_t flags)+int _db_del(DB** dbp, DB_TXN** dbtxnp, const char* key, u_int32_t key_len, u_int32_t flags) { DBT keyDbt; DB_TXN* dbtxn; UNWRAP_DB();- UNWRAP_DBTXN_();+ UNWRAP_DB_TXN2_(); memset(&keyDbt, 0, sizeof(keyDbt)); keyDbt.flags = DB_DBT_USERMEM;@@ -308,11 +330,11 @@ return db->close(db, flags); } -int _db_cursor(DB** dbp, MY_DBTXN** dbtxnp, DBC*** dbcursorpp, u_int32_t flags)+int _db_cursor(DB** dbp, DB_TXN** dbtxnp, DBC*** dbcursorpp, u_int32_t flags) { DB_TXN* dbtxn; UNWRAP_DB();- UNWRAP_DBTXN_();+ UNWRAP_DB_TXN2_(); *dbcursorpp = (DBC**)malloc(sizeof(DBC**)); int ret = db->cursor(db, dbtxn, *dbcursorpp, flags); if (ret != 0)
Database/Berkeley/db_helper.h view
@@ -3,7 +3,6 @@ #include <db.h> #define MY_DBENV DB_ENV*-#define MY_DBTXN DB_TXN typedef struct _DB_LOCK { MY_DBENV* dbenv;@@ -30,25 +29,25 @@ int _db_create(DB*** dbpp, MY_DBENV* dbenvp, u_int32_t flags); void _db_delete(DB** db); int _db_set_pagesize(DB** dbp, u_int32_t pagesize);-int _db_open(DB** dbp, MY_DBTXN** txnp, const char* file, const char* database,+int _db_open(DB** dbp, DB_TXN** txnp, const char* file, const char* database, int type, u_int32_t flags, int mode);-int _dbenv_txn_begin(MY_DBENV* dbenvp, MY_DBTXN** parent, MY_DBTXN*** txnpp, u_int32_t flags);+int _dbenv_txn_begin(MY_DBENV* dbenvp, DB_TXN** parent, DB_TXN*** txnpp, u_int32_t flags); int _dbenv_txn_checkpoint(MY_DBENV* dbenvp, u_int32_t kbyte, u_int32_t min, u_int32_t flags);-int _dbtxn_abort(MY_DBTXN** dbtxnp);-int _dbtxn_commit(MY_DBTXN** dbtxnp, u_int32_t flags);-void _dbtxn_delete(MY_DBTXN** dbtxnp);-u_int32_t _dbtxn_id(MY_DBTXN** dbtxnp);+int _dbtxn_abort(DB_TXN** dbtxnp);+int _dbtxn_commit(DB_TXN** dbtxnp, u_int32_t flags);+void _dbtxn_delete(DB_TXN** dbtxnp);+int _dbtxn_id(DB_TXN** dbtxnp, u_int32_t* locker); void _dblock_delete(_DB_LOCK* dblock); int _dbenv_lock_get(MY_DBENV* dbenvp, u_int32_t lockerID, u_int32_t flags, const char* object, u_int32_t object_len, u_int32_t lockmode, _DB_LOCK** dblock); int _dbenv_lock_put(_DB_LOCK* dblock); void _deleteString(char* str); void _freeString(char* str);-int _db_get(DB** dbp, MY_DBTXN** dbtxnp, const char* key, u_int32_t key_len, char** value, u_int32_t* value_len, u_int32_t flags);-int _db_put(DB** dbp, MY_DBTXN** dbtxnp, const char* key, u_int32_t key_len, const char* value, u_int32_t value_len, u_int32_t flags);-int _db_del(DB** dbp, MY_DBTXN** dbtxnp, const char* key, u_int32_t key_len, u_int32_t flags);+int _db_get(DB** dbp, DB_TXN** dbtxnp, const char* key, u_int32_t key_len, char** value, u_int32_t* value_len, u_int32_t flags);+int _db_put(DB** dbp, DB_TXN** dbtxnp, const char* key, u_int32_t key_len, const char* value, u_int32_t value_len, u_int32_t flags);+int _db_del(DB** dbp, DB_TXN** dbtxnp, const char* key, u_int32_t key_len, u_int32_t flags); int _db_close(DB** dbp, u_int32_t flags);-int _db_cursor(DB** dbp, MY_DBTXN** dbtxnp, DBC*** dbcursorpp, u_int32_t flags);+int _db_cursor(DB** dbp, DB_TXN** dbtxnp, DBC*** dbcursorpp, u_int32_t flags); void _dbcursor_delete(DBC** dbc); int _dbCursor_close(DBC** dbc); int _dbCursor_count(DBC** dbcp, u_int32_t* countp, u_int32_t flags);
examples/tests.hs view
@@ -139,7 +139,8 @@ -- This doesn't test very much: Just that locking doesn't cause any -- runtime errors, hangs or crashes. dbEnv_withTxn [] [] dbenv Nothing $ \txn -> do- dbEnv_withLock [] DB_LOCK_WRITE (pack "my_lock") dbenv (dbTxn_id txn) $ do+ locker <- dbTxn_id txn+ dbEnv_withLock [] DB_LOCK_WRITE (pack "my_lock") dbenv locker $ do db_put [] db (Just txn) (pack "fruit") (pack "durian") test_dbCursor_get =