packages feed

BerkeleyDB-0.7: Database/Berkeley/db_helper.c

#include "db_helper.h"

#include <string.h>
#include <stdlib.h>
#include <errno.h>

#if defined(USE_DB_CXX)
#define UNWRAP_DBENV() \
    DB_ENV* dbenv = dbenvp->get_DB_ENV(); \
    if (dbenv == NULL) return -20881;  /* Haskell binding-specific error code */

#define UNWRAP_DBTXN_() \
    if (dbtxnp == NULL) \
        dbtxn = NULL; \
    else { \
        if (*dbtxnp == NULL) return -20883;  /* Haskell binding-specific error code */ \
        dbtxn = (*dbtxnp)->get_DB_TXN(); \
    }
#else
#define UNWRAP_DBENV() \
    DB_ENV* dbenv; \
    if (*dbenvp == NULL) return -20881;  /* Haskell binding-specific error code */ \
    dbenv = *dbenvp;

#define UNWRAP_DBTXN_() \
    if (dbtxnp == NULL) \
        dbtxn = NULL; \
    else { \
        if (*dbtxnp == NULL) return -20883;  /* Haskell binding-specific error code */ \
        dbtxn = *dbtxnp; \
    }
#endif

#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_DBTXN() \
    DB_TXN* dbtxn; \
    UNWRAP_DBTXN_()

int _dbenv_create(MY_DBENV** dbenvpp, u_int32_t flags)
{
#if defined(USE_DB_CXX)
    *dbenvpp = new DbEnv(flags);
    return 0;
#else
    int ret;
    *dbenvpp = (MY_DBENV*)malloc(sizeof(MY_DBENV*));
    ret = db_env_create(*dbenvpp, flags);
    if (ret != 0)
        free(*dbenvpp);
    return ret;
#endif
}

void _dbenv_delete(MY_DBENV* dbenvp)
{
#if defined(USE_DB_CXX)
#else
    _dbenv_close(dbenvp, 0);
    free(dbenvp);
#endif
}

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_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 defined(USE_DB_CXX)
    ret = dbenvp->close(flags);
#else
    if (*dbenvp != NULL) {
        ret = (*dbenvp)->close(*dbenvp,flags);
        *dbenvp = NULL;
    }
    else
        ret = 0;
#endif
    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, MY_DBTXN** 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 */
#if defined(USE_DB_CXX)
        txn = (*txnp)->get_DB_TXN();
#else
        txn = *txnp;
#endif
    }
    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)
{
    MY_DBTXN* parent;
    UNWRAP_DBENV();
    if (parentp == NULL)
        parent = NULL;
    else {
        parent = *parentp;
        if (parent == NULL) return -20883;  /* Haskell binding-specific error code */
    }
    *txnpp = (MY_DBTXN**)malloc(sizeof(MY_DBTXN*));
#if defined(USE_DB_CXX)
    try {
        return dbenvp->txn_begin(parent, *txnpp, flags);
    }
    catch (DbException& exc) {
        free(*txnpp);
        return exc.get_errno();
    }
#else
    return dbenv->txn_begin(dbenv, parent, *txnpp, flags);
#endif
}

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(MY_DBTXN** dbtxnp)
{
    UNWRAP_DBTXN();
    *dbtxnp = NULL;
    dbtxn->abort(dbtxn);
}

int _dbtxn_commit(MY_DBTXN** dbtxnp, u_int32_t flags)
{
    UNWRAP_DBTXN();
    *dbtxnp = NULL;
    dbtxn->commit(dbtxn, flags);
}

void _dbtxn_delete(MY_DBTXN** dbtxnp)
{
    if (*dbtxnp != NULL)
#if defined(USE_DB_CXX)
        (*dbtxnp)->abort();
#else
        (*dbtxnp)->abort(*dbtxnp);
#endif
    free(dbtxnp);
}

u_int32_t _dbtxn_id(MY_DBTXN** dbtxnp)
{
    UNWRAP_DBTXN();
    return dbtxn->id(dbtxn);
}

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, MY_DBTXN** 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_();

    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, MY_DBTXN** 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_();

    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, MY_DBTXN** dbtxnp, const char* key, u_int32_t key_len, u_int32_t flags)
{
    DBT keyDbt;
    DB_TXN* dbtxn;
    UNWRAP_DB();
    UNWRAP_DBTXN_();

    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_cursor(DB** dbp, MY_DBTXN** dbtxnp, DBC*** dbcursorpp, u_int32_t flags)
{
    DB_TXN* dbtxn;
    UNWRAP_DB();
    UNWRAP_DBTXN_();
    *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);
}