BerkeleyDB-0.8.6: Database/Berkeley/db_helper.c
#include "db_helper.h"
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#define UNWRAP_DBENV() \
DB_ENV* dbenv; \
if (*dbenvp == NULL) return -20881; /* Haskell binding-specific error code */ \
dbenv = *dbenvp;
#define UNWRAP_DB_TXN_() \
if (dbtxnp == NULL) \
dbtxn = NULL; \
else { \
if (*dbtxnp == NULL) return -20883; /* Haskell binding-specific error code */ \
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 */
#define UNWRAP_DBCURSOR() \
DBC* dbc = *dbcp; \
if (dbc == NULL) return -20884; /* Haskell binding-specific error code */
#define UNWRAP_DB_TXN() \
DB_TXN* 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;
*dbenvpp = (MY_DBENV*)malloc(sizeof(MY_DBENV*));
ret = db_env_create(*dbenvpp, flags);
if (ret != 0)
free(*dbenvpp);
return ret;
}
int _dbenv_toNative(MY_DBENV* dbenvp, DB_ENV** pDbEnv)
{
int ret;
UNWRAP_DBENV();
*pDbEnv = dbenv;
return 0;
}
int _dbenv_set_data_dir(MY_DBENV* dbenvp, char* dir)
{
UNWRAP_DBENV();
return dbenv->set_data_dir(dbenv, dir);
}
int _dbenv_set_lg_dir(MY_DBENV* dbenvp, char* dir)
{
UNWRAP_DBENV();
return dbenv->set_lg_dir(dbenv, dir);
}
int _dbenv_get_lk_max_lockers(MY_DBENV* dbenvp, u_int32_t *lk_maxp) {
UNWRAP_DBENV();
return dbenv->get_lk_max_lockers(dbenv, lk_maxp);
}
int _dbenv_set_lk_max_lockers(MY_DBENV* dbenvp, u_int32_t max) {
UNWRAP_DBENV();
return dbenv->set_lk_max_lockers(dbenv, max);
}
int _dbenv_get_lk_max_locks(MY_DBENV* dbenvp, u_int32_t *lk_maxp) {
UNWRAP_DBENV();
return dbenv->get_lk_max_locks(dbenv, lk_maxp);
}
int _dbenv_set_lk_max_locks(MY_DBENV* dbenvp, u_int32_t max) {
UNWRAP_DBENV();
return dbenv->set_lk_max_locks(dbenv, max);
}
int _dbenv_get_lk_max_objects(MY_DBENV* dbenvp, u_int32_t *lk_maxp) {
UNWRAP_DBENV();
return dbenv->get_lk_max_objects(dbenv, lk_maxp);
}
int _dbenv_set_lk_max_objects(MY_DBENV* dbenvp, u_int32_t max) {
UNWRAP_DBENV();
return dbenv->set_lk_max_objects(dbenv, max);
}
int _dbenv_get_tx_max(MY_DBENV* dbenvp, u_int32_t *lk_maxp) {
UNWRAP_DBENV();
return dbenv->get_tx_max(dbenv, lk_maxp);
}
int _dbenv_set_tx_max(MY_DBENV* dbenvp, u_int32_t max) {
UNWRAP_DBENV();
return dbenv->set_tx_max(dbenv, max);
}
int _dbenv_get_cachesize(MY_DBENV* dbenvp, u_int32_t *gbytesp, u_int32_t *bytesp, int *ncachep) {
UNWRAP_DBENV();
return dbenv->get_cachesize(dbenv, gbytesp, bytesp, ncachep);
}
int _dbenv_set_cachesize(MY_DBENV* dbenvp, u_int32_t gbytes, u_int32_t bytes, int ncache) {
UNWRAP_DBENV();
return dbenv->set_cachesize(dbenv, gbytes, bytes, ncache);
}
int _dbenv_get_lg_regionmax(MY_DBENV* dbenvp, u_int32_t *lk_maxp) {
UNWRAP_DBENV();
return dbenv->get_lg_regionmax(dbenv, lk_maxp);
}
int _dbenv_set_lg_regionmax(MY_DBENV* dbenvp, u_int32_t max) {
UNWRAP_DBENV();
return dbenv->set_lg_regionmax(dbenv, max);
}
int _dbenv_set_lk_detect(MY_DBENV* dbenvp, u_int32_t flag)
{
UNWRAP_DBENV();
return dbenv->set_lk_detect(dbenv, flag);
}
int _dbenv_set_flags(MY_DBENV* dbenvp, u_int32_t flags, int onoff)
{
UNWRAP_DBENV();
return dbenv->set_flags(dbenv, flags, onoff);
}
#if (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR >= 7) || DB_VERSION_MAJOR > 4
int _dbenv_log_set_config(MY_DBENV* dbenvp, u_int32_t flags, int onoff)
{
UNWRAP_DBENV();
return dbenv->log_set_config(dbenv, flags, onoff);
}
#endif
int _dbenv_open(MY_DBENV* dbenvp, char *db_home, u_int32_t flags, int mode) {
UNWRAP_DBENV();
return dbenv->open(dbenv, db_home, flags, mode);
}
int _dbenv_close(MY_DBENV* dbenvp, u_int32_t flags)
{
int ret;
if (*dbenvp != NULL) {
ret = (*dbenvp)->close(*dbenvp,flags);
*dbenvp = NULL;
}
else
ret = 0;
return ret;
}
int _db_create(DB*** dbpp, MY_DBENV* dbenvp, u_int32_t flags)
{
int ret;
UNWRAP_DBENV();
*dbpp = (DB**)malloc(sizeof(DB**));
ret = db_create(*dbpp, dbenv, flags);
if (ret != 0)
free(*dbpp);
return ret;
}
void _db_delete(DB** dbp)
{
if (*dbp != NULL)
(*dbp)->close(*dbp, 0);
free(dbp);
}
int _db_set_pagesize(DB** dbp, u_int32_t pagesize)
{
UNWRAP_DB();
return db->set_pagesize(db, pagesize);
}
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;
UNWRAP_DB();
if (txnp == NULL)
txn = NULL;
else {
if (*txnp == NULL) return -20883; /* Haskell binding-specific error code */
txn = *txnp;
}
return db->open(db, txn, file, database, (DBTYPE) type, flags, mode);
}
int _dbenv_txn_begin(MY_DBENV* dbenvp, DB_TXN** parentp, DB_TXN*** txnpp, u_int32_t flags)
{
int ret;
DB_TXN* parent;
UNWRAP_DBENV();
if (parentp == NULL)
parent = NULL;
else {
parent = *parentp;
if (parent == NULL) return -20883; /* Haskell binding-specific error code */
}
*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)
{
UNWRAP_DBENV();
return dbenv->txn_checkpoint(dbenv, kbyte, min, flags);
}
int _dbtxn_abort(DB_TXN** dbtxnp)
{
UNWRAP_DB_TXN();
dbtxnp[0] = NULL;
dbtxnp[1] = NULL;
return dbtxn->abort(dbtxn);
}
int _dbtxn_commit(DB_TXN** dbtxnp, u_int32_t flags)
{
UNWRAP_DB_TXN();
dbtxnp[0] = NULL;
dbtxnp[1] = NULL;
return dbtxn->commit(dbtxn, flags);
}
void _dbtxn_delete(DB_TXN** dbtxnp)
{
if (*dbtxnp != NULL)
(*dbtxnp)->abort(*dbtxnp);
free(dbtxnp);
}
int _dbtxn_id(DB_TXN** dbtxnp, u_int32_t* locker)
{
UNWRAP_DB_TXN2();
*locker = dbtxn->id(dbtxn);
return 0;
}
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)
{
DBT dbt;
UNWRAP_DBENV();
memset(&dbt, 0, sizeof(dbt));
dbt.flags = DB_DBT_USERMEM;
dbt.data = (void*)object;
dbt.size = object_len;
*dblock = (_DB_LOCK*)malloc(sizeof(_DB_LOCK));
(*dblock)->dbenv = dbenvp;
int ret = dbenv->lock_get(dbenv, lockerID, flags, &dbt, (db_lockmode_t)lockmode, &(*dblock)->lock);
if (ret != 0)
free(*dblock);
return ret;
}
int _dbenv_lock_put(_DB_LOCK* dblock)
{
MY_DBENV* dbenvp = dblock->dbenv;
UNWRAP_DBENV();
return dbenv->lock_put(dbenv, &dblock->lock);
}
void _dblock_delete(_DB_LOCK* dblock)
{
free(dblock);
}
void _freeString(char* str)
{
free(str);
}
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_DB_TXN2_();
memset(&keyDbt, 0, sizeof(keyDbt));
keyDbt.flags = DB_DBT_USERMEM;
keyDbt.data = (void*)key;
keyDbt.size = key_len;
memset(&valueDbt, 0, sizeof(valueDbt));
valueDbt.flags = DB_DBT_MALLOC;
*value = NULL;
*value_len = 0;
ret = db->get(db, dbtxn, &keyDbt, &valueDbt, flags);
if (ret == 0) {
*value = (char*)valueDbt.data;
*value_len = valueDbt.size;
}
return ret;
}
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_DB_TXN2_();
memset(&keyDbt, 0, sizeof(keyDbt));
keyDbt.flags = DB_DBT_USERMEM;
keyDbt.data = (void*)key;
keyDbt.size = key_len;
memset(&valueDbt, 0, sizeof(valueDbt));
valueDbt.flags = DB_DBT_USERMEM;
valueDbt.data = (void*)value;
valueDbt.size = value_len;
return db->put(db, dbtxn, &keyDbt, &valueDbt, 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_DB_TXN2_();
memset(&keyDbt, 0, sizeof(keyDbt));
keyDbt.flags = DB_DBT_USERMEM;
keyDbt.data = (void*)key;
keyDbt.size = key_len;
return db->del(db, dbtxn, &keyDbt, flags);
}
int _db_close(DB** dbp, u_int32_t flags)
{
UNWRAP_DB();
*dbp = NULL;
return db->close(db, flags);
}
int _db_set_flags(DB** dbp, u_int32_t flags)
{
UNWRAP_DB();
return db->set_flags(db, flags);
}
int _db_sync(DB** dbp, u_int32_t flags)
{
UNWRAP_DB();
return db->sync(db, flags);
}
int _db_cursor(DB** dbp, DB_TXN** dbtxnp, DBC*** dbcursorpp, u_int32_t flags)
{
DB_TXN* dbtxn;
UNWRAP_DB();
UNWRAP_DB_TXN2_();
*dbcursorpp = (DBC**)malloc(sizeof(DBC**));
int ret = db->cursor(db, dbtxn, *dbcursorpp, flags);
if (ret != 0)
free(*dbcursorpp);
return ret;
}
void _dbcursor_delete(DBC** dbc)
{
if (*dbc != NULL)
(*dbc)->close(*dbc);
free(dbc);
}
int _dbCursor_close(DBC** dbc)
{
if (*dbc != NULL) {
int ret = (*dbc)->close(*dbc);
*dbc = NULL;
return ret;
}
else
return 0;
}
int _dbCursor_count(DBC** dbcp, u_int32_t* countp, u_int32_t flags)
{
UNWRAP_DBCURSOR();
db_recno_t countp_;
int ret = dbc->count(dbc, &countp_, flags);
*countp = (u_int32_t) countp_;
return ret;
}
int _dbCursor_del(DBC** dbcp, u_int32_t flags)
{
UNWRAP_DBCURSOR();
return dbc->del(dbc, flags);
}
int _dbCursor_dup(DBC** dbcp, DBC*** dbcursorpp, u_int32_t flags)
{
UNWRAP_DBCURSOR();
*dbcursorpp = (DBC**)malloc(sizeof(DBC**));
int ret = dbc->dup(dbc, *dbcursorpp, flags);
if (ret != 0)
free(*dbcursorpp);
return ret;
}
int _dbCursor_get(DBC** dbcp, char** key, u_int32_t* key_len, char** value, u_int32_t* value_len, u_int32_t flags)
{
UNWRAP_DBCURSOR();
int ret;
DBT keyDbt;
memset(&keyDbt, 0, sizeof(keyDbt));
keyDbt.flags = DB_DBT_MALLOC;
*key = NULL;
*key_len = 0;
DBT valueDbt;
memset(&valueDbt, 0, sizeof(valueDbt));
valueDbt.flags = DB_DBT_MALLOC;
*value = NULL;
*value_len = 0;
ret = dbc->get(dbc, &keyDbt, &valueDbt, flags);
if (ret == 0) {
*key = (char*)keyDbt.data;
*key_len = keyDbt.size;
*value = (char*)valueDbt.data;
*value_len = valueDbt.size;
}
return ret;
}
int _dbCursor_set(DBC** dbcp, const char* key, u_int32_t key_len, char** value, u_int32_t* value_len, u_int32_t flags)
{
UNWRAP_DBCURSOR();
int ret;
DBT keyDbt;
memset(&keyDbt, 0, sizeof(keyDbt));
keyDbt.flags = DB_DBT_USERMEM;
keyDbt.data = (void*)key;
keyDbt.size = key_len;
DBT valueDbt;
memset(&valueDbt, 0, sizeof(valueDbt));
valueDbt.flags = DB_DBT_MALLOC;
*value = NULL;
*value_len = 0;
ret = dbc->get(dbc, &keyDbt, &valueDbt, flags);
if (ret == 0) {
*value = (char*)valueDbt.data;
*value_len = valueDbt.size;
}
return ret;
}
int _dbCursor_put(DBC** dbcp, const char* key, u_int32_t key_len, const char* value, u_int32_t value_len, u_int32_t flags)
{
UNWRAP_DBCURSOR();
DBT keyDbt;
memset(&keyDbt, 0, sizeof(keyDbt));
keyDbt.flags = DB_DBT_USERMEM;
keyDbt.data = (void*)key;
keyDbt.size = key_len;
DBT valueDbt;
memset(&valueDbt, 0, sizeof(valueDbt));
valueDbt.flags = DB_DBT_USERMEM;
valueDbt.data = (void*)value;
valueDbt.size = value_len;
return dbc->put(dbc, &keyDbt, &valueDbt, flags);
}